fix(security): update security contact email to codewhale.com #2
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: Auto-tag on version bump | ||
| # When the workspace version on `main` advances past the latest existing | ||
| # `vX.Y.Z` tag, push the matching tag automatically. The push then triggers | ||
| # `release.yml`, which runs parity, builds binaries, drafts the GitHub | ||
| # Release, and publishes the npm wrapper. | ||
| # | ||
| # IMPORTANT: tag pushes signed by the default `GITHUB_TOKEN` do NOT trigger | ||
| # downstream `on: push: tags` workflows (GitHub Actions safety rule). For | ||
| # this auto-tag flow to actually fire `release.yml`, store a PAT (or | ||
| # fine-grained token) with `contents: write` on this repo as the | ||
| # `RELEASE_TAG_PAT` secret. Without it, the tag is created but `release.yml` | ||
| # does NOT run automatically — you'd have to push the tag again manually | ||
| # (`git push origin v$VERSION` from a developer machine) to trigger release. | ||
| on: | ||
| push: | ||
| branches: [main] | ||
| paths: | ||
| - 'Cargo.toml' | ||
| - 'npm/codewhale/package.json' | ||
| - 'npm/deepseek-tui/package.json' | ||
| workflow_dispatch: | ||
| permissions: | ||
| contents: write | ||
| # Serialize auto-tag runs per branch to prevent race conditions when | ||
| # multiple version bumps land on main in quick succession. | ||
| concurrency: | ||
| group: auto-tag-${{ github.ref_name }} | ||
| cancel-in-progress: false | ||
| jobs: | ||
| tag: | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| with: | ||
| fetch-depth: 0 | ||
| # Prefer PAT so the resulting tag push triggers release.yml. | ||
| # Falls back to GITHUB_TOKEN, which will tag but NOT trigger. | ||
| token: ${{ secrets.RELEASE_TAG_PAT || github.token }} | ||
| - name: Read workspace version | ||
| id: ver | ||
| run: | | ||
| # Robust version parsing: extract version from workspace Cargo.toml | ||
| # and validate it matches semver format vX.Y.Z (without v prefix). | ||
| v="$(grep -E '^version = "' Cargo.toml | head -n1 | sed -E 's/^version = "([^"]+)".*/\1/')" | ||
| if [ -z "$v" ]; then | ||
| echo "::error::Could not parse workspace version from Cargo.toml" >&2 | ||
| exit 1 | ||
| fi | ||
| # Validate semver format (digits.digits.digits) | ||
| if ! echo "$v" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+$'; then | ||
| echo "::error::Workspace version '$v' is not valid semver (expected X.Y.Z)" >&2 | ||
| exit 1 | ||
| fi | ||
| echo "version=$v" >> "$GITHUB_OUTPUT" | ||
| echo "tag=v$v" >> "$GITHUB_OUTPUT" | ||
| echo "Workspace version: $v" | ||
| - name: Check whether tag already exists | ||
| id: check | ||
| env: | ||
| TAG: ${{ steps.ver.outputs.tag }} | ||
| run: | | ||
| git fetch --tags --quiet | ||
| # Check both local tags and remote tags for idempotency | ||
| if git rev-parse -q --verify "refs/tags/${TAG}" >/dev/null 2>&1 || \ | ||
| git ls-remote --tags origin "refs/tags/${TAG}" | grep -q .; then | ||
| echo "exists=true" >> "$GITHUB_OUTPUT" | ||
| echo "::notice::Tag ${TAG} already exists; nothing to do (idempotent)." | ||
| else | ||
| echo "exists=false" >> "$GITHUB_OUTPUT" | ||
| echo "Tag ${TAG} does not exist; will create." | ||
| fi | ||
| - name: Verify version consistency | ||
| if: steps.check.outputs.exists == 'false' | ||
| run: | | ||
| # Run version consistency check before creating tag | ||
| # This prevents tagging inconsistent versions | ||
| ./scripts/release/check-versions.sh || { | ||
| echo "::error::Version consistency check failed. Aborting tag creation." >&2 | ||
| exit 1 | ||
| } | ||
| - name: Create and push tag | ||
| if: steps.check.outputs.exists == 'false' | ||
| env: | ||
| TAG: ${{ steps.ver.outputs.tag }} | ||
| run: | | ||
| git config user.name "github-actions[bot]" | ||
| git config user.email "41898282+github-actions[bot]@users.noreply.github.com" | ||
| # Create annotated tag with release information | ||
| git tag -a "${TAG}" -m "Release ${TAG} | ||
| Automatically created by auto-tag workflow. | ||
| Commit: ${GITHUB_SHA} | ||
| Repository: ${GITHUB_REPOSITORY} | ||
| " | ||
| # Push with retry logic for network resilience | ||
| max_retries=3 | ||
| retry_count=0 | ||
| while [[ ${retry_count} -lt ${max_retries} ]]; do | ||
| if git push origin "${TAG}" 2>/dev/null; then | ||
| echo "Successfully pushed ${TAG}." | ||
| echo "release.yml should now run (requires RELEASE_TAG_PAT for trigger)." | ||
| exit 0 | ||
| fi | ||
| retry_count=$((retry_count + 1)) | ||
| if [[ ${retry_count} -lt ${max_retries} ]]; then | ||
| echo "Push attempt ${retry_count} failed; retrying in 10s..." | ||
| sleep 10 | ||
| fi | ||
| done | ||
| echo "::error::Failed to push tag ${TAG} after ${max_retries} attempts." >&2 | ||
| exit 1 | ||
| - name: Warn if PAT missing | ||
| if: steps.check.outputs.exists == 'false' && env.HAS_PAT != 'true' | ||
| env: | ||
| HAS_PAT: ${{ secrets.RELEASE_TAG_PAT != '' }} | ||
| run: | | ||
| echo "::warning::RELEASE_TAG_PAT secret is not set. The tag was pushed using GITHUB_TOKEN, which does NOT trigger release.yml. Manually re-push the tag from a developer machine, or run 'gh workflow run release.yml --ref ${{ steps.ver.outputs.tag }}'." | ||