Kaynağa Gözat

chore: Add Publish & Install workflow to CI

Tests the publishing & installation via `@vendure/create` across supported platforms & Node versions.
Michael Bromley 5 yıl önce
ebeveyn
işleme
c9cf090828

+ 0 - 1
.github/workflows/build_and_test.yml

@@ -7,7 +7,6 @@ on:
   pull_request:
     branches:
     - master
-
 env:
   CI: true
   node: 12.x

+ 37 - 26
.github/workflows/publish_and_install.yml

@@ -1,50 +1,61 @@
 name: Publish & Install
-# Temporarily disabled this workflow because the last step (installing from Verdaccio) is flaky and
-# randomly failing despite numerous attempts to stabilize. Therefore this is not useful at
-# the moment.
-# on:
-#   push:
-#     branches:
-#     - master
-#   pull_request:
-#     branches:
-#     - master
 on:
-  deployment
+  push:
+    branches:
+    - master
+  pull_request:
+    branches:
+    - master
+defaults:
+  run:
+    shell: bash
 jobs:
   publish_install:
     runs-on: ${{ matrix.os }}
     strategy:
       matrix:
-        os: [ubuntu-latest, macOS-latest]
-        node-version: [10.x, 12.x]
+        os: [ubuntu-latest, windows-latest, macos-latest]
+        node-version: [12.x, 14.x]
+      fail-fast: false
     steps:
-    - uses: actions/checkout@v1
+    - uses: actions/checkout@v2
     - name: Use Node.js ${{ matrix.node-version }}
       uses: actions/setup-node@v1
       with:
         node-version: ${{ matrix.node-version }}
-    - name: Install & bootstrap
-      run: |
-        yarn install
-        yarn bootstrap
-      env:
-        CI: true
     - name: Install Verdaccio
       run: |
         npm install -g verdaccio
+        npm install -g verdaccio-auth-memory
+        npm install -g verdaccio-memory
+        npm install -g npm-auth-to-token@1.0.0
+        tmp_registry_log=`mktemp`
         mkdir -p $HOME/.config/verdaccio
         cp -v ./.github/workflows/verdaccio/config.yaml $HOME/.config/verdaccio/config.yaml
-        verdaccio --config $HOME/.config/verdaccio/config.yaml &
+        nohup verdaccio --config $HOME/.config/verdaccio/config.yaml &>$tmp_registry_log &
+        npm-auth-to-token -u test -p test -e test@test.com -r http://0.0.0.0:4873
+    - name: Windows dependencies
+      if: matrix.os == 'windows-latest'
+      run: npm install -g @angular/cli
+    - name: Install & bootstrap
+      run: |
+        yarn config set unsafe-perm true
+        yarn install --network-timeout 1000000
+        yarn bootstrap
+      env:
+        CI: true
     - name: Publish to Verdaccio
       run: |
-        npm set //registry.npmjs.org/:_authToken=${{ secrets.NPM_AUTH_TOKEN }}
-        npm set //localhost:4873/:_authToken=${{ secrets.VERDACCIO_AUTH_TOKEN }}
-        npm set registry=http://localhost:4873/
-        yarn lerna publish prepatch --preid ci --no-push --no-git-tag-version --no-commit-hooks --force-publish "*" --yes --dist-tag ci --registry http://localhost:4873/
+        yarn lerna publish prepatch --preid ci --no-push --no-git-tag-version --no-commit-hooks --force-publish "*" --yes --dist-tag ci --registry http://0.0.0.0:4873
     - name: Install via @vendure/create
       run: |
         mkdir -p $HOME/install
         cd $HOME/install
+        npm set registry=http://0.0.0.0:4873
         npm dist-tag ls @vendure/create
-        npx @vendure/create@ci test-app --ci --use-npm
+        npx @vendure/create@ci test-app --ci --use-npm --log-level info
+    - name: Server smoke tests
+      run: |
+        cd $HOME/install/test-app
+        npm run start &
+        node $GITHUB_WORKSPACE/.github/workflows/scripts/smoke-tests

+ 117 - 0
.github/workflows/scripts/smoke-tests.js

