diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..0be0212 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,24 @@ +name: Publish + +on: + push: + tags: + - '*.*.*' + +jobs: + publish: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + # Setup .npmrc file to publish to npm + - uses: actions/setup-node@v1 + with: + node-version: '12.x' + registry-url: 'https://registry.npmjs.org' + - name: Build + run: | + npm install + - name: Publish + run: npm publish + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..2f61c1f --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,20 @@ +name: Test + +on: + pull_request: + push: + branches: + - master + +jobs: + coverage: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 5 + - name: Install and run tests + run: | + npm ci + npm test + bash <(curl -s https://codecov.io/bash) diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 867150e..0000000 --- a/.travis.yml +++ /dev/null @@ -1,10 +0,0 @@ -language: node_js - -branches: - only: - - master - - /^[0-9]+\.[0-9]+\.[0-9]+.*/ - -after_success: - - bash <(curl -s https://codecov.io/bash) - - bash <(curl -s https://blackbaud.github.io/skyux-travis/after-success.sh) diff --git a/lib/assets.js b/lib/assets.js index 877514b..5b23e33 100644 --- a/lib/assets.js +++ b/lib/assets.js @@ -131,6 +131,8 @@ const formatAssets = (includeContent, isStaticClient, asset, hashFileNames = tru props.content = content; } + props.type = asset.type || 'script'; + return merge({}, asset, props); }; diff --git a/lib/deploy-spa.js b/lib/deploy-spa.js index 85b1fdb..6bd798e 100644 --- a/lib/deploy-spa.js +++ b/lib/deploy-spa.js @@ -11,13 +11,20 @@ async function deploy(settings) { settings.hashFileNames ); + const scripts = assetsWithoutContent.filter(x => x.type === 'script'); + const stylesheets = assetsWithoutContent.filter(x => x.type === 'stylesheet'); + const spa = { name: settings.name, package_config: settings.packageConfig, - scripts: assetsWithoutContent, + scripts, sky_ux_config: settings.skyuxConfig }; + if (stylesheets.length) { + spa.stylesheets = stylesheets; + } + if (settings.rootElementTagName) { spa.root_element_tag_name = settings.rootElementTagName; } diff --git a/lib/deploy-static.js b/lib/deploy-static.js index 0e0c7dd..1f52595 100644 --- a/lib/deploy-static.js +++ b/lib/deploy-static.js @@ -13,14 +13,21 @@ async function register(settings, versionAssets, versionRowKey) { versionAssets ); + const scripts = assetsWithoutContent.filter(x => x.type === 'script'); + const stylesheets = assetsWithoutContent.filter(x => x.type === 'stylesheet'); + const entity = { PartitionKey: azure.generator.String(settings.name), RowKey: azure.generator.String(versionRowKey), - Scripts: azure.generator.String(JSON.stringify(assetsWithoutContent)), + Scripts: azure.generator.String(JSON.stringify(scripts)), PackageConfig: azure.generator.String(JSON.stringify(settings.packageConfig)), SkyUXConfig: azure.generator.String(JSON.stringify(settings.skyuxConfig)) }; + if (stylesheets.length) { + entity.Stylesheets = azure.generator.String(JSON.stringify(stylesheets)); + } + logger.info(`Registering ${versionAssets} as ${versionRowKey}.`); return await azure.registerEntityToTable(settings, entity); } diff --git a/test/lib-assets.spec.js b/test/lib-assets.spec.js index e6b2aa3..6dd2f8f 100644 --- a/test/lib-assets.spec.js +++ b/test/lib-assets.spec.js @@ -70,6 +70,28 @@ describe('skyux-deploy lib assets', () => { expect(fs.statSync).toHaveBeenCalled(); }); + it('should set the asset type to "script" by default', () => { + spyOn(fs, 'existsSync').and.returnValue(true); + spyOn(fs, 'readFileSync').and.returnValue(''); + + let stubs = {}; + stubs[path.join(process.cwd(), 'dist', 'metadata.json')] = [ + { + name: 'custom-name.js' + }, + { + name: 'styles.css', + type: 'stylesheet' + } + ]; + + const lib = proxyquire('../lib/assets', stubs); + const assets = lib.getDistAssets(); + + expect(assets[0].type).toEqual('script'); + expect(assets[1].type).toEqual('stylesheet'); + }); + it('should allow disabling the file name hash', () => { const readFileSync = fs.readFileSync; spyOn(fs, 'existsSync').and.returnValue(true); diff --git a/test/lib-deploy-spa.spec.js b/test/lib-deploy-spa.spec.js index 553057d..afcadcf 100644 --- a/test/lib-deploy-spa.spec.js +++ b/test/lib-deploy-spa.spec.js @@ -8,20 +8,24 @@ describe('skyux-deploy lib deploy SPA', () => { let assetsMock; let portalMock; let lib; + let mockAssets; beforeEach(() => { spyOn(logger, 'error'); spyOn(logger, 'info'); + mockAssets = [ + { + name: 'my-asset.js', + content: 'my-content', + type: 'script' + } + ]; + assetsMock = { getDistAssets: jasmine.createSpy('getDistAssets') .and - .returnValue([ - { - name: 'my-asset.js', - content: 'my-content' - } - ]), + .returnValue(mockAssets), }; portalMock = { @@ -62,7 +66,8 @@ describe('skyux-deploy lib deploy SPA', () => { scripts: [ { name: 'my-asset.js', - content: 'my-content' + content: 'my-content', + type: 'script' } ] }, @@ -89,4 +94,28 @@ describe('skyux-deploy lib deploy SPA', () => { expect(actualTagName).toEqual('app-root'); }); + it('should call deploySpa with style sheets', async () => { + mockAssets.push({ + name: 'styles.css', + type: 'stylesheet' + }); + + await lib( + { + azureStorageAccessKey: 'abc', + name: 'custom-name2', + version: 'custom-version2', + skyuxConfig: { test1: true }, + packageConfig: { test2: true } + } + ); + + expect(portalMock.deploySpa.calls.mostRecent().args[1].stylesheets).toEqual([ + { + name: 'styles.css', + type: 'stylesheet' + } + ]); + }); + }); diff --git a/test/lib-deploy-static.spec.js b/test/lib-deploy-static.spec.js index 19f4350..6cc6061 100644 --- a/test/lib-deploy-static.spec.js +++ b/test/lib-deploy-static.spec.js @@ -5,13 +5,7 @@ describe('skyux-deploy lib deploy static', () => { const mock = require('mock-require'); const logger = require('@blackbaud/skyux-logger'); - const distAsset = [ - { - name: 'my-asset.js', - content: 'my-content' - } - ]; - + let distAsset; let assetsMock; let azureMock; let lib; @@ -20,6 +14,14 @@ describe('skyux-deploy lib deploy static', () => { spyOn(logger, 'error'); spyOn(logger, 'info'); + distAsset = [ + { + name: 'my-asset.js', + content: 'my-content', + type: 'script' + } + ]; + assetsMock = { getDistAssets: jasmine.createSpy('getDistAssets').and.returnValue(distAsset) }; @@ -65,6 +67,28 @@ describe('skyux-deploy lib deploy static', () => { ); }); + it('should call registerEntityToTable with style sheets if they exist', async () => { + distAsset.push({ + name: 'styles.css', + type: 'stylesheet' + }); + + const settings = { + azureStorageAccessKey: 'abc', + isStaticClient: true, + name: 'custom-name2', + version: 'custom-version2', + skyuxConfig: { test1: true }, + packageConfig: { test2: true } + }; + + await lib(settings); + + expect(azureMock.registerEntityToTable.calls.mostRecent().args[1].Stylesheets).toEqual( + '[{"name":"styles.css","type":"stylesheet"}]' + ); + }); + it('should log a warning if version is invalid', async () => { const settings = { version: 'INVALID_VERSION'