Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Web components: Introduce versioning #574

Merged
merged 6 commits into from
Sep 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions .github/workflows/webcomponents.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ on:
push:
branches:
- main
tags:
- 'v*.*.*'
release:
types: [published]

Expand Down Expand Up @@ -54,10 +56,10 @@ jobs:
tag: ${{ github.ref }}
overwrite: true

- name: Publish web component to ${{ env.PUBLISH_BRANCH }} branch
- name: Publish web component to ${{ env.PUBLISH_BRANCH }}-${{ github.ref_name }} branch
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
force_orphan: true
publish_dir: ./wc-dist
publish_branch: ${{ env.PUBLISH_BRANCH }}
publish_branch: ${{ env.PUBLISH_BRANCH }}-${{ github.ref_name }}
2 changes: 2 additions & 0 deletions apps/datahub/src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ import { WEB_COMPONENT_EMBEDDER_URL } from '@geonetwork-ui/feature/record'
import { LANGUAGES_LIST, UiCatalogModule } from '@geonetwork-ui/ui/catalog'
import { METADATA_LANGUAGE } from '@geonetwork-ui/api/repository'
import { BrowserAnimationsModule } from '@angular/platform-browser/animations'
import { GN_UI_VERSION } from '@geonetwork-ui/feature/record'

