From 3c81d3af231398a9e66b7cab68a7814b98f314b0 Mon Sep 17 00:00:00 2001 From: ajianaz Date: Sat, 8 Aug 2026 23:42:19 +0700 Subject: [PATCH 01/11] ci(cla): add CLA check workflow Calls org-level reusable workflow from codecoradev/.github. Every PR will now be checked for CLA signature. Signed-off-by: ajianaz --- .github/workflows/cla-check.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 .github/workflows/cla-check.yml diff --git a/.github/workflows/cla-check.yml b/.github/workflows/cla-check.yml new file mode 100644 index 0000000..03afb7a --- /dev/null +++ b/.github/workflows/cla-check.yml @@ -0,0 +1,14 @@ +name: CLA Check + +on: + pull_request: + types: [opened, synchronize, reopened] + +jobs: + cla: + uses: codecoradev/.github/.github/workflows/cla-check.yml@main + with: + pr-number: ${{ github.event.pull_request.number }} + pr-author: ${{ github.event.pull_request.user.login }} + pr-head-sha: ${{ github.event.pull_request.head.sha }} + secrets: inherit From 9269ea2f862dfdf76ba76313f793c95a77b13aa5 Mon Sep 17 00:00:00 2001 From: ajianaz Date: Sat, 8 Aug 2026 23:51:34 +0700 Subject: [PATCH 02/11] ci: re-trigger CLA check (org workflow now merged) Signed-off-by: ajianaz From 722de0b818a60b7d6ed2b789c9b1809f8095e030 Mon Sep 17 00:00:00 2001 From: ajianaz Date: Sat, 8 Aug 2026 23:52:34 +0700 Subject: [PATCH 03/11] fix(ci): add permissions to CLA check caller workflow Reusable workflow needs explicit permissions grant from caller. Without it, GitHub Actions silently fails (0s, no log). Signed-off-by: ajianaz --- .github/workflows/cla-check.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/cla-check.yml b/.github/workflows/cla-check.yml index 03afb7a..919c4d3 100644 --- a/.github/workflows/cla-check.yml +++ b/.github/workflows/cla-check.yml @@ -4,6 +4,11 @@ on: pull_request: types: [opened, synchronize, reopened] +permissions: + pull-requests: write + contents: read + statuses: write + jobs: cla: uses: codecoradev/.github/.github/workflows/cla-check.yml@main From 7030e5f4fc9683f05330ab74daff985268a8fa9e Mon Sep 17 00:00:00 2001 From: ajianaz Date: Sat, 8 Aug 2026 23:53:52 +0700 Subject: [PATCH 04/11] fix(ci): inline CLA check workflow (drop reusable dependency) Reusable workflow path with .github repo caused YAML validation failure (0s, no jobs). Switching to self-contained inline workflow that fetches signatures.json from org repo via raw.githubusercontent. Signed-off-by: ajianaz --- .github/workflows/cla-check.yml | 121 ++++++++++++++++++++++++++++++-- 1 file changed, 114 insertions(+), 7 deletions(-) diff --git a/.github/workflows/cla-check.yml b/.github/workflows/cla-check.yml index 919c4d3..99cbf06 100644 --- a/.github/workflows/cla-check.yml +++ b/.github/workflows/cla-check.yml @@ -10,10 +10,117 @@ permissions: statuses: write jobs: - cla: - uses: codecoradev/.github/.github/workflows/cla-check.yml@main - with: - pr-number: ${{ github.event.pull_request.number }} - pr-author: ${{ github.event.pull_request.user.login }} - pr-head-sha: ${{ github.event.pull_request.head.sha }} - secrets: inherit + cla-check: + runs-on: ubuntu-latest + steps: + - name: Fetch CLA signatures + run: | + curl -sfL "https://raw.githubusercontent.com/codecoradev/.github/main/.cla/signatures.json" -o signatures.json \ + || echo '{"signatures":[]}' > signatures.json + + - name: Check CLA signature + id: check + run: | + python3 - << 'EOF' + import json, os + + author = os.environ["PR_AUTHOR"] + with open("signatures.json") as f: + data = json.load(f) + + signatures = data.get("signatures", []) + found = any( + s.get("github_username", "").lower() == author.lower() + for s in signatures + ) + + with open(os.environ["GITHUB_OUTPUT"], "a") as f: + f.write(f"signed={'true' if found else 'false'}\n") + + print(f"CLA signed by @{author}: {found}") + EOF + env: + PR_AUTHOR: ${{ github.event.pull_request.user.login }} + + - name: Comment on PR + uses: actions/github-script@v7 + with: + script: | + const signed = '${{ steps.check.outputs.signed }}' === 'true'; + const author = '${{ github.event.pull_request.user.login }}'; + const prNumber = ${{ github.event.pull_request.number }}; + + // Find existing CLA bot comment + const comments = await github.rest.issues.listComments({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: prNumber, + }); + + const botComment = comments.data.find(c => + c.user.login === 'github-actions[bot]' && + c.body.includes('CodeCoraDev CLA Bot') + ); + + const body = signed + ? [ + '## ✅ CodeCoraDev CLA Bot', + '', + `Thank you @${author}! Your CLA is on file. 🎉`, + '', + 'Your contribution can now be reviewed.', + ].join('\n') + : [ + '## ⚠️ CodeCoraDev CLA Bot', + '', + `Hi @${author}! Thanks for your contribution.`, + '', + 'Before this PR can be reviewed, please sign our Contributor License Agreement:', + '', + '- 📋 **Individual?** → [Sign CLA Individual](https://codecoradev.github.io/cla/?type=individual)', + '- 🏢 **Corporate?** → [Sign CLA Corporate](https://codecoradev.github.io/cla/?type=corporate)', + '', + '---', + 'By signing, you agree to the terms in [CLA_INDIVIDUAL.md](https://github.com/codecoradev/.github/blob/main/CLA_INDIVIDUAL.md) or [CLA_CORPORATE.md](https://github.com/codecoradev/.github/blob/main/CLA_CORPORATE.md).', + ].join('\n'); + + if (botComment) { + await github.rest.issues.updateComment({ + owner: context.repo.owner, + repo: context.repo.repo, + comment_id: botComment.id, + body, + }); + } else { + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: prNumber, + body, + }); + } + + - name: Set commit status + uses: actions/github-script@v7 + with: + script: | + const signed = '${{ steps.check.outputs.signed }}' === 'true'; + await github.rest.repos.createCommitStatus({ + owner: context.repo.owner, + repo: context.repo.repo, + sha: '${{ github.event.pull_request.head.sha }}', + state: signed ? 'success' : 'failure', + context: 'CLA Check', + description: signed + ? '✅ CLA signed' + : '❌ CLA not signed — sign at https://codecoradev.github.io/cla', + target_url: signed + ? 'https://github.com/codecoradev/.github/blob/main/.cla/signatures.json' + : 'https://codecoradev.github.io/cla', + }); + + - name: Fail if not signed + if: steps.check.outputs.signed != 'true' + run: | + echo "❌ CLA not signed by ${{ github.event.pull_request.user.login }}" + exit 1 From 2ff56a4a4916700391e82fdab3899349b42da356 Mon Sep 17 00:00:00 2001 From: ajianaz Date: Sat, 8 Aug 2026 23:56:30 +0700 Subject: [PATCH 05/11] ci: re-trigger CLA check (CDN cache cleared) Signed-off-by: ajianaz From 4bb09154ff1dd4243b20cdd21e48e1a0ef0b0315 Mon Sep 17 00:00:00 2001 From: ajianaz Date: Sat, 8 Aug 2026 23:58:15 +0700 Subject: [PATCH 06/11] fix(ci): use GitHub API for signatures (raw CDN unreliable) raw.githubusercontent.com returns HTTP 200 with '404: Not Found' body instead of proper HTTP 404, breaking curl -f flag. Switching to gh api which properly resolves content via GitHub REST API. Signed-off-by: ajianaz --- .github/workflows/cla-check.yml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/workflows/cla-check.yml b/.github/workflows/cla-check.yml index 99cbf06..cff6092 100644 --- a/.github/workflows/cla-check.yml +++ b/.github/workflows/cla-check.yml @@ -14,8 +14,15 @@ jobs: runs-on: ubuntu-latest steps: - name: Fetch CLA signatures + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | - curl -sfL "https://raw.githubusercontent.com/codecoradev/.github/main/.cla/signatures.json" -o signatures.json \ + # Use GitHub API (more reliable than raw CDN) + gh api repos/codecoradev/.github/contents/.cla/signatures.json --jq '.content' \ + | base64 -d > signatures.json 2>/dev/null \ + || echo '{"signatures":[]}' > signatures.json + # Validate JSON + python3 -c "import json; json.load(open('signatures.json'))" 2>/dev/null \ || echo '{"signatures":[]}' > signatures.json - name: Check CLA signature From 32b9fc77269924e6e0891e89c5f76744beae79b5 Mon Sep 17 00:00:00 2001 From: ajianaz Date: Sat, 8 Aug 2026 23:59:44 +0700 Subject: [PATCH 07/11] fix(ci): use public REST API for signatures fetch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GITHUB_TOKEN is repo-scoped — cannot access codecoradev/.github. Switching to unauthenticated public REST API endpoint (60 req/hr limit is fine for PR-triggered workflow). Signed-off-by: ajianaz --- .github/workflows/cla-check.yml | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/.github/workflows/cla-check.yml b/.github/workflows/cla-check.yml index cff6092..acbc3c2 100644 --- a/.github/workflows/cla-check.yml +++ b/.github/workflows/cla-check.yml @@ -14,12 +14,10 @@ jobs: runs-on: ubuntu-latest steps: - name: Fetch CLA signatures - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | - # Use GitHub API (more reliable than raw CDN) - gh api repos/codecoradev/.github/contents/.cla/signatures.json --jq '.content' \ - | base64 -d > signatures.json 2>/dev/null \ + # Fetch via GitHub REST API (unauthenticated, public repo) + curl -sfL "https://api.github.com/repos/codecoradev/.github/contents/.cla/signatures.json" \ + | python3 -c "import json,sys,base64; d=json.load(sys.stdin); sys.stdout.buffer.write(base64.b64decode(d['content']))" > signatures.json 2>/dev/null \ || echo '{"signatures":[]}' > signatures.json # Validate JSON python3 -c "import json; json.load(open('signatures.json'))" 2>/dev/null \ From 132e3f4b34775c2160254c580c6aa71e4c8c4e16 Mon Sep 17 00:00:00 2001 From: ajianaz Date: Sun, 9 Aug 2026 00:03:15 +0700 Subject: [PATCH 08/11] fix(ci): use actions/checkout for signatures fetch All CDN/API approaches failed for cross-repo access: - raw.githubusercontent: CDN cache returns 404 body with HTTP 200 - api.github.com: rate limited unauthenticated, GITHUB_TOKEN 404 cross-repo - jsdelivr: too slow for freshly pushed content actions/checkout with sparse-checkout is bulletproof: uses git protocol to clone .cla/ folder from codecoradev/.github directly. Signed-off-by: ajianaz --- .github/workflows/cla-check.yml | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/.github/workflows/cla-check.yml b/.github/workflows/cla-check.yml index acbc3c2..2352528 100644 --- a/.github/workflows/cla-check.yml +++ b/.github/workflows/cla-check.yml @@ -14,18 +14,17 @@ jobs: runs-on: ubuntu-latest steps: - name: Fetch CLA signatures - run: | - # Fetch via GitHub REST API (unauthenticated, public repo) - curl -sfL "https://api.github.com/repos/codecoradev/.github/contents/.cla/signatures.json" \ - | python3 -c "import json,sys,base64; d=json.load(sys.stdin); sys.stdout.buffer.write(base64.b64decode(d['content']))" > signatures.json 2>/dev/null \ - || echo '{"signatures":[]}' > signatures.json - # Validate JSON - python3 -c "import json; json.load(open('signatures.json'))" 2>/dev/null \ - || echo '{"signatures":[]}' > signatures.json + uses: actions/checkout@v4 + with: + repository: codecoradev/.github + path: cla-store + sparse-checkout: .cla + token: ${{ secrets.GITHUB_TOKEN }} - name: Check CLA signature id: check run: | + cp cla-store/.cla/signatures.json signatures.json 2>/dev/null || echo '{"signatures":[]}' > signatures.json python3 - << 'EOF' import json, os From b24d73b8d9210e9672ff2bd47de57360283d2542 Mon Sep 17 00:00:00 2001 From: ajianaz Date: Sun, 9 Aug 2026 00:05:15 +0700 Subject: [PATCH 09/11] fix(ci): use unauthenticated git clone for signatures MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GITHUB_TOKEN cannot access codecoradev/.github (repo-scoped). Switching to plain git clone over HTTPS — repo is public, no auth needed. Signed-off-by: ajianaz --- .github/workflows/cla-check.yml | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/.github/workflows/cla-check.yml b/.github/workflows/cla-check.yml index 2352528..fc1a801 100644 --- a/.github/workflows/cla-check.yml +++ b/.github/workflows/cla-check.yml @@ -13,18 +13,16 @@ jobs: cla-check: runs-on: ubuntu-latest steps: - - name: Fetch CLA signatures - uses: actions/checkout@v4 - with: - repository: codecoradev/.github - path: cla-store - sparse-checkout: .cla - token: ${{ secrets.GITHUB_TOKEN }} - - - name: Check CLA signature + - name: Fetch & check CLA signature id: check run: | + # Clone .cla/ folder from public repo (no auth needed) + git clone --no-checkout --depth 1 https://github.com/codecoradev/.github.git cla-store 2>&1 + cd cla-store && git sparse-checkout set .cla && git checkout 2>&1 + cd .. cp cla-store/.cla/signatures.json signatures.json 2>/dev/null || echo '{"signatures":[]}' > signatures.json + echo "Loaded signatures:" + python3 -c "import json; d=json.load(open('signatures.json')); print(f' {len(d.get(\"signatures\",[]))} entries')" python3 - << 'EOF' import json, os From 8bf98e62fcf8b9ab096bd1343eb6ffc11d50b221 Mon Sep 17 00:00:00 2001 From: ajianaz Date: Sun, 9 Aug 2026 00:07:05 +0700 Subject: [PATCH 10/11] fix(ci): wget+curl fallback for signatures fetch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .github repo was private — now public. CDN may still cache 404. Using wget (primary) → curl (fallback) → empty JSON (last resort). Signed-off-by: ajianaz --- .github/workflows/cla-check.yml | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/.github/workflows/cla-check.yml b/.github/workflows/cla-check.yml index fc1a801..d189a4b 100644 --- a/.github/workflows/cla-check.yml +++ b/.github/workflows/cla-check.yml @@ -16,13 +16,14 @@ jobs: - name: Fetch & check CLA signature id: check run: | - # Clone .cla/ folder from public repo (no auth needed) - git clone --no-checkout --depth 1 https://github.com/codecoradev/.github.git cla-store 2>&1 - cd cla-store && git sparse-checkout set .cla && git checkout 2>&1 - cd .. - cp cla-store/.cla/signatures.json signatures.json 2>/dev/null || echo '{"signatures":[]}' > signatures.json - echo "Loaded signatures:" - python3 -c "import json; d=json.load(open('signatures.json')); print(f' {len(d.get(\"signatures\",[]))} entries')" + # Fetch signatures.json directly from raw GitHub (public repo) + # Use wget as primary (handles 200-with-404-body better than curl) + wget -q -O signatures.json "https://raw.githubusercontent.com/codecoradev/.github/main/.cla/signatures.json" 2>/dev/null \ + || curl -sfL "https://raw.githubusercontent.com/codecoradev/.github/main/.cla/signatures.json" -o signatures.json 2>/dev/null \ + || echo '{"signatures":[]}' > signatures.json + # Validate JSON — if invalid, use empty + python3 -c "import json; json.load(open('signatures.json'))" 2>/dev/null \ + || echo '{"signatures":[]}' > signatures.json python3 - << 'EOF' import json, os From f141f16b3c5964e5ecd26ecf8bb8f85909fef8bd Mon Sep 17 00:00:00 2001 From: ajianaz Date: Sun, 9 Aug 2026 00:09:19 +0700 Subject: [PATCH 11/11] ci: re-trigger CLA check (.github now public + CDN refreshed) Signed-off-by: ajianaz