@@ -0,0 +1,117 @@
+const http = require('http');
+
+const healthUrl = 'http://localhost:3000/health';
+const shopUrl = 'http://localhost:3000/shop-api';
+const adminUrl = 'http://localhost:3000/admin-api';
+
+/**
+ * This script is run as part of the "publish & install" workflow, and performs some very simple
+ * tests of the Vendure API to make sure it is running and responding in the expected way.
+ */
+awaitServerStartup()
+    .then(() => runTests())
+    .catch((e) => {
+        console.log('Tests failed!');
+        console.log(e);
+        process.exit(1);
+    });
+
+function awaitServerStartup() {
+    console.log('Checking for availability of Vendure Server...');
+    let attempts = 0;
+    return new Promise((resolve, reject) => {
+        async function poll() {
+            try {
+                let result = await request(healthUrl, 'GET');
+                if (result && result.status === 'ok') {
+                    console.log('Server is running!');
+                    resolve();
+                    return;
+                }
+            } catch (e) {
+                //
+            }
+            attempts++;
+            if (attempts < 30) {
+                console.log('Server not yet available, waiting 1s...');
+                setTimeout(poll, 1000);
+            } else {
+                reject('Unable to establish connection to Vendure server!');
+            }
+        }
+        poll();
+    });
+}
+
+async function runTests() {
+    console.log('Running some smoke tests...');
+    const result1 = await gqlRequest(
+        shopUrl,
+        `
+        { "query": "{ products(options: { take: 3 })  { items { id name } } }" }
+    `,
+    );
+    assertEquals(result1.data.products.items, [
+        { id: '1', name: 'Laptop' },
+        { id: '2', name: 'Tablet' },
+        { id: '3', name: 'Wireless Optical Mouse' },
+    ]);
+
+    const result2 = await gqlRequest(
+        adminUrl,
+        `
+        { "query": "mutation { login(username: \\"superadmin\\" password: \\"superadmin\\")  { user { id } } }" }
+    `,
+    );
+    assertEquals(result2.data.login, { user: { id: '1' } });
+
+    console.log(`All tests passed!`);
+    process.exit(0);
+}
+
+function gqlRequest(url, body) {
+    return request(url, 'POST', body).catch((e) => console.log(e));
+}
+
+/**
+ *
+ * @param url
+ * @param body
+ * @return {Promise<unknown>}
+ */
+function request(url, method, body) {
+    const options = {
+        method,
+        headers: {
+            'Content-Type': 'application/json',
+        },
+    };
+
+    return new Promise((resolve, reject) => {
+        const req = http.request(url, options, (res) => {
+            var response = '';
+            res.setEncoding('utf8');
+            res.on('data', (chunk) => {
+                return (response += chunk);
+            });
+            res.on('end', () => {
+                resolve(JSON.parse(response));
+            });
+        });
+
+        req.on('error', (e) => {
+            reject(e);
+        });
+
+        // Write data to request body
+        req.write(body || '');
+        req.end();
+    });
+}
+
+function assertEquals(actual, expected) {
+    if (JSON.stringify(actual) !== JSON.stringify(expected)) {
+        console.log(`Expected [${JSON.stringify(actual)}] to equal [${JSON.stringify(expected)}]`);
+        process.exit(1);
+    }
+}

+ 4 - 4
.github/workflows/verdaccio/config.yaml

@@ -34,8 +34,8 @@ uplinks:
 packages:
   '@*/*':
     # scoped packages
-    access: $anonymous
-    publish: $anonymous
+    access: $all
+    publish: $all
     proxy: npmjs
 
   '**':
@@ -44,11 +44,11 @@ packages:
     #
     # you can specify usernames/groupnames (depending on your auth plugin)
     # and three keywords: "$all", "$anonymous", "$authenticated"
-    access: $anonymous
+    access: $all
 
     # allow all known users to publish packages
     # (anyone can register by default, remember?)
-    publish: $anonymous
+    publish: $all
 
     # if package is not available locally, proxy requests to 'npmjs' registry
     proxy: npmjs

+ 0 - 3
.gitignore

@@ -223,9 +223,6 @@ DocProject/Help/*.hhp
 DocProject/Help/Html2
 DocProject/Help/html
 
-# Click-Once directory
-publish/
-
 # Publish Web Output
 *.[Pp]ublish.xml
 *.azurePubxml

+ 15 - 15
packages/admin-ui/package.json

@@ -6,7 +6,7 @@
     "ng": "ng",
     "start": "node scripts/set-version.js && ng serve",
     "build:app": "ng build --prod",
-    "build": "node scripts/copy-package-json.js && node scripts/set-version.js && node scripts/build-public-api.js && ng build vendure-admin-lib --prod && node scripts/compile-styles.js",
+    "build": "node scripts/copy-package-json.js && node scripts/set-version.js && node scripts/build-public-api.js && yarn ng build vendure-admin-lib --prod && node scripts/compile-styles.js",
     "watch": "ng build --watch=true",
     "test": "ng test --watch=false --browsers=ChromeHeadlessCI --progress=false",
     "lint": "tslint --fix",
@@ -18,15 +18,15 @@
     "directory": "package"
   },
   "dependencies": {
-    "@angular/animations": "9.1.0",
-    "@angular/cdk": "9.2.0",
-    "@angular/common": "9.1.0",
-    "@angular/core": "9.1.0",
-    "@angular/forms": "9.1.0",
-    "@angular/language-service": "9.1.0",
-    "@angular/platform-browser": "9.1.0",
-    "@angular/platform-browser-dynamic": "9.1.0",
-    "@angular/router": "9.1.0",
+    "@angular/animations": "9.1.7",
+    "@angular/cdk": "9.2.3",
+    "@angular/common": "9.1.7",
+    "@angular/core": "9.1.7",
+    "@angular/forms": "9.1.7",
+    "@angular/language-service": "9.1.7",
+    "@angular/platform-browser": "9.1.7",
+    "@angular/platform-browser-dynamic": "9.1.7",
+    "@angular/router": "9.1.7",
     "@biesbjerg/ngx-translate-extract-marker": "^1.0.0",
     "@clr/angular": "^3.0.0",
     "@clr/core": "^3.0.0",
@@ -65,11 +65,11 @@
     "zone.js": "~0.10.2"
   },
   "devDependencies": {
-    "@angular-devkit/build-angular": "~0.900.5",
-    "@angular-devkit/build-ng-packagr": "~0.900.5",
-    "@angular/cli": "^9.0.5",
-    "@angular/compiler": "^9.0.6",
-    "@angular/compiler-cli": "^9.0.6",
+    "@angular-devkit/build-angular": "~0.901.6",
+    "@angular-devkit/build-ng-packagr": "~0.901.6",
+    "@angular/cli": "^9.1.6",
+    "@angular/compiler": "^9.1.7",
+    "@angular/compiler-cli": "^9.1.7",
     "@biesbjerg/ngx-translate-extract": "^6.0.3",
     "@types/jasmine": "~3.5.10",
     "@types/jasminewd2": "~2.0.6",