Verify Publish #16
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Verify Publish | |
| # Manually triggered smoke test against the npm registry — run after a Publish | |
| # Package workflow completes. Installs the just-published package into a clean | |
| # environment and exercises it enough to catch "published but broken" failures | |
| # (bin missing +x, workspace:* deps not rewritten, missing exports, etc.). | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| package: | |
| description: 'Package to verify' | |
| required: true | |
| default: '@agentworkforce/cli' | |
| type: choice | |
| options: | |
| - '@agentworkforce/events' | |
| - '@agentworkforce/persona-kit' | |
| - '@agentworkforce/runtime' | |
| - '@agentworkforce/compose' | |
| - '@agentworkforce/delivery' | |
| - '@agentworkforce/workload-router' | |
| - '@agentworkforce/deploy' | |
| - '@agentworkforce/review-kit' | |
| - '@agentworkforce/mcp-workforce' | |
| - '@agentworkforce/daytona-runner' | |
| - '@agentworkforce/local-surface' | |
| - '@agentworkforce/cli' | |
| - 'agentworkforce' | |
| version: | |
| description: 'Version to verify (defaults to the "latest" dist-tag)' | |
| required: false | |
| default: latest | |
| tag: | |
| description: 'Alternate dist-tag to pull from if `version` is left as default' | |
| required: false | |
| default: latest | |
| permissions: | |
| contents: read | |
| jobs: | |
| verify: | |
| name: Install + smoke test | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Setup Node | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '26.5.0' | |
| registry-url: 'https://registry.npmjs.org' | |
| - name: Resolve version | |
| id: resolve | |
| run: | | |
| INPUT='${{ github.event.inputs.version }}' | |
| TAG='${{ github.event.inputs.tag }}' | |
| if [ -z "$INPUT" ] || [ "$INPUT" = "latest" ]; then | |
| RESOLVED=$(npm view "${{ github.event.inputs.package }}@$TAG" version) | |
| else | |
| RESOLVED="$INPUT" | |
| fi | |
| echo "version=$RESOLVED" >> "$GITHUB_OUTPUT" | |
| echo "Verifying ${{ github.event.inputs.package }}@$RESOLVED" | |
| - name: CLI smoke test | |
| if: ${{ github.event.inputs.package == 'agentworkforce' }} | |
| run: | | |
| set -euo pipefail | |
| # The top-level `agentworkforce` package is the user-facing global | |
| # CLI package. The scoped @agentworkforce/cli package is an | |
| # implementation dependency and intentionally does not declare a bin. | |
| BIN="agentworkforce" | |
| npm install -g "${{ github.event.inputs.package }}@${{ steps.resolve.outputs.version }}" | |
| # --help should exit 0 and print the usage block. | |
| output=$("$BIN" --help) | |
| echo "$output" | |
| echo "$output" | grep -q "Usage: $BIN " || { | |
| echo "::error::--help output did not include expected usage block (looking for 'Usage: $BIN ')" >&2 | |
| exit 1 | |
| } | |
| # Bare invocation should exit non-zero with the usage text. | |
| if "$BIN" > /dev/null 2>&1; then | |
| echo "::error::bare $BIN should exit non-zero (missing subcommand)" >&2 | |
| exit 1 | |
| fi | |
| # Unknown persona should exit non-zero and list the catalog. | |
| if "$BIN" agent __definitely_not_a_persona__ > /dev/null 2>&1; then | |
| echo "::error::unknown persona should exit non-zero" >&2 | |
| exit 1 | |
| fi | |
| echo "CLI smoke test passed." | |
| - name: Scoped CLI package smoke test | |
| if: ${{ github.event.inputs.package == '@agentworkforce/cli' }} | |
| run: | | |
| set -euo pipefail | |
| WORKDIR=$(mktemp -d) | |
| cd "$WORKDIR" | |
| npm init -y > /dev/null | |
| npm install "${{ github.event.inputs.package }}@${{ steps.resolve.outputs.version }}" | |
| node --input-type=module <<'EOF' | |
| import { readFileSync } from 'node:fs'; | |
| import assert from 'node:assert/strict'; | |
| const pkg = JSON.parse(readFileSync('node_modules/@agentworkforce/cli/package.json', 'utf8')); | |
| assert.equal(pkg.name, '@agentworkforce/cli'); | |
| assert.equal(pkg.version, '${{ steps.resolve.outputs.version }}'); | |
| assert.equal(pkg.bin, undefined); | |
| const mod = await import('./node_modules/@agentworkforce/cli/dist/cli.js'); | |
| assert.equal(typeof mod.main, 'function'); | |
| console.log(`scoped CLI package smoke passed for ${pkg.name}@${pkg.version}`); | |
| EOF | |
| - name: Library smoke test (ESM import + exports surface) | |
| if: ${{ github.event.inputs.package != '@agentworkforce/cli' && github.event.inputs.package != 'agentworkforce' }} | |
| run: | | |
| set -euo pipefail | |
| WORKDIR=$(mktemp -d) | |
| cd "$WORKDIR" | |
| npm init -y > /dev/null | |
| node -e "require('fs').writeFileSync('package.json', JSON.stringify({...require('./package.json'), type:'module'}, null, 2))" | |
| npm install "${{ github.event.inputs.package }}@${{ steps.resolve.outputs.version }}" | |
| cat > check.mjs <<'EOF' | |
| const mod = await import(process.argv[2]); | |
| const exports = Object.keys(mod).sort(); | |
| if (exports.length === 0) { | |
| console.error('no exports from package'); | |
| process.exit(1); | |
| } | |
| console.log('exports:', exports.join(', ')); | |
| EOF | |
| node check.mjs "${{ github.event.inputs.package }}" | |
| echo "Library smoke test passed." | |
| - name: Summary | |
| if: always() | |
| run: | | |
| { | |
| echo "### Verify Publish" | |
| echo "" | |
| echo "- **package**: \`${{ github.event.inputs.package }}\`" | |
| echo "- **version**: \`${{ steps.resolve.outputs.version }}\`" | |
| echo "- **result**: ${{ job.status }}" | |
| } >> "$GITHUB_STEP_SUMMARY" |