Release #14
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: | |
| permissions: | |
| contents: write | |
| id-token: write | |
| issues: write | |
| pull-requests: write | |
| jobs: | |
| release: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Verify admin permissions | |
| run: | | |
| # Use the repository's permission endpoint which works for both personal and org repos | |
| RESPONSE=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ | |
| -H "Accept: application/vnd.github.v3+json" \ | |
| "https://api.github.com/repos/${{ github.repository }}/collaborators/${{ github.actor }}/permission") | |
| # Extract permission using jq if available, otherwise use grep | |
| if command -v jq &> /dev/null; then | |
| PERMISSION=$(echo "$RESPONSE" | jq -r '.permission // empty') | |
| else | |
| PERMISSION=$(echo "$RESPONSE" | grep -o '"permission":"[^"]*"' | head -1 | cut -d'"' -f4) | |
| fi | |
| if [ -z "$PERMISSION" ]; then | |
| echo "Warning: Could not determine permission level. Response: $RESPONSE" | |
| echo "Note: workflow_dispatch requires write access, proceeding..." | |
| exit 0 | |
| fi | |
| if [ "$PERMISSION" != "admin" ]; then | |
| echo "Error: Only repository admins can trigger releases. Current permission: $PERMISSION" | |
| exit 1 | |
| fi | |
| echo "✓ Verified admin permission for ${{ github.actor }}" | |
| - uses: actions/checkout@v4 | |
| with: | |
| ref: main | |
| fetch-depth: 0 | |
| - name: Setup git branch | |
| run: | | |
| git fetch --all --tags | |
| git checkout -B main | |
| git branch --set-upstream-to=origin/main main | |
| - name: Debug branch info | |
| run: | | |
| echo "Current branch: $(git branch --show-current)" | |
| echo "All branches: $(git branch -a)" | |
| echo "Git remote: $(git remote -v)" | |
| echo "Git status: $(git status)" | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20' | |
| registry-url: 'https://registry.npmjs.org' | |
| always-auth: true | |
| - run: npm ci | |
| - run: npm test --if-present | |
| - name: Configure git | |
| run: | | |
| git config user.name "github-actions[bot]" | |
| git config user.email "github-actions[bot]@users.noreply.github.com" | |
| - name: Create initial tag if needed | |
| run: | | |
| if ! git rev-parse --verify "v1.0.0-beta.1" >/dev/null 2>&1; then | |
| echo "Creating initial tag v1.0.0-beta.1" | |
| git tag -a "v1.0.0-beta.1" -m "chore: initial beta release" | |
| git push origin "v1.0.0-beta.1" || echo "Tag push failed (may not have permission or tag exists)" | |
| else | |
| echo "Tag v1.0.0-beta.1 already exists" | |
| fi | |
| - name: Debug semantic-release config | |
| run: | | |
| echo "=== .releaserc.json ===" | |
| cat .releaserc.json | |
| echo "" | |
| echo "=== Git branches ===" | |
| git branch -a | |
| echo "" | |
| echo "=== Current branch ===" | |
| git branch --show-current | |
| echo "" | |
| echo "=== Git tags ===" | |
| git tag | |
| - name: Configure npm authentication for semantic-release | |
| run: | | |
| echo "=== NPM Authentication Setup ===" | |
| echo "NPM_CONFIG_USERCONFIG: $NPM_CONFIG_USERCONFIG" | |
| echo "NODE_AUTH_TOKEN is set: $([ -n "$NODE_AUTH_TOKEN" ] && echo 'yes' || echo 'no')" | |
| # Check if .npmrc exists in temp location | |
| if [ -f "$NPM_CONFIG_USERCONFIG" ]; then | |
| echo "✓ Found .npmrc at $NPM_CONFIG_USERCONFIG" | |
| # Show first line only (without token) for debugging | |
| head -1 "$NPM_CONFIG_USERCONFIG" | sed 's/=.*/=***/' || true | |
| # Copy to home directory | |
| mkdir -p ~/.npm | |
| cp "$NPM_CONFIG_USERCONFIG" ~/.npmrc | |
| echo "✓ Copied .npmrc to ~/.npmrc" | |
| # Extract token - try multiple patterns | |
| TOKEN="" | |
| # Pattern 1: //registry.npmjs.org/:_authToken=TOKEN | |
| TOKEN=$(grep -oP '(?<=//registry\.npmjs\.org/:_authToken=).*' ~/.npmrc 2>/dev/null || echo "") | |
| # Pattern 2: _authToken=TOKEN (without registry prefix) | |
| if [ -z "$TOKEN" ]; then | |
| TOKEN=$(grep -oP '(?<=_authToken=).*' ~/.npmrc 2>/dev/null | head -1 || echo "") | |
| fi | |
| # Pattern 3: Check if it's using NODE_AUTH_TOKEN variable | |
| if [ -z "$TOKEN" ] && [ -n "$NODE_AUTH_TOKEN" ]; then | |
| TOKEN="$NODE_AUTH_TOKEN" | |
| echo "Using NODE_AUTH_TOKEN directly" | |
| fi | |
| if [ -n "$TOKEN" ]; then | |
| # Mask token in logs | |
| echo "::add-mask::$TOKEN" | |
| echo "NPM_TOKEN=$TOKEN" >> $GITHUB_ENV | |
| echo "✓ NPM_TOKEN configured (masked in logs)" | |
| else | |
| echo "✗ Warning: Could not extract token from .npmrc" | |
| echo "Contents of ~/.npmrc (first 3 lines, tokens masked):" | |
| head -3 ~/.npmrc | sed 's/=.*/=***/' || true | |
| fi | |
| else | |
| echo "✗ Warning: NPM_CONFIG_USERCONFIG file not found" | |
| echo "Trying to use NODE_AUTH_TOKEN directly..." | |
| if [ -n "$NODE_AUTH_TOKEN" ]; then | |
| echo "::add-mask::$NODE_AUTH_TOKEN" | |
| echo "NPM_TOKEN=$NODE_AUTH_TOKEN" >> $GITHUB_ENV | |
| echo "✓ NPM_TOKEN set from NODE_AUTH_TOKEN" | |
| else | |
| echo "✗ Error: No npm authentication found" | |
| fi | |
| fi | |
| # Test npm auth | |
| echo "" | |
| echo "=== Testing npm authentication ===" | |
| if npm whoami --registry=https://registry.npmjs.org 2>/dev/null; then | |
| echo "✓ npm authentication successful" | |
| else | |
| echo "✗ npm authentication failed" | |
| echo "This might be OK if using OIDC - semantic-release will verify" | |
| fi | |
| - name: Release | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: npx semantic-release |