Release #255
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: Release | |
| 'on': | |
| workflow_dispatch: | |
| inputs: | |
| version: | |
| description: 'Explicit CalVer (e.g. 2026.05.13-2). Empty = auto-compute today.' | |
| required: false | |
| type: string | |
| default: '' | |
| dry_run: | |
| description: 'Dry-run preview only (no publish or push)' | |
| required: false | |
| type: boolean | |
| default: false | |
| publish-only: | |
| description: 'Publish an already prepared version through GitHub OIDC; requires version.' | |
| required: false | |
| type: boolean | |
| default: false | |
| permissions: | |
| contents: read | |
| id-token: write | |
| concurrency: | |
| group: release | |
| cancel-in-progress: false | |
| jobs: | |
| release: | |
| runs-on: ubuntu-latest | |
| # `--ref main` resolves at run start, so the release can always check out a commit | |
| # whose CI has not finished yet; the test gate then runs the full suite in-job. | |
| # Measured full-gate releases land at 22-26 min, so a 30 min cap has under 5 min | |
| # of headroom and kills the job mid-suite (run 33605173502). Budget for the slow | |
| # path plus growth; gate-reused releases still finish in ~4 min. | |
| timeout-minutes: 50 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| fetch-depth: 0 | |
| persist-credentials: false | |
| - name: Configure git identity | |
| run: | | |
| git config user.name "senpi-release-bot" | |
| git config user.email "actions@github.com" | |
| - name: Setup Node.js | |
| uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 | |
| with: | |
| node-version: '24' | |
| registry-url: 'https://registry.npmjs.org/' | |
| package-manager-cache: false | |
| - name: Setup Bun | |
| uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0 | |
| with: | |
| bun-version: '1.4.0' | |
| - name: Assert bun 1.4 toolchain | |
| run: bash scripts/assert-bun-toolchain.sh | |
| - name: Install dependencies | |
| run: npm install --ignore-scripts --no-audit --no-fund | |
| # coding-agent tool tests resolve rg/fd via system binaries first and only | |
| # download from GitHub releases as a fallback. Unauthenticated downloads | |
| # are rate-limited on shared runner egress IPs, which flakes the release | |
| # gate; provisioning the binaries here keeps the fallback unused. | |
| - name: Provision ripgrep and fd | |
| run: sudo apt-get update && sudo apt-get install -y ripgrep fd-find | |
| - name: Build all workspaces (so husky pre-commit type check resolves) | |
| run: npm run build | |
| - name: Reset auto-generated and npm-install drift files (not part of release diff) | |
| run: git checkout -- packages/ai/src/models.generated.ts packages/ai/src/image-models.generated.ts package-lock.json | |
| - name: Run release | |
| if: inputs.publish-only != true | |
| env: | |
| GH_TOKEN: ${{ secrets.UPSTREAM_AUTOMATION_TOKEN }} | |
| SENPI_SKIP_PM_VERIFY: '1' | |
| run: | | |
| test -n "$GH_TOKEN" || { | |
| echo "::error::UPSTREAM_AUTOMATION_TOKEN is required to push release commits and tags through branch protection." | |
| exit 1 | |
| } | |
| git remote set-url origin "https://x-access-token:${GH_TOKEN}@github.com/${GITHUB_REPOSITORY}.git" | |
| ARGS=() | |
| if [ -n "${{ inputs.version }}" ]; then | |
| ARGS+=(--version "${{ inputs.version }}") | |
| fi | |
| if [ "${{ inputs.dry_run }}" = "true" ]; then | |
| ARGS+=(--dry-run) | |
| fi | |
| npm run release -- "${ARGS[@]}" | |
| - name: Publish prepared version | |
| if: inputs.publish-only == true | |
| env: | |
| EXPECTED_VERSION: ${{ inputs.version }} | |
| DRY_RUN: ${{ inputs.dry_run }} | |
| run: | | |
| test -n "$EXPECTED_VERSION" || { | |
| echo "publish-only requires an explicit version" >&2 | |
| exit 1 | |
| } | |
| ACTUAL_VERSION="$(node -p 'require("./packages/coding-agent/package.json").version')" | |
| test "$ACTUAL_VERSION" = "$EXPECTED_VERSION" || { | |
| echo "expected $EXPECTED_VERSION, found $ACTUAL_VERSION" >&2 | |
| exit 1 | |
| } | |
| PUBLISH_ARGS=() | |
| if [ "$DRY_RUN" = "true" ]; then | |
| PUBLISH_ARGS+=(--dry-run) | |
| fi | |
| node scripts/publish.mjs "${PUBLISH_ARGS[@]}" | |
| - name: Workflow summary | |
| if: always() | |
| shell: bash | |
| run: | | |
| { | |
| echo "## Release" | |
| echo | |
| echo "| Field | Value |" | |
| echo "| --- | --- |" | |
| echo "| Job status | ${{ job.status }} |" | |
| echo "| Mode | ${{ inputs.publish-only && 'publish-only' || 'release' }} |" | |
| echo "| Dry run | ${{ inputs.dry_run }} |" | |
| echo "| Version | ${{ inputs.version || 'auto' }} |" | |
| echo "| Commit | ${{ github.sha }} |" | |
| } >> "$GITHUB_STEP_SUMMARY" |