All 3 merge methods (merge, squash, rebase) #175
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: Portfolio CI | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| branches: [main] | |
| jobs: | |
| # ------------------- | |
| # 1. Lint HTML, CSS, JS | |
| # ------------------- | |
| lint: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: 20 | |
| - name: Install linters | |
| run: npm install -g eslint stylelint htmlhint | |
| - name: Lint JavaScript | |
| run: eslint . --ext .js,.jsx || true | |
| - name: Lint CSS | |
| run: stylelint "**/*.{css,scss}" || true | |
| - name: Lint HTML | |
| run: htmlhint "**/*.html" || true | |
| # ------------------- | |
| # 2. DCO + GPG Check | |
| # 2.1 Commit Verification (GPG + Trust) | |
| # ------------------- | |
| commit-checks: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 # full history, but we’ll check only the latest commit | |
| # ---------- DCO Check ---------- | |
| - name: DCO Check | |
| if: github.event_name == 'pull_request' | |
| uses: tisonkun/actions-dco@v1.1 | |
| - name: Import GPG public keys | |
| run: | | |
| if [ -n "${{ secrets.GPG_PUBLIC_KEY }}" ]; then | |
| echo "${{ secrets.GPG_PUBLIC_KEY }}" | gpg --import | |
| echo "✅ Imported GPG_PUBLIC_KEY" | |
| fi | |
| if [ -n "${{ secrets.GPG_PUBLIC_KEY_1 }}" ]; then | |
| echo "${{ secrets.GPG_PUBLIC_KEY_1 }}" | gpg --import | |
| echo "✅ Imported GPG_PUBLIC_KEY_1" | |
| fi | |
| # ---------- Verify latest commit ---------- | |
| - name: Verify commit signature | |
| run: | | |
| if [ "${{ github.event_name }}" = "pull_request" ]; then | |
| echo "🔍 PR mode: verifying ALL commits in PR" | |
| BASE=${{ github.event.pull_request.base.sha }} | |
| HEAD=${{ github.event.pull_request.head.sha }} | |
| # Get all commits in PR | |
| COMMITS=$(git rev-list $BASE..$HEAD) | |
| for COMMIT in $COMMITS; do | |
| echo "🔎 Checking commit: $COMMIT" | |
| # Step 1: Cryptographic verification | |
| if git verify-commit "$COMMIT" >/dev/null 2>&1; then | |
| echo "✅ Signature valid" | |
| else | |
| echo "❌ Commit not signed properly" | |
| exit 1 | |
| fi | |
| # Step 2: Fingerprint check | |
| FINGERPRINT=$(git log -1 --pretty=format:'%GF' "$COMMIT") | |
| echo "🔑 Fingerprint: $FINGERPRINT" | |
| TRUSTED_KEYS="83FB991D930D7177F25456C07F4C7CA953E1C09E D432152833DA3244" | |
| if echo "$TRUSTED_KEYS" | grep -q "$FINGERPRINT"; then | |
| echo "✅ Trusted key" | |
| else | |
| echo "❌ Untrusted key!" | |
| exit 1 | |
| fi | |
| done | |
| echo "🎉 All PR commits are valid and trusted" | |
| else | |
| echo "🔍 Push to main detected" | |
| echo "ℹ️ Skipping strict GPG verification for merge/rebase/squash commit" | |
| git log -1 --oneline | |
| fi | |
| # ---------- Optional status for skipped forked PRs ---------- | |
| - name: Skip GPG checks for external PRs | |
| if: ${{ github.event.pull_request.head.repo.full_name != github.repository && github.event_name == 'pull_request' }} | |
| run: echo "🟡 Skipping GPG verification for external PR (no access to secrets)." |