export const metaReducers: MetaReducer[] = !environment.production ? [] : []
// https://github.com/nrwl/nx/issues/191
Expand Down Expand Up @@ -130,6 +131,7 @@ export const metaReducers: MetaReducer[] = !environment.production ? [] : []
providers: [
{ provide: RouterService, useClass: DatahubRouterService },
importProvidersFrom(FeatureAuthModule),
{ provide: GN_UI_VERSION, useValue: environment.version },
{
provide: Configuration,
useFactory: () =>
Expand Down
2 changes: 2 additions & 0 deletions apps/datahub/src/environments/environment.prod.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import packageJson from '../../../../package.json'
export const environment = {
production: true,
version: `v${packageJson.version.split('-')[0]}`,
}
5 changes: 5 additions & 0 deletions apps/datahub/src/environments/environment.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import packageJson from '../../../../package.json'
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be a better practice to import only the version: import { version } from '...'

Otherwise the complete package.json content might end up in the bundle which might be a security issue.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hum, importing only the version does not seem to work. Following the discussion here I decided to put the logic into the environment.ts to prevent exposing the entire package.json within the code. Checking the produced main.js in production this indeed seems to work, while in dev the package.json content is visible in the debugger.

// This file can be replaced during build by using the `fileReplacements` array.
// `ng build` replaces `environment.ts` with `environment.prod.ts`.
// The list of file replacements can be found in `angular.json`.

export const environment = {
production: false,
version:
packageJson.version.split('-')[1] === 'dev'
? 'main'
: `v${packageJson.version}`,
}

/*
Expand Down
2 changes: 1 addition & 1 deletion apps/webcomponents/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ All Web Components are prefixed with `gn-`.
Web Components are made to be easily included in any context, e.g.:

```html
<script src="https://cdn.jsdelivr.net/gh/geonetwork/geonetwork-ui@wc-dist/gn-wc.js"></script>
<script src="https://cdn.jsdelivr.net/gh/geonetwork/geonetwork-ui@wc-dist-main/gn-wc.js"></script>
...
<gn-results-list
api-url="https://apps.titellus.net/geonetwork/srv/api"
Expand Down
8 changes: 7 additions & 1 deletion docs/guide/webcomponents.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Web Components are made to be easily included in any context. To do so, you have
- include your Web Component in the HTML content.

```html
<script src="https://cdn.jsdelivr.net/gh/geonetwork/geonetwork-ui@wc-dist/gn-wc.js"></script>
<script src="https://cdn.jsdelivr.net/gh/geonetwork/geonetwork-ui@wc-dist-v2.0.0/gn-wc.js"></script>
...
<gn-results-list
api-url="https://dev.geo2france.fr/geonetwork/srv/api"
Expand All @@ -31,6 +31,12 @@ Web Components are made to be easily included in any context. To do so, you have
></gn-results-list>
```

## Publication and Versioning

The Web Component script is automatically built upon merges on main and for releases. These builds are made available via a jsdelivr CDN, which points at `wc-dist` branches in the github repository. There is a `wc-dist` branch for every release tag > `v2.0.0` as well as `wc-dist-main`.

You can choose the version of the Web Component script you wish to use by indicating the corresponding value in the script's URL e.g. `wc-dist-v2.0.0`.

## Build

All Angular custom elements are served by the same application `webcomponents`.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { BehaviorSubject, firstValueFrom } from 'rxjs'
import { MdViewFacade } from '../state'
import { Component, Input } from '@angular/core'
import { TranslateModule } from '@ngx-translate/core'
import { GN_UI_VERSION } from '../feature-record.module'

const chartConfig1 = {
aggregation: 'sum',
Expand Down Expand Up @@ -38,6 +39,8 @@ class ConfigMock {

const baseUrl = 'https://example.com/wc-embedder'

const gnUiVersion = 'v1.2.3'

@Component({
selector: 'gn-ui-copy-text-button',
template: '<div></div>',
Expand Down Expand Up @@ -69,6 +72,10 @@ describe('DataViewPermalinkComponent', () => {
provide: WEB_COMPONENT_EMBEDDER_URL,
useValue: baseUrl,
},
{
provide: GN_UI_VERSION,
useValue: gnUiVersion,
},
],
}).compileComponents()
facade = TestBed.inject(MdViewFacade)
Expand All @@ -85,7 +92,7 @@ describe('DataViewPermalinkComponent', () => {
it('should generate URL based on configs', async () => {
const url = await firstValueFrom(component.permalinkUrl$)
expect(url).toBe(
`https://example.com/wc-embedder?e=gn-dataset-view-chart&a=api-url=${component.config.basePath}&a=dataset-id=${metadata.uniqueIdentifier}&a=primary-color=%230f4395&a=secondary-color=%238bc832&a=main-color=%23555&a=background-color=%23fdfbff&a=aggregation=${chartConfig1.aggregation}&a=x-property=${chartConfig1.xProperty}&a=y-property=${chartConfig1.yProperty}&a=chart-type=${chartConfig1.chartType}`
`https://example.com/wc-embedder?v=${gnUiVersion}&e=gn-dataset-view-chart&a=api-url=${component.config.basePath}&a=dataset-id=${metadata.uniqueIdentifier}&a=primary-color=%230f4395&a=secondary-color=%238bc832&a=main-color=%23555&a=background-color=%23fdfbff&a=aggregation=${chartConfig1.aggregation}&a=x-property=${chartConfig1.xProperty}&a=y-property=${chartConfig1.yProperty}&a=chart-type=${chartConfig1.chartType}`
)
})
})
Expand All @@ -96,7 +103,7 @@ describe('DataViewPermalinkComponent', () => {
it('should update URL based on configs', async () => {
const url = await firstValueFrom(component.permalinkUrl$)
expect(url).toBe(
`https://example.com/wc-embedder?e=gn-dataset-view-chart&a=api-url=${component.config.basePath}&a=dataset-id=${metadata.uniqueIdentifier}&a=primary-color=%230f4395&a=secondary-color=%238bc832&a=main-color=%23555&a=background-color=%23fdfbff&a=aggregation=${chartConfig2.aggregation}&a=x-property=${chartConfig2.xProperty}&a=y-property=${chartConfig2.yProperty}&a=chart-type=${chartConfig2.chartType}`
`https://example.com/wc-embedder?v=${gnUiVersion}&e=gn-dataset-view-chart&a=api-url=${component.config.basePath}&a=dataset-id=${metadata.uniqueIdentifier}&a=primary-color=%230f4395&a=secondary-color=%238bc832&a=main-color=%23555&a=background-color=%23fdfbff&a=aggregation=${chartConfig2.aggregation}&a=x-property=${chartConfig2.xProperty}&a=y-property=${chartConfig2.yProperty}&a=chart-type=${chartConfig2.chartType}`
)
})
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
import { Configuration } from '@geonetwork-ui/data-access/gn4'
import { combineLatest, map } from 'rxjs'
import { MdViewFacade } from '../state'
import { GN_UI_VERSION } from '../feature-record.module'

export const WEB_COMPONENT_EMBEDDER_URL = new InjectionToken<string>(
'webComponentEmbedderUrl'
Expand All @@ -28,7 +29,8 @@ export class DataViewPermalinkComponent {
if (config) {
const { aggregation, xProperty, yProperty, chartType } = config
const url = new URL(`${this.wcEmbedderBaseUrl}`, window.location.origin)
url.search = `?e=gn-dataset-view-chart
url.search = `?v=${this.version}
&e=gn-dataset-view-chart
&a=api-url=${this.config.basePath}
&a=dataset-id=${metadata.uniqueIdentifier}
&a=primary-color=%230f4395
Expand All @@ -50,6 +52,7 @@ export class DataViewPermalinkComponent {
@Optional()
@Inject(WEB_COMPONENT_EMBEDDER_URL)
protected wcEmbedderBaseUrl: string,
@Inject(GN_UI_VERSION) private version: string,
private facade: MdViewFacade
) {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Configuration } from '@geonetwork-ui/data-access/gn4'
import { MdViewFacade } from '../state'
import { TranslateModule } from '@ngx-translate/core'
import { Component, Input } from '@angular/core'
import { GN_UI_VERSION } from '../feature-record.module'

const chartConfig1 = {
aggregation: 'sum',
Expand All @@ -24,6 +25,8 @@ const metadata = {
uniqueIdentifier: 'md_record_1234',
}

const gnUiVersion = 'v1.2.3'

class MdViewFacadeMock {
chartConfig$ = new BehaviorSubject(chartConfig1)
metadata$ = new BehaviorSubject(metadata)
Expand Down Expand Up @@ -63,6 +66,10 @@ describe('DataViewWebComponentComponent', () => {
provide: MdViewFacade,
useClass: MdViewFacadeMock,
},
{
provide: GN_UI_VERSION,
useValue: gnUiVersion,
},
],
}).compileComponents()
facade = TestBed.inject(MdViewFacade)
Expand All @@ -79,7 +86,7 @@ describe('DataViewWebComponentComponent', () => {
it('should generate HTML based on configs', async () => {
const html = await firstValueFrom(component.webComponentHtml$)
expect(html).toBe(
`<script src="https://cdn.jsdelivr.net/gh/geonetwork/geonetwork-ui@wc-dist/gn-wc.js"></script>
`<script src="https://cdn.jsdelivr.net/gh/geonetwork/geonetwork-ui@wc-dist-${gnUiVersion}/gn-wc.js"></script>
<gn-dataset-view-chart
api-url="http://localhost/undefined"
dataset-id="${metadata.uniqueIdentifier}"
Expand All @@ -104,7 +111,7 @@ describe('DataViewWebComponentComponent', () => {
it('should update HTML based on configs', async () => {
const html = await firstValueFrom(component.webComponentHtml$)
expect(html).toBe(
`<script src="https://cdn.jsdelivr.net/gh/geonetwork/geonetwork-ui@wc-dist/gn-wc.js"></script>
`<script src="https://cdn.jsdelivr.net/gh/geonetwork/geonetwork-ui@wc-dist-${gnUiVersion}/gn-wc.js"></script>
<gn-dataset-view-chart
api-url="http://localhost/undefined"
dataset-id="${metadata.uniqueIdentifier}"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { ChangeDetectionStrategy, Component, Inject } from '@angular/core'
import { Configuration } from '@geonetwork-ui/data-access/gn4'
import { MdViewFacade } from '../state'
import { combineLatest, map } from 'rxjs'
import { GN_UI_VERSION } from '../feature-record.module'

@Component({
selector: 'gn-ui-data-view-web-component',
Expand All @@ -17,7 +18,9 @@ export class DataViewWebComponentComponent {
map(([config, metadata]) => {
if (config) {
const { aggregation, xProperty, yProperty, chartType } = config
return `<script src="https://cdn.jsdelivr.net/gh/geonetwork/geonetwork-ui@wc-dist/gn-wc.js"></script>
return `<script src="https://cdn.jsdelivr.net/gh/geonetwork/geonetwork-ui@wc-dist-${
this.version
}/gn-wc.js"></script>
<gn-dataset-view-chart
api-url="${new URL(
this.config.basePath,
Expand All @@ -42,6 +45,7 @@ export class DataViewWebComponentComponent {

constructor(
@Inject(Configuration) private config: Configuration,
@Inject(GN_UI_VERSION) private version: string,
private facade: MdViewFacade
) {}
}
3 changes: 2 additions & 1 deletion libs/feature/record/src/lib/feature-record.module.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { NgModule } from '@angular/core'
import { InjectionToken, NgModule } from '@angular/core'
import { CommonModule } from '@angular/common'
import { UiMapModule } from '@geonetwork-ui/ui/map'
import { StoreModule } from '@ngrx/store'
Expand Down Expand Up @@ -29,6 +29,7 @@ import { DataViewPermalinkComponent } from './data-view-permalink/data-view-perm
import { DataViewWebComponentComponent } from './data-view-web-component/data-view-web-component.component'
import { DataViewShareComponent } from './data-view-share/data-view-share.component'

export const GN_UI_VERSION = new InjectionToken<string>('gnUiVersion')
@NgModule({
declarations: [
RecordMetadataComponent,
Expand Down
6 changes: 5 additions & 1 deletion tools/webcomponent/wc-embedder.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
font-family: 'Open Sans', 'dataFeeder', sans-serif !important;
}
</style>
<script src="https://cdn.jsdelivr.net/gh/geonetwork/geonetwork-ui@wc-dist/gn-wc.js"></script>
<script id="gn-wc-script"></script>
<script>
function showError(message) {
const errorMessage = document.createElement('div')
Expand All @@ -37,6 +37,10 @@

try {
const params = new URL(window.location).searchParams
const version = params.get('v')
document.getElementById(
'gn-wc-script'
).src = `https://cdn.jsdelivr.net/gh/geonetwork/geonetwork-ui@wc-dist-${version}/gn-wc.js`
const elementName = params.get('e')
const attributes = params.getAll('a')

Expand Down
Loading