Skip to content

fix: resolve OpenSSF Scorecard warnings and enable verified GPG commits #947

fix: resolve OpenSSF Scorecard warnings and enable verified GPG commits

fix: resolve OpenSSF Scorecard warnings and enable verified GPG commits #947

Workflow file for this run

name: CI/CD Pipeline
on:
pull_request:
branches: [main]
pull_request_target:
branches: [main]
types: [opened, synchronize, reopened]
push:
branches: [main]
merge_group:
branches: [main]
permissions:
contents: read
jobs:
# This job acts as a prerequisite for the pipeline. It runs on EVERY PR, push, and merge queue (merge_group) run.
# Currently performs repository checkout to prepare for subsequent jobs.
# For formal releases with versioning and signed artifacts, see .github/workflows/release.yml
guard:
name: Build Guard
runs-on: ubuntu-latest
# Security: Only run on version bump PRs from the trusted bot
if: |
github.event_name != 'pull_request_target' ||
(startsWith(github.event.pull_request.head.ref, 'version-bump-') && github.event.pull_request.user.login == 'ghostclass-release-automation[bot]')
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
# SECURITY: This workflow uses pull_request_target but is SAFE because:
# 1. Job-level 'if' condition restricts pull_request_target to ONLY trusted bot PRs
# 2. For pull_request events: checks out PR head to run tests on proposed changes
# 3. For pull_request_target events: checks out base branch (trusted code only)
ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }}
# Auto-tag releases on main branch
# This simplified job creates signed tags from version bumps made in PRs
# The version bump now happens at PR creation time via auto-version-bump.yml
auto-tag:
name: Auto Tag Release
needs: guard
if: |
github.event_name == 'push' &&
github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
- name: Import GPG key
uses: crazy-max/ghaction-import-gpg@01dd5d3ca463c7f10f7f4f7b4f177225ac661ee4 # v6.1.0
with:
gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
passphrase: ${{ secrets.GPG_PASSPHRASE }}
git_tag_gpgsign: true
git_user_signingkey: true
- name: Setup Node.js
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
with:
node-version: '20'
- name: Create and push signed tag
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -euo pipefail
VERSION=$(node -p "require('./package.json').version")
VERSION_TAG="v${VERSION}"
echo "Current version: ${VERSION}"
echo "Tag to create: ${VERSION_TAG}"
# Check if tag already exists
if git ls-remote --tags origin | grep -q "refs/tags/${VERSION_TAG}$"; then
echo "Tag ${VERSION_TAG} already exists, skipping"
exit 0
fi
echo "Creating signed tag ${VERSION_TAG}"
# Configure git identity for tagging (GPG action sets signing config)
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
# Create signed annotated tag
git tag -a "${VERSION_TAG}" -m "Release ${VERSION_TAG}"
# Push tag (handle possible concurrent creation)
set +e
git push origin "${VERSION_TAG}"
push_status=$?
set -e
if [ $push_status -ne 0 ]; then
echo "git push for tag ${VERSION_TAG} failed with status ${push_status}, checking if tag exists on remote..."
if git ls-remote --tags origin | grep -q "refs/tags/${VERSION_TAG}$"; then
echo "Tag ${VERSION_TAG} already exists on remote (likely created concurrently); continuing."
else
echo "✗ Failed to push tag ${VERSION_TAG} and tag not found on remote."
exit $push_status
fi
fi
echo "✓ Tag ${VERSION_TAG} created and pushed"
# Trigger release workflow via repository_dispatch
echo "Triggering release workflow via repository_dispatch"
# Add retry logic for transient failures
max_attempts=3
attempt=1
while [ $attempt -le $max_attempts ]; do
if gh api repos/${{ github.repository }}/dispatches \
--method POST \
-H "Accept: application/vnd.github+json" \
-f event_type="release_requested" \
-f client_payload[version_tag]="${VERSION_TAG}" \
-f client_payload[triggered_by]="auto-tag" \
-f client_payload[run_id]="${{ github.run_id }}"; then
echo "✓ Release workflow triggered for ${VERSION_TAG}"
break
fi
if [ $attempt -eq $max_attempts ]; then
echo "✗ Failed to trigger release workflow after ${max_attempts} attempts"
exit 1
fi
echo "Retry attempt ${attempt}/${max_attempts} in 5s..."
sleep 5
attempt=$((attempt + 1))
done