From 54d02c53102eacad93125373d2482533e71427f0 Mon Sep 17 00:00:00 2001 From: zFernand0 Date: Fri, 5 Nov 2021 15:32:22 +0000 Subject: [PATCH] Add 'npm run test:act' script Signed-off-by: zFernand0 --- .github/README.md | 12 +-- .github/_act_zowe-cli_example.yml | 139 ++++++++++++++++++++++++++++++ .github/workflows/zowe-cli.yml | 5 +- .gitignore | 3 +- package.json | 1 + scripts/testCliWorkflow.js | 103 ++++++++++++++++++++++ 6 files changed, 252 insertions(+), 11 deletions(-) create mode 100644 .github/_act_zowe-cli_example.yml create mode 100644 scripts/testCliWorkflow.js diff --git a/.github/README.md b/.github/README.md index 5e183c72bf..bcf684c1cf 100644 --- a/.github/README.md +++ b/.github/README.md @@ -4,14 +4,10 @@ General information about GH Workflows ### Using `act` -1. Read about it: https://github.com/nektos/act (Requires Docker) -2. Install it https://github.com/nektos/act#installation -3. Run: `act --eventpath .github/_act_event.json --workflows .github/workflows/zowe-cli.yml --reuse` - - Equivalent: `act -re .github/_act_event.json -W .github/workflows/zowe-cli.yml` - -`100.` To start from scratch, just remove the containers - - `docker rm act-Zowe-CLI-Build-Linux --force` - - `docker rm act-Zowe-CLI-Cross-Platform-Test --force` +- Read it: https://github.com/nektos/act (Requires Docker) +- Install it https://github.com/nektos/act#installation +- Run it: `npm run test:act` +- Clean it: `npm run test:act -- --clean` **Known Issues for `nektos/act@0.2.24`** diff --git a/.github/_act_zowe-cli_example.yml b/.github/_act_zowe-cli_example.yml new file mode 100644 index 0000000000..6ea3df4ea7 --- /dev/null +++ b/.github/_act_zowe-cli_example.yml @@ -0,0 +1,139 @@ +name: Zowe CLI +'on': + push: + paths-ignore: + - zowex/** + - .github/workflows/rust-cli*.yml + pull_request: + paths-ignore: + - zowex/** + - .github/workflows/rust-cli*.yml + workflow_dispatch: + inputs: + binary-type: + description: Specify whether to use a `debug` or a `release` version of the binary + default: debug + required: false +jobs: + prebuild: + name: Build Linux + runs-on: ubuntu-latest + container: quay.io/pypa/manylinux2014_x86_64 + if: '(github.event_name == ''push'' || github.event.pull_request.head.repo.full_name != github.repository) && !contains(github.event.head_commit.message, ''[ci skip]'')' + steps: + - uses: actions/checkout@v2 + - name: Install Rust toolchain + if: (!github.event.run_with_act) + id: install-rust + uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: stable + override: true + - name: Install Rust toolchain + if: github.event.run_with_act + run: | + yum install cargo -y + cargo --version + - name: Build + run: 'cargo build --verbose ${{ github.event.inputs.binary-type == ''release'' && ''--release'' || '''' }} --manifest-path=zowex/Cargo.toml' + - name: Create Archive + run: 'tar -cvzf zowe.tgz -C zowex/target/${{ github.event.inputs.binary-type == ''release'' && ''release'' || ''debug'' }} zowe' + - name: Upload the Prebuilt Linux Binary + if: (!github.event.run_with_act) + uses: actions/upload-artifact@v2 + with: + name: zowe-linux-latest.tgz + path: zowe.tgz + - name: Upload the Prebuilt Linux Binary + if: (github.event.run_with_act) + run: mkdir -p /toolcache/artifacts && cp zowe.tgz /toolcache/artifacts/zowe-linux-latest.tgz + test: + name: Cross-Platform Test + runs-on: '${{ matrix.os }}' + needs: prebuild + strategy: + fail-fast: false + matrix: + node-version: + - 16.x + os: + - ubuntu-latest + env: + OS: '${{ matrix.os }}' + NODE: '${{ matrix.node-version }}' + NODE_OPTIONS: '--max_old_space_size=4096' + if: '(github.event_name == ''push'' || github.event.pull_request.head.repo.full_name != github.repository) && !contains(github.event.head_commit.message, ''[ci skip]'')' + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: 'Use Node.js ${{ matrix.node-version }}' + uses: actions/setup-node@v2 + with: + node-version: '${{ matrix.node-version }}' + - name: Get NPM Version + id: npm-version + run: 'echo "::set-output name=number::$(npm --version)"' + - name: Use NPM v8 + id: npm8 + run: npm install -g npm@^8 + - name: Install Node Package Dependencies + id: install + run: npm ci + - name: Use Original NPM Version + id: original-npm-version + run: 'npm install -g npm@${{ steps.npm-version.outputs.number }}' + - name: Build Source + id: build + run: npm run build --if-present + - name: Build Windows Binary + if: matrix.os == 'windows-latest' + run: | + cargo build --verbose ${{ github.event.inputs.binary-type == 'release' && '--release' || '' }} --manifest-path=zowex/Cargo.toml + tar -cvzf zowe.tgz -C zowex/target/${{ github.event.inputs.binary-type == 'release' && 'release' || 'debug' }} zowe.exe + - name: Build MacOS Binary + if: matrix.os == 'macos-latest' + run: | + cargo build --verbose ${{ github.event.inputs.binary-type == 'release' && '--release' || '' }} --manifest-path=zowex/Cargo.toml + tar -cvzf zowe.tgz -C zowex/target/${{ github.event.inputs.binary-type == 'release' && 'release' || 'debug' }} zowe + - name: Download Prebuilt Linux Binary + if: matrix.os == 'ubuntu-latest' && !github.event.run_with_act + uses: actions/download-artifact@v2 + with: + name: zowe-linux-latest.tgz + - name: Download Prebuilt Linux Binary + if: matrix.os == 'ubuntu-latest' && github.event.run_with_act + run: cp /toolcache/artifacts/zowe-linux-latest.tgz zowe.tgz + - name: Archive Binary + if: matrix.os != 'ubuntu-latest' + id: upload-binary + uses: actions/upload-artifact@v2 + with: + name: 'zowe-${{ matrix.os }}.tgz' + path: zowe.tgz + - name: Setup Binary in PATH + id: setup-binary + run: tar -xvzf zowe.tgz -C ./node_modules/.bin --overwrite + - name: Unit Tests + id: unit + if: '${{ always() && steps.build.outcome == ''success'' }} || github.event.run_with_act' + run: 'npm run test:unit >> unit-tests.txt' + - name: Integration Tests + id: integration + if: '${{ always() && steps.build.outcome == ''success'' }} || github.event.run_with_act' + run: 'npm run test:integration >> integration-tests.txt' + - name: Archive Results + id: upload + if: '${{ always() && steps.build.outcome == ''success'' }} && !github.event.run_with_act' + uses: actions/upload-artifact@v2 + with: + name: '${{ matrix.os }}-${{ matrix.node-version }}-results' + path: | + __tests__/__results__/ + unit-tests.txt + integration-tests.txt + - name: Upload Results to Codecov + if: '${{ always() && steps.build.outcome == ''success'' }} && !github.event.run_with_act' + uses: codecov/codecov-action@v1.0.7 + with: + env_vars: 'OS,NODE' diff --git a/.github/workflows/zowe-cli.yml b/.github/workflows/zowe-cli.yml index ad0b9bab74..860474a9f5 100644 --- a/.github/workflows/zowe-cli.yml +++ b/.github/workflows/zowe-cli.yml @@ -20,7 +20,7 @@ on: required: false jobs: - build-linux: + prebuild: name: Build Linux runs-on: ubuntu-latest @@ -34,6 +34,7 @@ jobs: - name: Install Rust toolchain if: (!github.event.run_with_act) + id: install-rust uses: actions-rs/toolchain@v1 with: profile: minimal @@ -66,7 +67,7 @@ jobs: test: name: Cross-Platform Test runs-on: ${{ matrix.os }} - needs: build-linux + needs: prebuild strategy: fail-fast: false matrix: diff --git a/.gitignore b/.gitignore index d69c43c2a0..a7bc20c77d 100644 --- a/.gitignore +++ b/.gitignore @@ -101,4 +101,5 @@ imperative_debug.log /packages/cli/prebuilds zowe.config.json zowe.config.user.json -zowe.schema.json \ No newline at end of file +zowe.schema.json +.github/_act_*.yml diff --git a/package.json b/package.json index 708e4b904d..589b9a8117 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "lint:tests": "eslint \"**/__tests__/**/*.ts\"", "update:imperative": "npm i --save --save-exact @zowe/imperative@next && syncpack fix-mismatches --dev --prod --filter @zowe/imperative", "test": "npm run test:unit && npm run test:integration && npm run test:system", + "test:act": "node scripts/testCliWorkflow.js", "test:cleanResults": "rimraf __tests__/__results__", "test:cleanUpProfiles": "sh __tests__/__scripts__/clean_profiles.sh", "test:integration": "cross-env FORCE_COLOR=1 jest \".*__tests__.*\\**\\.integration\\.(spec|test)\\.ts\\$\" --coverage false", diff --git a/scripts/testCliWorkflow.js b/scripts/testCliWorkflow.js new file mode 100644 index 0000000000..b44da71ed9 --- /dev/null +++ b/scripts/testCliWorkflow.js @@ -0,0 +1,103 @@ +/* +* This program and the accompanying materials are made available under the terms of the +* Eclipse Public License v2.0 which accompanies this distribution, and is available at +* https://www.eclipse.org/legal/epl-v20.html +* +* SPDX-License-Identifier: EPL-2.0 +* +* Copyright Contributors to the Zowe Project. +* +*/ + +/** + * Run Github workflows locally + * + * Steps: + * 1. Verifies that act is installed + * 2. Reads given workflow (e.g. zowe-cli.yml) + * 3. Replaces all known steps that could fail + * 4. Generates a .github/_act_.yml + * 5. Executes `act -rW .github/_act_.yml -e .github/_act_event.json + * Creates a custom yaml file for running locally with act + */ +const cp = require("child_process"); +const fs = require("fs"); +const path = require("path"); +const yaml = require("js-yaml"); +const chalk = require("chalk"); +const rl = require("readline").createInterface({input: process.stdin, output: process.stdout}); + +const wfPath = ".github/workflows/zowe-cli.yml"; +const epPath = ".github/_act_event.json"; + +const _sleep = async (ms) => { + return new Promise(resolve => setTimeout(resolve, ms ?? 1000)); +} +const _handle = async (fun, msg) => { + try { + await fun(); + } catch(_) { + if (msg) console.log(chalk.red(msg)); + console.error(_.toString()); + process.exit(1); + } +} + +const _yesno = async (q) => { + const question = (str) => new Promise(resolve => rl.question(str, resolve)); + const res = (await question(q)) ?? "no"; + return res.toLowerCase() === "yes" || res.toLowerCase() === "y"; +} + +async function clean() { + const containers = ["act-Zowe-CLI-Build-Linux", "act-Zowe-CLI-Cross-Platform-Test"]; + for (const c of containers) { + if (await _yesno(`Remove Container: ${c}\nAre you sure? [y/n]`)) { + cp.spawn("docker", ["rm", c, "--force"], {stdio: "inherit"}); + } else { + console.log(`Skip Container: ${c}`); + } + console.log(); + await _sleep(); + } +} + +async function main() { + // Check nektos/act version + _handle(() => { + console.log(`Using "nektos/act", ${cp.spawnSync("act", ["--version"]).stdout.toString().trim()}`); + }, `Please install "act", https://github.com/nektos/act`); + + await _sleep(); + + // Read given workflow + let wf; + _handle(() => { + wf = yaml.load(fs.readFileSync(path.resolve(__dirname, "..", wfPath))); + }, `Unable to read "${wfPath}"`); + + // Replace known steps that could fail + // console.log(wf); + + // Output generated workflow + const genWfPath = path.resolve(__dirname, "../.github", `_act_${path.basename(wfPath)}`); + console.log("Generating new workflow..."); + await _sleep(); + _handle(() => { + fs.writeFileSync(genWfPath, yaml.dump(wf, {indent: 2, lineWidth: -1}), {flag: "w"}); + }, `Unable to write "${genWfPath}"`); + + // Execute workflow locally + console.log("Executing new workflow..."); + await _sleep(); + cp.spawn("act", ["-rW", genWfPath, "-e", epPath], {stdio: "inherit"}); +} + +(async () => { + if (process.argv.indexOf("--clean") > 0) { + await clean(); + } else { + await main(); + } + rl.close(); +})(); \ No newline at end of file