name: Release on: push: branches: [main] workflow_dispatch: jobs: release: if: ${{ github.ref == 'refs/heads/main' }} runs-on: [self-hosted, linux, x64] permissions: contents: write issues: write pull-requests: write id-token: write steps: - name: Checkout code uses: actions/checkout@v4 with: fetch-depth: 0 persist-credentials: false - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: '22' registry-url: 'https://registry.npmjs.org' - name: Setup Bun uses: oven-sh/setup-bun@v2 with: bun-version: '1.3.9' - name: Install dependencies run: bash scripts/ensure-deps.sh - name: Build package run: bun run build:all - name: Validate fast gate run: bun run validate - name: Test slow bucket run: bun run test:slow - name: Test CLI e2e env: CCS_E2E_SKIP_BUILD: '1' run: bun run test:e2e - name: Release id: release env: HUSKY: 0 # PAT_TOKEN bypasses branch protection so semantic-release can push # version bump + CHANGELOG commits directly to main. GITHUB_TOKEN: ${{ secrets.PAT_TOKEN }} GH_TOKEN: ${{ secrets.PAT_TOKEN }} NPM_TOKEN: ${{ secrets.NPM_TOKEN }} NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} run: | auth_header=$(printf 'x-access-token:%s' "$GITHUB_TOKEN" | base64 | tr -d '\n') echo "::add-mask::${auth_header}" export GIT_CONFIG_COUNT=2 export GIT_CONFIG_KEY_0=http.https://github.com/kaitranntt/ccs.extraheader export GIT_CONFIG_VALUE_0="AUTHORIZATION: basic ${auth_header}" export GIT_CONFIG_KEY_1=http.https://github.com/kaitranntt/ccs.git.extraheader export GIT_CONFIG_VALUE_1="AUTHORIZATION: basic ${auth_header}" set +e OUTPUT=$(bun x semantic-release 2>&1) STATUS=$? set -e echo "$OUTPUT" # Strip ANSI color codes before matching (semantic-release outputs colored text) CLEAN=$(echo "$OUTPUT" | sed 's/\x1b\[[0-9;]*m//g') if [[ "$STATUS" -ne 0 ]]; then echo "released=false" >> $GITHUB_OUTPUT exit "$STATUS" fi if echo "$CLEAN" | grep -q "Published GitHub release"; then echo "released=true" >> $GITHUB_OUTPUT else echo "released=false" >> $GITHUB_OUTPUT fi - name: Notify Discord if: success() && steps.release.outputs.released == 'true' env: DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }} run: | if [ -z "$DISCORD_WEBHOOK_URL" ]; then echo "DISCORD_WEBHOOK_URL not set, skipping" exit 0 fi node scripts/send-discord-release.cjs production "$DISCORD_WEBHOOK_URL" - name: Cleanup labels and close released issues if: success() && steps.release.outputs.released == 'true' env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: node scripts/github/stable-release-issue-cleanup.mjs