From 08636d840a545d54628888b48b9a6367ba1a528c Mon Sep 17 00:00:00 2001 From: Rhuan Barreto Date: Wed, 25 Mar 2026 03:14:11 +0100 Subject: [PATCH 1/2] ci: consolidate PR checks into single "Validate Code" gate job MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Merge smoke-test.yml into code-pull-request.yml and add a gate job ("Validate Code") that depends on all other jobs. This provides a single required status check for branch protection that blocks the PR if any job fails — validate, Windows smoke test, or Linux smoke test. Also removes deploy-docs.yml (docs deployed via Cloudflare Pages). --- .github/workflows/code-pull-request.yml | 253 +++++++++++++++++++++++- .github/workflows/deploy-docs.yml | 58 ------ .github/workflows/smoke-test.yml | 245 ----------------------- 3 files changed, 252 insertions(+), 304 deletions(-) delete mode 100644 .github/workflows/deploy-docs.yml delete mode 100644 .github/workflows/smoke-test.yml diff --git a/.github/workflows/code-pull-request.yml b/.github/workflows/code-pull-request.yml index 0aae8ad1..582958f6 100644 --- a/.github/workflows/code-pull-request.yml +++ b/.github/workflows/code-pull-request.yml @@ -17,7 +17,7 @@ concurrency: jobs: validate: - name: Validate Code + name: Lint, Test & Check runs-on: ubuntu-latest timeout-minutes: 10 if: github.event_name != 'pull_request' || github.event.pull_request.draft == false @@ -60,3 +60,254 @@ jobs: with: path: /home/runner/.bun/install/cache key: ${{ steps.restore-bun-cache.outputs.cache-primary-key }} + + smoke-windows: + name: Smoke Test (Windows) + runs-on: windows-latest + timeout-minutes: 15 + if: github.event_name != 'pull_request' || github.event.pull_request.draft == false + steps: + - name: Checkout code + uses: actions/checkout@v6 + with: + fetch-depth: 0 + + - uses: moonrepo/setup-toolchain@v0 + with: + auto-install: true + + - name: Install dependencies + run: bun install --frozen-lockfile + + - name: Lint + run: bun run lint + + - name: Typecheck + run: bun run typecheck + + - name: Format check + run: bun run format:check + + - name: Tests + run: bun test --timeout 60000 + + - name: Build Windows binary + run: bun build src/cli.ts --compile --bytecode --outfile dist/archgate-smoke-test + + - name: Smoke test binary + shell: pwsh + run: | + $binary = "dist/archgate-smoke-test.exe" + if (-not (Test-Path $binary)) { + Write-Error "Binary not found at $binary" + exit 1 + } + $output = & $binary --version 2>&1 + Write-Host "archgate version: $output" + if ($LASTEXITCODE -ne 0) { + Write-Error "Binary exited with code $LASTEXITCODE" + exit 1 + } + + - name: Smoke test binary from install dir + shell: pwsh + run: | + # Simulate binary install at %APPDATA%\archgate\ + $installDir = Join-Path $env:APPDATA "archgate" + New-Item -Path $installDir -ItemType Directory -Force | Out-Null + Copy-Item "dist/archgate-smoke-test.exe" (Join-Path $installDir "archgate.exe") + $output = & (Join-Path $installDir "archgate.exe") --version 2>&1 + Write-Host "archgate version from binary install dir: $output" + if ($LASTEXITCODE -ne 0) { + Write-Error "Binary exited with code $LASTEXITCODE" + exit 1 + } + Remove-Item -Path $installDir -Recurse -Force -ErrorAction SilentlyContinue + + - name: Smoke test binary from proto dir + shell: pwsh + run: | + # Simulate proto install at ~/.proto/tools/archgate// + $protoDir = Join-Path $env:USERPROFILE ".proto" "tools" "archgate" "0.0.0" + New-Item -Path $protoDir -ItemType Directory -Force | Out-Null + Copy-Item "dist/archgate-smoke-test.exe" (Join-Path $protoDir "archgate.exe") + $output = & (Join-Path $protoDir "archgate.exe") --version 2>&1 + Write-Host "archgate version from proto dir: $output" + if ($LASTEXITCODE -ne 0) { + Write-Error "Binary exited with code $LASTEXITCODE" + exit 1 + } + Remove-Item -Path (Join-Path $env:USERPROFILE ".proto") -Recurse -Force -ErrorAction SilentlyContinue + + - name: Smoke test binary from node_modules + shell: pwsh + run: | + # Simulate local dev dependency install + $projectDir = Join-Path $env:TEMP "archgate-local-smoke" + $binDir = Join-Path $projectDir "node_modules" ".bin" + New-Item -Path $binDir -ItemType Directory -Force | Out-Null + Set-Content -Path (Join-Path $projectDir "package.json") -Value "{}" + Set-Content -Path (Join-Path $projectDir "bun.lock") -Value "" + Copy-Item "dist/archgate-smoke-test.exe" (Join-Path $binDir "archgate.exe") + $output = & (Join-Path $binDir "archgate.exe") --version 2>&1 + Write-Host "archgate version from node_modules: $output" + if ($LASTEXITCODE -ne 0) { + Write-Error "Binary exited with code $LASTEXITCODE" + exit 1 + } + Remove-Item -Path $projectDir -Recurse -Force -ErrorAction SilentlyContinue + + - name: Smoke test install.ps1 + shell: pwsh + env: + ARCHGATE_VERSION: ${{ vars.LATEST_RELEASE_TAG || '' }} + GH_TOKEN: ${{ github.token }} + run: | + # Resolve version: use ARCHGATE_VERSION if set, otherwise query GitHub + if (-not $env:ARCHGATE_VERSION) { + $release = gh release view --json tagName --jq .tagName 2>$null + if ($LASTEXITCODE -ne 0 -or -not $release) { + Write-Host "::warning::No releases found, skipping install.ps1 smoke test" + exit 0 + } + $env:ARCHGATE_VERSION = $release + } + Write-Host "Testing install.ps1 with version $env:ARCHGATE_VERSION" + + $installDir = Join-Path $env:TEMP "archgate-smoke-install-$(Get-Random)" + $env:ARCHGATE_INSTALL_DIR = $installDir + + # Run installer non-interactively (Read-Host returns empty → defaults to adding PATH) + & "$env:GITHUB_WORKSPACE\install.ps1" + if ($LASTEXITCODE -ne 0) { + Write-Error "install.ps1 exited with code $LASTEXITCODE" + exit 1 + } + + # Verify binary was installed + $exe = Join-Path $installDir "archgate.exe" + if (-not (Test-Path $exe)) { + Write-Error "archgate.exe not found at $exe after install" + exit 1 + } + + $output = & $exe --version 2>&1 + Write-Host "Installed archgate version: $output" + if ($LASTEXITCODE -ne 0) { + Write-Error "Installed binary exited with code $LASTEXITCODE" + exit 1 + } + + # Cleanup + Remove-Item -Path $installDir -Recurse -Force -ErrorAction SilentlyContinue + + smoke-linux: + name: Smoke Test (Linux) + runs-on: ubuntu-latest + timeout-minutes: 10 + if: github.event_name != 'pull_request' || github.event.pull_request.draft == false + steps: + - name: Checkout code + uses: actions/checkout@v6 + with: + fetch-depth: 0 + + - uses: moonrepo/setup-toolchain@v0 + with: + auto-install: true + + - name: Install dependencies + run: bun install --frozen-lockfile + + - name: Build Linux binary + run: bun build src/cli.ts --compile --bytecode --outfile dist/archgate-smoke-test + + - name: Smoke test binary + run: | + chmod +x dist/archgate-smoke-test + output=$(dist/archgate-smoke-test --version 2>&1) + echo "archgate version: $output" + + - name: Smoke test binary from ~/.archgate/bin/ + run: | + mkdir -p ~/.archgate/bin + cp dist/archgate-smoke-test ~/.archgate/bin/archgate + chmod +x ~/.archgate/bin/archgate + output=$(~/.archgate/bin/archgate --version 2>&1) + echo "archgate version from binary install dir: $output" + rm -rf ~/.archgate/bin + + - name: Smoke test binary from proto dir + run: | + mkdir -p ~/.proto/tools/archgate/0.0.0 + cp dist/archgate-smoke-test ~/.proto/tools/archgate/0.0.0/archgate + chmod +x ~/.proto/tools/archgate/0.0.0/archgate + output=$(~/.proto/tools/archgate/0.0.0/archgate --version 2>&1) + echo "archgate version from proto dir: $output" + rm -rf ~/.proto/tools/archgate + + - name: Smoke test binary from node_modules + run: | + project_dir=$(mktemp -d) + mkdir -p "$project_dir/node_modules/.bin" + echo '{}' > "$project_dir/package.json" + touch "$project_dir/bun.lock" + cp dist/archgate-smoke-test "$project_dir/node_modules/.bin/archgate" + chmod +x "$project_dir/node_modules/.bin/archgate" + output=$("$project_dir/node_modules/.bin/archgate" --version 2>&1) + echo "archgate version from node_modules: $output" + rm -rf "$project_dir" + + - name: Smoke test install.sh + env: + ARCHGATE_VERSION: ${{ vars.LATEST_RELEASE_TAG || '' }} + GH_TOKEN: ${{ github.token }} + run: | + # Resolve version: use ARCHGATE_VERSION if set, otherwise query GitHub + if [ -z "$ARCHGATE_VERSION" ]; then + ARCHGATE_VERSION="$(gh release view --json tagName --jq .tagName 2>/dev/null || true)" + if [ -z "$ARCHGATE_VERSION" ]; then + echo "::warning::No releases found, skipping install.sh smoke test" + exit 0 + fi + export ARCHGATE_VERSION + fi + echo "Testing install.sh with version $ARCHGATE_VERSION" + + export ARCHGATE_INSTALL_DIR="$(mktemp -d)" + + # Run installer (no TTY in CI → skips PATH prompt automatically) + sh install.sh + + # Verify binary was installed + if [ ! -f "$ARCHGATE_INSTALL_DIR/archgate" ]; then + echo "::error::archgate binary not found at $ARCHGATE_INSTALL_DIR/archgate after install" + exit 1 + fi + + output="$("$ARCHGATE_INSTALL_DIR/archgate" --version 2>&1)" + echo "Installed archgate version: $output" + + # Cleanup + rm -rf "$ARCHGATE_INSTALL_DIR" + + # Gate job — this is the single required status check for branch protection. + # It passes only when ALL jobs above succeed. + status: + name: Validate Code + runs-on: ubuntu-latest + if: always() + needs: [validate, smoke-windows, smoke-linux] + steps: + - name: Check job results + run: | + if [[ "${{ needs.validate.result }}" != "success" ]] || \ + [[ "${{ needs.smoke-windows.result }}" != "success" ]] || \ + [[ "${{ needs.smoke-linux.result }}" != "success" ]]; then + echo "::error::One or more jobs failed:" + echo " validate: ${{ needs.validate.result }}" + echo " smoke-windows: ${{ needs.smoke-windows.result }}" + echo " smoke-linux: ${{ needs.smoke-linux.result }}" + exit 1 + fi + echo "All checks passed." diff --git a/.github/workflows/deploy-docs.yml b/.github/workflows/deploy-docs.yml deleted file mode 100644 index 05e44401..00000000 --- a/.github/workflows/deploy-docs.yml +++ /dev/null @@ -1,58 +0,0 @@ -name: Deploy Docs - -on: - push: - branches: - - main - paths: - - "docs/**" - workflow_dispatch: - -permissions: - contents: read - pages: write - id-token: write - -concurrency: - group: deploy-docs - cancel-in-progress: true - -jobs: - build: - name: Build Docs - runs-on: ubuntu-latest - timeout-minutes: 10 - steps: - - name: Checkout code - uses: actions/checkout@v6 - - - name: Setup toolchain - uses: moonrepo/setup-toolchain@v0 - with: - auto-install: true - - - name: Install dependencies - run: bun install --frozen-lockfile - working-directory: docs - - - name: Build docs - run: bunx --bun astro build - working-directory: docs - - - name: Upload Pages artifact - uses: actions/upload-pages-artifact@v4 - with: - path: docs/dist - - deploy: - name: Deploy to GitHub Pages - needs: build - runs-on: ubuntu-latest - timeout-minutes: 5 - environment: - name: github-pages - url: ${{ steps.deployment.outputs.page_url }} - steps: - - name: Deploy to GitHub Pages - id: deployment - uses: actions/deploy-pages@v4 diff --git a/.github/workflows/smoke-test.yml b/.github/workflows/smoke-test.yml deleted file mode 100644 index cee37354..00000000 --- a/.github/workflows/smoke-test.yml +++ /dev/null @@ -1,245 +0,0 @@ -name: Smoke Test - -on: - pull_request: - types: [opened, synchronize, reopened] - branches: - - main - -permissions: - contents: read - -concurrency: - group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} - cancel-in-progress: true - -jobs: - windows: - name: Windows Smoke Test - runs-on: windows-latest - timeout-minutes: 15 - if: github.event.pull_request.draft == false - steps: - - name: Checkout code - uses: actions/checkout@v6 - with: - fetch-depth: 0 - - - uses: moonrepo/setup-toolchain@v0 - with: - auto-install: true - - - name: Install dependencies - run: bun install --frozen-lockfile - - - name: Lint - run: bun run lint - - - name: Typecheck - run: bun run typecheck - - - name: Format check - run: bun run format:check - - - name: Tests - run: bun test --timeout 60000 - - - name: Build Windows binary - run: bun build src/cli.ts --compile --bytecode --outfile dist/archgate-smoke-test - - - name: Smoke test binary - shell: pwsh - run: | - $binary = "dist/archgate-smoke-test.exe" - if (-not (Test-Path $binary)) { - Write-Error "Binary not found at $binary" - exit 1 - } - $output = & $binary --version 2>&1 - Write-Host "archgate version: $output" - if ($LASTEXITCODE -ne 0) { - Write-Error "Binary exited with code $LASTEXITCODE" - exit 1 - } - - - name: Smoke test binary from install dir - shell: pwsh - run: | - # Simulate binary install at %APPDATA%\archgate\ - $installDir = Join-Path $env:APPDATA "archgate" - New-Item -Path $installDir -ItemType Directory -Force | Out-Null - Copy-Item "dist/archgate-smoke-test.exe" (Join-Path $installDir "archgate.exe") - $output = & (Join-Path $installDir "archgate.exe") --version 2>&1 - Write-Host "archgate version from binary install dir: $output" - if ($LASTEXITCODE -ne 0) { - Write-Error "Binary exited with code $LASTEXITCODE" - exit 1 - } - Remove-Item -Path $installDir -Recurse -Force -ErrorAction SilentlyContinue - - - name: Smoke test binary from proto dir - shell: pwsh - run: | - # Simulate proto install at ~/.proto/tools/archgate// - $protoDir = Join-Path $env:USERPROFILE ".proto" "tools" "archgate" "0.0.0" - New-Item -Path $protoDir -ItemType Directory -Force | Out-Null - Copy-Item "dist/archgate-smoke-test.exe" (Join-Path $protoDir "archgate.exe") - $output = & (Join-Path $protoDir "archgate.exe") --version 2>&1 - Write-Host "archgate version from proto dir: $output" - if ($LASTEXITCODE -ne 0) { - Write-Error "Binary exited with code $LASTEXITCODE" - exit 1 - } - Remove-Item -Path (Join-Path $env:USERPROFILE ".proto") -Recurse -Force -ErrorAction SilentlyContinue - - - name: Smoke test binary from node_modules - shell: pwsh - run: | - # Simulate local dev dependency install - $projectDir = Join-Path $env:TEMP "archgate-local-smoke" - $binDir = Join-Path $projectDir "node_modules" ".bin" - New-Item -Path $binDir -ItemType Directory -Force | Out-Null - Set-Content -Path (Join-Path $projectDir "package.json") -Value "{}" - Set-Content -Path (Join-Path $projectDir "bun.lock") -Value "" - Copy-Item "dist/archgate-smoke-test.exe" (Join-Path $binDir "archgate.exe") - $output = & (Join-Path $binDir "archgate.exe") --version 2>&1 - Write-Host "archgate version from node_modules: $output" - if ($LASTEXITCODE -ne 0) { - Write-Error "Binary exited with code $LASTEXITCODE" - exit 1 - } - Remove-Item -Path $projectDir -Recurse -Force -ErrorAction SilentlyContinue - - - name: Smoke test install.ps1 - shell: pwsh - env: - ARCHGATE_VERSION: ${{ vars.LATEST_RELEASE_TAG || '' }} - GH_TOKEN: ${{ github.token }} - run: | - # Resolve version: use ARCHGATE_VERSION if set, otherwise query GitHub - if (-not $env:ARCHGATE_VERSION) { - $release = gh release view --json tagName --jq .tagName 2>$null - if ($LASTEXITCODE -ne 0 -or -not $release) { - Write-Host "::warning::No releases found, skipping install.ps1 smoke test" - exit 0 - } - $env:ARCHGATE_VERSION = $release - } - Write-Host "Testing install.ps1 with version $env:ARCHGATE_VERSION" - - $installDir = Join-Path $env:TEMP "archgate-smoke-install-$(Get-Random)" - $env:ARCHGATE_INSTALL_DIR = $installDir - - # Run installer non-interactively (Read-Host returns empty → defaults to adding PATH) - & "$env:GITHUB_WORKSPACE\install.ps1" - if ($LASTEXITCODE -ne 0) { - Write-Error "install.ps1 exited with code $LASTEXITCODE" - exit 1 - } - - # Verify binary was installed - $exe = Join-Path $installDir "archgate.exe" - if (-not (Test-Path $exe)) { - Write-Error "archgate.exe not found at $exe after install" - exit 1 - } - - $output = & $exe --version 2>&1 - Write-Host "Installed archgate version: $output" - if ($LASTEXITCODE -ne 0) { - Write-Error "Installed binary exited with code $LASTEXITCODE" - exit 1 - } - - # Cleanup - Remove-Item -Path $installDir -Recurse -Force -ErrorAction SilentlyContinue - - linux: - name: Linux Smoke Test - runs-on: ubuntu-latest - timeout-minutes: 10 - if: github.event.pull_request.draft == false - steps: - - name: Checkout code - uses: actions/checkout@v6 - with: - fetch-depth: 0 - - - uses: moonrepo/setup-toolchain@v0 - with: - auto-install: true - - - name: Install dependencies - run: bun install --frozen-lockfile - - - name: Build Linux binary - run: bun build src/cli.ts --compile --bytecode --outfile dist/archgate-smoke-test - - - name: Smoke test binary - run: | - chmod +x dist/archgate-smoke-test - output=$(dist/archgate-smoke-test --version 2>&1) - echo "archgate version: $output" - - - name: Smoke test binary from ~/.archgate/bin/ - run: | - mkdir -p ~/.archgate/bin - cp dist/archgate-smoke-test ~/.archgate/bin/archgate - chmod +x ~/.archgate/bin/archgate - output=$(~/.archgate/bin/archgate --version 2>&1) - echo "archgate version from binary install dir: $output" - rm -rf ~/.archgate/bin - - - name: Smoke test binary from proto dir - run: | - mkdir -p ~/.proto/tools/archgate/0.0.0 - cp dist/archgate-smoke-test ~/.proto/tools/archgate/0.0.0/archgate - chmod +x ~/.proto/tools/archgate/0.0.0/archgate - output=$(~/.proto/tools/archgate/0.0.0/archgate --version 2>&1) - echo "archgate version from proto dir: $output" - rm -rf ~/.proto/tools/archgate - - - name: Smoke test binary from node_modules - run: | - project_dir=$(mktemp -d) - mkdir -p "$project_dir/node_modules/.bin" - echo '{}' > "$project_dir/package.json" - touch "$project_dir/bun.lock" - cp dist/archgate-smoke-test "$project_dir/node_modules/.bin/archgate" - chmod +x "$project_dir/node_modules/.bin/archgate" - output=$("$project_dir/node_modules/.bin/archgate" --version 2>&1) - echo "archgate version from node_modules: $output" - rm -rf "$project_dir" - - - name: Smoke test install.sh - env: - ARCHGATE_VERSION: ${{ vars.LATEST_RELEASE_TAG || '' }} - GH_TOKEN: ${{ github.token }} - run: | - # Resolve version: use ARCHGATE_VERSION if set, otherwise query GitHub - if [ -z "$ARCHGATE_VERSION" ]; then - ARCHGATE_VERSION="$(gh release view --json tagName --jq .tagName 2>/dev/null || true)" - if [ -z "$ARCHGATE_VERSION" ]; then - echo "::warning::No releases found, skipping install.sh smoke test" - exit 0 - fi - export ARCHGATE_VERSION - fi - echo "Testing install.sh with version $ARCHGATE_VERSION" - - export ARCHGATE_INSTALL_DIR="$(mktemp -d)" - - # Run installer (no TTY in CI → skips PATH prompt automatically) - sh install.sh - - # Verify binary was installed - if [ ! -f "$ARCHGATE_INSTALL_DIR/archgate" ]; then - echo "::error::archgate binary not found at $ARCHGATE_INSTALL_DIR/archgate after install" - exit 1 - fi - - output="$("$ARCHGATE_INSTALL_DIR/archgate" --version 2>&1)" - echo "Installed archgate version: $output" - - # Cleanup - rm -rf "$ARCHGATE_INSTALL_DIR" From ff68b16b4028694f47ea6f5021f166ae0c4e5dc1 Mon Sep 17 00:00:00 2001 From: Rhuan Barreto Date: Wed, 25 Mar 2026 03:24:48 +0100 Subject: [PATCH 2/2] ci: split smoke tests into reusable workflows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Extract Windows and Linux smoke tests into separate workflow files called via workflow_call. The orchestrator (code-pull-request.yml) stays lean — validate job + two smoke test calls + gate job. --- .github/workflows/code-pull-request.yml | 227 +---------------------- .github/workflows/smoke-test-linux.yml | 93 ++++++++++ .github/workflows/smoke-test-windows.yml | 140 ++++++++++++++ 3 files changed, 236 insertions(+), 224 deletions(-) create mode 100644 .github/workflows/smoke-test-linux.yml create mode 100644 .github/workflows/smoke-test-windows.yml diff --git a/.github/workflows/code-pull-request.yml b/.github/workflows/code-pull-request.yml index 582958f6..68ebcaa8 100644 --- a/.github/workflows/code-pull-request.yml +++ b/.github/workflows/code-pull-request.yml @@ -63,236 +63,15 @@ jobs: smoke-windows: name: Smoke Test (Windows) - runs-on: windows-latest - timeout-minutes: 15 if: github.event_name != 'pull_request' || github.event.pull_request.draft == false - steps: - - name: Checkout code - uses: actions/checkout@v6 - with: - fetch-depth: 0 - - - uses: moonrepo/setup-toolchain@v0 - with: - auto-install: true - - - name: Install dependencies - run: bun install --frozen-lockfile - - - name: Lint - run: bun run lint - - - name: Typecheck - run: bun run typecheck - - - name: Format check - run: bun run format:check - - - name: Tests - run: bun test --timeout 60000 - - - name: Build Windows binary - run: bun build src/cli.ts --compile --bytecode --outfile dist/archgate-smoke-test - - - name: Smoke test binary - shell: pwsh - run: | - $binary = "dist/archgate-smoke-test.exe" - if (-not (Test-Path $binary)) { - Write-Error "Binary not found at $binary" - exit 1 - } - $output = & $binary --version 2>&1 - Write-Host "archgate version: $output" - if ($LASTEXITCODE -ne 0) { - Write-Error "Binary exited with code $LASTEXITCODE" - exit 1 - } - - - name: Smoke test binary from install dir - shell: pwsh - run: | - # Simulate binary install at %APPDATA%\archgate\ - $installDir = Join-Path $env:APPDATA "archgate" - New-Item -Path $installDir -ItemType Directory -Force | Out-Null - Copy-Item "dist/archgate-smoke-test.exe" (Join-Path $installDir "archgate.exe") - $output = & (Join-Path $installDir "archgate.exe") --version 2>&1 - Write-Host "archgate version from binary install dir: $output" - if ($LASTEXITCODE -ne 0) { - Write-Error "Binary exited with code $LASTEXITCODE" - exit 1 - } - Remove-Item -Path $installDir -Recurse -Force -ErrorAction SilentlyContinue - - - name: Smoke test binary from proto dir - shell: pwsh - run: | - # Simulate proto install at ~/.proto/tools/archgate// - $protoDir = Join-Path $env:USERPROFILE ".proto" "tools" "archgate" "0.0.0" - New-Item -Path $protoDir -ItemType Directory -Force | Out-Null - Copy-Item "dist/archgate-smoke-test.exe" (Join-Path $protoDir "archgate.exe") - $output = & (Join-Path $protoDir "archgate.exe") --version 2>&1 - Write-Host "archgate version from proto dir: $output" - if ($LASTEXITCODE -ne 0) { - Write-Error "Binary exited with code $LASTEXITCODE" - exit 1 - } - Remove-Item -Path (Join-Path $env:USERPROFILE ".proto") -Recurse -Force -ErrorAction SilentlyContinue - - - name: Smoke test binary from node_modules - shell: pwsh - run: | - # Simulate local dev dependency install - $projectDir = Join-Path $env:TEMP "archgate-local-smoke" - $binDir = Join-Path $projectDir "node_modules" ".bin" - New-Item -Path $binDir -ItemType Directory -Force | Out-Null - Set-Content -Path (Join-Path $projectDir "package.json") -Value "{}" - Set-Content -Path (Join-Path $projectDir "bun.lock") -Value "" - Copy-Item "dist/archgate-smoke-test.exe" (Join-Path $binDir "archgate.exe") - $output = & (Join-Path $binDir "archgate.exe") --version 2>&1 - Write-Host "archgate version from node_modules: $output" - if ($LASTEXITCODE -ne 0) { - Write-Error "Binary exited with code $LASTEXITCODE" - exit 1 - } - Remove-Item -Path $projectDir -Recurse -Force -ErrorAction SilentlyContinue - - - name: Smoke test install.ps1 - shell: pwsh - env: - ARCHGATE_VERSION: ${{ vars.LATEST_RELEASE_TAG || '' }} - GH_TOKEN: ${{ github.token }} - run: | - # Resolve version: use ARCHGATE_VERSION if set, otherwise query GitHub - if (-not $env:ARCHGATE_VERSION) { - $release = gh release view --json tagName --jq .tagName 2>$null - if ($LASTEXITCODE -ne 0 -or -not $release) { - Write-Host "::warning::No releases found, skipping install.ps1 smoke test" - exit 0 - } - $env:ARCHGATE_VERSION = $release - } - Write-Host "Testing install.ps1 with version $env:ARCHGATE_VERSION" - - $installDir = Join-Path $env:TEMP "archgate-smoke-install-$(Get-Random)" - $env:ARCHGATE_INSTALL_DIR = $installDir - - # Run installer non-interactively (Read-Host returns empty → defaults to adding PATH) - & "$env:GITHUB_WORKSPACE\install.ps1" - if ($LASTEXITCODE -ne 0) { - Write-Error "install.ps1 exited with code $LASTEXITCODE" - exit 1 - } - - # Verify binary was installed - $exe = Join-Path $installDir "archgate.exe" - if (-not (Test-Path $exe)) { - Write-Error "archgate.exe not found at $exe after install" - exit 1 - } - - $output = & $exe --version 2>&1 - Write-Host "Installed archgate version: $output" - if ($LASTEXITCODE -ne 0) { - Write-Error "Installed binary exited with code $LASTEXITCODE" - exit 1 - } - - # Cleanup - Remove-Item -Path $installDir -Recurse -Force -ErrorAction SilentlyContinue + uses: ./.github/workflows/smoke-test-windows.yml smoke-linux: name: Smoke Test (Linux) - runs-on: ubuntu-latest - timeout-minutes: 10 if: github.event_name != 'pull_request' || github.event.pull_request.draft == false - steps: - - name: Checkout code - uses: actions/checkout@v6 - with: - fetch-depth: 0 - - - uses: moonrepo/setup-toolchain@v0 - with: - auto-install: true - - - name: Install dependencies - run: bun install --frozen-lockfile - - - name: Build Linux binary - run: bun build src/cli.ts --compile --bytecode --outfile dist/archgate-smoke-test - - - name: Smoke test binary - run: | - chmod +x dist/archgate-smoke-test - output=$(dist/archgate-smoke-test --version 2>&1) - echo "archgate version: $output" - - - name: Smoke test binary from ~/.archgate/bin/ - run: | - mkdir -p ~/.archgate/bin - cp dist/archgate-smoke-test ~/.archgate/bin/archgate - chmod +x ~/.archgate/bin/archgate - output=$(~/.archgate/bin/archgate --version 2>&1) - echo "archgate version from binary install dir: $output" - rm -rf ~/.archgate/bin - - - name: Smoke test binary from proto dir - run: | - mkdir -p ~/.proto/tools/archgate/0.0.0 - cp dist/archgate-smoke-test ~/.proto/tools/archgate/0.0.0/archgate - chmod +x ~/.proto/tools/archgate/0.0.0/archgate - output=$(~/.proto/tools/archgate/0.0.0/archgate --version 2>&1) - echo "archgate version from proto dir: $output" - rm -rf ~/.proto/tools/archgate - - - name: Smoke test binary from node_modules - run: | - project_dir=$(mktemp -d) - mkdir -p "$project_dir/node_modules/.bin" - echo '{}' > "$project_dir/package.json" - touch "$project_dir/bun.lock" - cp dist/archgate-smoke-test "$project_dir/node_modules/.bin/archgate" - chmod +x "$project_dir/node_modules/.bin/archgate" - output=$("$project_dir/node_modules/.bin/archgate" --version 2>&1) - echo "archgate version from node_modules: $output" - rm -rf "$project_dir" - - - name: Smoke test install.sh - env: - ARCHGATE_VERSION: ${{ vars.LATEST_RELEASE_TAG || '' }} - GH_TOKEN: ${{ github.token }} - run: | - # Resolve version: use ARCHGATE_VERSION if set, otherwise query GitHub - if [ -z "$ARCHGATE_VERSION" ]; then - ARCHGATE_VERSION="$(gh release view --json tagName --jq .tagName 2>/dev/null || true)" - if [ -z "$ARCHGATE_VERSION" ]; then - echo "::warning::No releases found, skipping install.sh smoke test" - exit 0 - fi - export ARCHGATE_VERSION - fi - echo "Testing install.sh with version $ARCHGATE_VERSION" - - export ARCHGATE_INSTALL_DIR="$(mktemp -d)" - - # Run installer (no TTY in CI → skips PATH prompt automatically) - sh install.sh - - # Verify binary was installed - if [ ! -f "$ARCHGATE_INSTALL_DIR/archgate" ]; then - echo "::error::archgate binary not found at $ARCHGATE_INSTALL_DIR/archgate after install" - exit 1 - fi - - output="$("$ARCHGATE_INSTALL_DIR/archgate" --version 2>&1)" - echo "Installed archgate version: $output" - - # Cleanup - rm -rf "$ARCHGATE_INSTALL_DIR" + uses: ./.github/workflows/smoke-test-linux.yml - # Gate job — this is the single required status check for branch protection. - # It passes only when ALL jobs above succeed. + # Gate job — single required status check for branch protection. status: name: Validate Code runs-on: ubuntu-latest diff --git a/.github/workflows/smoke-test-linux.yml b/.github/workflows/smoke-test-linux.yml new file mode 100644 index 00000000..6b567933 --- /dev/null +++ b/.github/workflows/smoke-test-linux.yml @@ -0,0 +1,93 @@ +name: Smoke Test (Linux) + +on: + workflow_call: + +permissions: + contents: read + +jobs: + linux: + name: Linux + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - name: Checkout code + uses: actions/checkout@v6 + with: + fetch-depth: 0 + + - uses: moonrepo/setup-toolchain@v0 + with: + auto-install: true + + - name: Install dependencies + run: bun install --frozen-lockfile + + - name: Build Linux binary + run: bun build src/cli.ts --compile --bytecode --outfile dist/archgate-smoke-test + + - name: Smoke test binary + run: | + chmod +x dist/archgate-smoke-test + output=$(dist/archgate-smoke-test --version 2>&1) + echo "archgate version: $output" + + - name: Smoke test binary from ~/.archgate/bin/ + run: | + mkdir -p ~/.archgate/bin + cp dist/archgate-smoke-test ~/.archgate/bin/archgate + chmod +x ~/.archgate/bin/archgate + output=$(~/.archgate/bin/archgate --version 2>&1) + echo "archgate version from binary install dir: $output" + rm -rf ~/.archgate/bin + + - name: Smoke test binary from proto dir + run: | + mkdir -p ~/.proto/tools/archgate/0.0.0 + cp dist/archgate-smoke-test ~/.proto/tools/archgate/0.0.0/archgate + chmod +x ~/.proto/tools/archgate/0.0.0/archgate + output=$(~/.proto/tools/archgate/0.0.0/archgate --version 2>&1) + echo "archgate version from proto dir: $output" + rm -rf ~/.proto/tools/archgate + + - name: Smoke test binary from node_modules + run: | + project_dir=$(mktemp -d) + mkdir -p "$project_dir/node_modules/.bin" + echo '{}' > "$project_dir/package.json" + touch "$project_dir/bun.lock" + cp dist/archgate-smoke-test "$project_dir/node_modules/.bin/archgate" + chmod +x "$project_dir/node_modules/.bin/archgate" + output=$("$project_dir/node_modules/.bin/archgate" --version 2>&1) + echo "archgate version from node_modules: $output" + rm -rf "$project_dir" + + - name: Smoke test install.sh + env: + ARCHGATE_VERSION: ${{ vars.LATEST_RELEASE_TAG || '' }} + GH_TOKEN: ${{ github.token }} + run: | + if [ -z "$ARCHGATE_VERSION" ]; then + ARCHGATE_VERSION="$(gh release view --json tagName --jq .tagName 2>/dev/null || true)" + if [ -z "$ARCHGATE_VERSION" ]; then + echo "::warning::No releases found, skipping install.sh smoke test" + exit 0 + fi + export ARCHGATE_VERSION + fi + echo "Testing install.sh with version $ARCHGATE_VERSION" + + export ARCHGATE_INSTALL_DIR="$(mktemp -d)" + + sh install.sh + + if [ ! -f "$ARCHGATE_INSTALL_DIR/archgate" ]; then + echo "::error::archgate binary not found at $ARCHGATE_INSTALL_DIR/archgate after install" + exit 1 + fi + + output="$("$ARCHGATE_INSTALL_DIR/archgate" --version 2>&1)" + echo "Installed archgate version: $output" + + rm -rf "$ARCHGATE_INSTALL_DIR" diff --git a/.github/workflows/smoke-test-windows.yml b/.github/workflows/smoke-test-windows.yml new file mode 100644 index 00000000..1c2c50a9 --- /dev/null +++ b/.github/workflows/smoke-test-windows.yml @@ -0,0 +1,140 @@ +name: Smoke Test (Windows) + +on: + workflow_call: + +permissions: + contents: read + +jobs: + windows: + name: Windows + runs-on: windows-latest + timeout-minutes: 15 + steps: + - name: Checkout code + uses: actions/checkout@v6 + with: + fetch-depth: 0 + + - uses: moonrepo/setup-toolchain@v0 + with: + auto-install: true + + - name: Install dependencies + run: bun install --frozen-lockfile + + - name: Lint + run: bun run lint + + - name: Typecheck + run: bun run typecheck + + - name: Format check + run: bun run format:check + + - name: Tests + run: bun test --timeout 60000 + + - name: Build Windows binary + run: bun build src/cli.ts --compile --bytecode --outfile dist/archgate-smoke-test + + - name: Smoke test binary + shell: pwsh + run: | + $binary = "dist/archgate-smoke-test.exe" + if (-not (Test-Path $binary)) { + Write-Error "Binary not found at $binary" + exit 1 + } + $output = & $binary --version 2>&1 + Write-Host "archgate version: $output" + if ($LASTEXITCODE -ne 0) { + Write-Error "Binary exited with code $LASTEXITCODE" + exit 1 + } + + - name: Smoke test binary from install dir + shell: pwsh + run: | + $installDir = Join-Path $env:APPDATA "archgate" + New-Item -Path $installDir -ItemType Directory -Force | Out-Null + Copy-Item "dist/archgate-smoke-test.exe" (Join-Path $installDir "archgate.exe") + $output = & (Join-Path $installDir "archgate.exe") --version 2>&1 + Write-Host "archgate version from binary install dir: $output" + if ($LASTEXITCODE -ne 0) { + Write-Error "Binary exited with code $LASTEXITCODE" + exit 1 + } + Remove-Item -Path $installDir -Recurse -Force -ErrorAction SilentlyContinue + + - name: Smoke test binary from proto dir + shell: pwsh + run: | + $protoDir = Join-Path $env:USERPROFILE ".proto" "tools" "archgate" "0.0.0" + New-Item -Path $protoDir -ItemType Directory -Force | Out-Null + Copy-Item "dist/archgate-smoke-test.exe" (Join-Path $protoDir "archgate.exe") + $output = & (Join-Path $protoDir "archgate.exe") --version 2>&1 + Write-Host "archgate version from proto dir: $output" + if ($LASTEXITCODE -ne 0) { + Write-Error "Binary exited with code $LASTEXITCODE" + exit 1 + } + Remove-Item -Path (Join-Path $env:USERPROFILE ".proto") -Recurse -Force -ErrorAction SilentlyContinue + + - name: Smoke test binary from node_modules + shell: pwsh + run: | + $projectDir = Join-Path $env:TEMP "archgate-local-smoke" + $binDir = Join-Path $projectDir "node_modules" ".bin" + New-Item -Path $binDir -ItemType Directory -Force | Out-Null + Set-Content -Path (Join-Path $projectDir "package.json") -Value "{}" + Set-Content -Path (Join-Path $projectDir "bun.lock") -Value "" + Copy-Item "dist/archgate-smoke-test.exe" (Join-Path $binDir "archgate.exe") + $output = & (Join-Path $binDir "archgate.exe") --version 2>&1 + Write-Host "archgate version from node_modules: $output" + if ($LASTEXITCODE -ne 0) { + Write-Error "Binary exited with code $LASTEXITCODE" + exit 1 + } + Remove-Item -Path $projectDir -Recurse -Force -ErrorAction SilentlyContinue + + - name: Smoke test install.ps1 + shell: pwsh + env: + ARCHGATE_VERSION: ${{ vars.LATEST_RELEASE_TAG || '' }} + GH_TOKEN: ${{ github.token }} + run: | + if (-not $env:ARCHGATE_VERSION) { + $release = gh release view --json tagName --jq .tagName 2>$null + if ($LASTEXITCODE -ne 0 -or -not $release) { + Write-Host "::warning::No releases found, skipping install.ps1 smoke test" + exit 0 + } + $env:ARCHGATE_VERSION = $release + } + Write-Host "Testing install.ps1 with version $env:ARCHGATE_VERSION" + + $installDir = Join-Path $env:TEMP "archgate-smoke-install-$(Get-Random)" + $env:ARCHGATE_INSTALL_DIR = $installDir + + & "$env:GITHUB_WORKSPACE\install.ps1" + if ($LASTEXITCODE -ne 0) { + Write-Error "install.ps1 exited with code $LASTEXITCODE" + exit 1 + } + + $exe = Join-Path $installDir "archgate.exe" + if (-not (Test-Path $exe)) { + Write-Error "archgate.exe not found at $exe after install" + exit 1 + } + + $output = & $exe --version 2>&1 + Write-Host "Installed archgate version: $output" + if ($LASTEXITCODE -ne 0) { + Write-Error "Installed binary exited with code $LASTEXITCODE" + exit 1 + } + + Remove-Item -Path $installDir -Recurse -Force -ErrorAction SilentlyContinue