Harden FastLED project sync workflow#3
Conversation
📝 WalkthroughWalkthroughThe workflow file is refactored to use the ChangesGitHub Actions workflow for fork-safe project board integration
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/add-to-project.yml:
- Line 1: The workflow file was flattened onto a single line breaking YAML
structure; restore proper YAML by putting top-level keys (name, on, env,
permissions, jobs) each on their own lines with correct indentation, re-indent
the jobs.add block and its steps, and ensure the step with id "app-token" and
the "Add to project" step (uses: actions/add-to-project@v1.0.2) are nested under
jobs -> add -> steps as a sequence; validate with a YAML linter/actionlint
before committing.
- Line 1: The skip warning message in the workflow step named "App not installed
— skipping project sync" incorrectly asserts the App is not installed when
actions/create-github-app-token (step id app-token) fails; update that step's
run output to a neutral message like "Skipping project sync: unable to create
App token (this can occur for fork PRs or when the private key secret is
unavailable)" and optionally include the step outcome to aid debugging, so
replace the current install-focused warnings with a neutral skip explanation
referencing the app-token creation failure.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: df4f7e50-b06b-4422-8cd2-57478bad680c
📒 Files selected for processing (1)
.github/workflows/add-to-project.yml
| with: | ||
| project-url: https://github.com/orgs/${{ vars.PROJECT_OWNER }}/projects/${{ vars.PROJECT_NUMBER }} | ||
| github-token: ${{ steps.app-token.outputs.token }} | ||
| name: add-to-project # Auto-adds every new issue / PR to the FastLED Tracker project (#1). # # Auth: GitHub App "FastLED Project Sync" — scoped to Projects: read/write + # Contents/Issues/Pull requests: read. No expiration (App installation tokens # auto-rotate). The App ID lives in a repo variable; the private key lives in # a repo secret. # # Required configuration (already set on all 6 feeder repos): # vars.PROJECT_APP_CLIENT_ID = Iv23liL4dLxjYFwTNWKt # vars.PROJECT_OWNER = FastLED # vars.PROJECT_NUMBER = 1 # secrets.PROJECT_APP_PRIVATE_KEY = <PEM contents> # # To rotate the App's private key: # 1. On https://github.com/organizations/FastLED/settings/apps generate new key # 2. For each repo: gh secret set PROJECT_APP_PRIVATE_KEY --repo FastLED/<repo> < new.pem # 3. Revoke the old key in the App settings on: issues: types: [opened] pull_request: types: [opened] env: FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true" # pull_request (not pull_request_target) — fork PRs run in the fork's context # without access to PROJECT_APP_PRIVATE_KEY, so they simply won't be # auto-added. That is an intentional security trade-off: pull_request_target # would run with base-repo secrets against fork-authored metadata, which is a # known exfiltration vector even when no code is checked out. permissions: contents: read pull-requests: read jobs: add: runs-on: ubuntu-latest if: ${{ vars.PROJECT_APP_CLIENT_ID != '' && vars.PROJECT_OWNER != '' }} steps: - name: Generate App token id: app-token continue-on-error: true uses: actions/create-github-app-token@v3 with: client-id: ${{ vars.PROJECT_APP_CLIENT_ID }} private-key: ${{ secrets.PROJECT_APP_PRIVATE_KEY }} owner: ${{ vars.PROJECT_OWNER }} - name: App not installed — skipping project sync if: ${{ steps.app-token.outcome != 'success' }} run: | echo "::warning::FastLED Project Sync App is not installed on '${{ vars.PROJECT_OWNER }}'." echo "::warning::Install it at https://github.com/organizations/${{ vars.PROJECT_OWNER }}/settings/installations to enable auto-add-to-project." - name: Add to project if: ${{ steps.app-token.outcome == 'success' }} uses: actions/add-to-project@v1.0.2 with: project-url: https://github.com/orgs/${{ vars.PROJECT_OWNER }}/projects/${{ vars.PROJECT_NUMBER }} github-token: ${{ steps.app-token.outputs.token }} No newline at end of file |
There was a problem hiding this comment.
Restore YAML structure before merging.
Line 1 currently contains the entire workflow body, so on, permissions, and jobs are not valid top-level YAML mappings. GitHub won't load this workflow at all, which matches the actionlint failures.
🐛 Proposed fix
-name: add-to-project # Auto-adds every new issue / PR to the FastLED Tracker project (`#1`). # # Auth: GitHub App "FastLED Project Sync" — scoped to Projects: read/write + # Contents/Issues/Pull requests: read. No expiration (App installation tokens # auto-rotate). The App ID lives in a repo variable; the private key lives in # a repo secret. # # Required configuration (already set on all 6 feeder repos): # vars.PROJECT_APP_CLIENT_ID = Iv23liL4dLxjYFwTNWKt # vars.PROJECT_OWNER = FastLED # vars.PROJECT_NUMBER = 1 # secrets.PROJECT_APP_PRIVATE_KEY = <PEM contents> # # To rotate the App's private key: # 1. On https://github.com/organizations/FastLED/settings/apps generate new key # 2. For each repo: gh secret set PROJECT_APP_PRIVATE_KEY --repo FastLED/<repo> < new.pem # 3. Revoke the old key in the App settings on: issues: types: [opened] pull_request: types: [opened] env: FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true" # pull_request (not pull_request_target) — fork PRs run in the fork's context # without access to PROJECT_APP_PRIVATE_KEY, so they simply won't be # auto-added. That is an intentional security trade-off: pull_request_target # would run with base-repo secrets against fork-authored metadata, which is a # known exfiltration vector even when no code is checked out. permissions: contents: read pull-requests: read jobs: add: runs-on: ubuntu-latest if: ${{ vars.PROJECT_APP_CLIENT_ID != '' && vars.PROJECT_OWNER != '' }} steps: - name: Generate App token id: app-token continue-on-error: true uses: actions/create-github-app-token@v3 with: client-id: ${{ vars.PROJECT_APP_CLIENT_ID }} private-key: ${{ secrets.PROJECT_APP_PRIVATE_KEY }} owner: ${{ vars.PROJECT_OWNER }} - name: App not installed — skipping project sync if: ${{ steps.app-token.outcome != 'success' }} run: | echo "::warning::FastLED Project Sync App is not installed on '${{ vars.PROJECT_OWNER }}'." echo "::warning::Install it at https://github.com/organizations/${{ vars.PROJECT_OWNER }}/settings/installations to enable auto-add-to-project." - name: Add to project if: ${{ steps.app-token.outcome == 'success' }} uses: actions/add-to-project@v1.0.2 with: project-url: https://github.com/orgs/${{ vars.PROJECT_OWNER }}/projects/${{ vars.PROJECT_NUMBER }} github-token: ${{ steps.app-token.outputs.token }}
+name: add-to-project
+
+on:
+ issues:
+ types: [opened]
+ pull_request:
+ types: [opened]
+
+env:
+ FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true"
+
+permissions:
+ contents: read
+ pull-requests: read
+
+jobs:
+ add:
+ runs-on: ubuntu-latest
+ if: ${{ vars.PROJECT_APP_CLIENT_ID != '' && vars.PROJECT_OWNER != '' }}
+ steps:
+ - name: Generate App token
+ id: app-token
+ continue-on-error: true
+ uses: actions/create-github-app-token@v3
+ with:
+ client-id: ${{ vars.PROJECT_APP_CLIENT_ID }}
+ private-key: ${{ secrets.PROJECT_APP_PRIVATE_KEY }}
+ owner: ${{ vars.PROJECT_OWNER }}
+
+ - name: App not installed — skipping project sync
+ if: ${{ steps.app-token.outcome != 'success' }}
+ run: |
+ echo "::warning::FastLED Project Sync App is not installed on '${{ vars.PROJECT_OWNER }}'."
+ echo "::warning::Install it at https://github.com/organizations/${{ vars.PROJECT_OWNER }}/settings/installations to enable auto-add-to-project."
+
+ - name: Add to project
+ if: ${{ steps.app-token.outcome == 'success' }}
+ uses: actions/add-to-project@v1.0.2
+ with:
+ project-url: https://github.com/orgs/${{ vars.PROJECT_OWNER }}/projects/${{ vars.PROJECT_NUMBER }}
+ github-token: ${{ steps.app-token.outputs.token }}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| name: add-to-project # Auto-adds every new issue / PR to the FastLED Tracker project (#1). # # Auth: GitHub App "FastLED Project Sync" — scoped to Projects: read/write + # Contents/Issues/Pull requests: read. No expiration (App installation tokens # auto-rotate). The App ID lives in a repo variable; the private key lives in # a repo secret. # # Required configuration (already set on all 6 feeder repos): # vars.PROJECT_APP_CLIENT_ID = Iv23liL4dLxjYFwTNWKt # vars.PROJECT_OWNER = FastLED # vars.PROJECT_NUMBER = 1 # secrets.PROJECT_APP_PRIVATE_KEY = <PEM contents> # # To rotate the App's private key: # 1. On https://github.com/organizations/FastLED/settings/apps generate new key # 2. For each repo: gh secret set PROJECT_APP_PRIVATE_KEY --repo FastLED/<repo> < new.pem # 3. Revoke the old key in the App settings on: issues: types: [opened] pull_request: types: [opened] env: FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true" # pull_request (not pull_request_target) — fork PRs run in the fork's context # without access to PROJECT_APP_PRIVATE_KEY, so they simply won't be # auto-added. That is an intentional security trade-off: pull_request_target # would run with base-repo secrets against fork-authored metadata, which is a # known exfiltration vector even when no code is checked out. permissions: contents: read pull-requests: read jobs: add: runs-on: ubuntu-latest if: ${{ vars.PROJECT_APP_CLIENT_ID != '' && vars.PROJECT_OWNER != '' }} steps: - name: Generate App token id: app-token continue-on-error: true uses: actions/create-github-app-token@v3 with: client-id: ${{ vars.PROJECT_APP_CLIENT_ID }} private-key: ${{ secrets.PROJECT_APP_PRIVATE_KEY }} owner: ${{ vars.PROJECT_OWNER }} - name: App not installed — skipping project sync if: ${{ steps.app-token.outcome != 'success' }} run: | echo "::warning::FastLED Project Sync App is not installed on '${{ vars.PROJECT_OWNER }}'." echo "::warning::Install it at https://github.com/organizations/${{ vars.PROJECT_OWNER }}/settings/installations to enable auto-add-to-project." - name: Add to project if: ${{ steps.app-token.outcome == 'success' }} uses: actions/add-to-project@v1.0.2 with: project-url: https://github.com/orgs/${{ vars.PROJECT_OWNER }}/projects/${{ vars.PROJECT_NUMBER }} github-token: ${{ steps.app-token.outputs.token }} | |
| name: add-to-project | |
| # Auto-adds every new issue / PR to the FastLED Tracker project (`#1`). | |
| # | |
| # Auth: GitHub App "FastLED Project Sync" — scoped to Projects: read/write + | |
| # Contents/Issues/Pull requests: read. No expiration (App installation tokens | |
| # auto-rotate). The App ID lives in a repo variable; the private key lives in | |
| # a repo secret. | |
| # | |
| # Required configuration (already set on all 6 feeder repos): | |
| # vars.PROJECT_APP_CLIENT_ID = Iv23liL4dLxjYFwTNWKt | |
| # vars.PROJECT_OWNER = FastLED | |
| # vars.PROJECT_NUMBER = 1 | |
| # secrets.PROJECT_APP_PRIVATE_KEY = <PEM contents> | |
| # | |
| # To rotate the App's private key: | |
| # 1. On https://github.com/organizations/FastLED/settings/apps generate new key | |
| # 2. For each repo: gh secret set PROJECT_APP_PRIVATE_KEY --repo FastLED/<repo> < new.pem | |
| # 3. Revoke the old key in the App settings | |
| on: | |
| issues: | |
| types: [opened] | |
| pull_request: | |
| types: [opened] | |
| env: | |
| FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true" | |
| # pull_request (not pull_request_target) — fork PRs run in the fork's context | |
| # without access to PROJECT_APP_PRIVATE_KEY, so they simply won't be | |
| # auto-added. That is an intentional security trade-off: pull_request_target | |
| # would run with base-repo secrets against fork-authored metadata, which is a | |
| # known exfiltration vector even when no code is checked out. | |
| permissions: | |
| contents: read | |
| pull-requests: read | |
| jobs: | |
| add: | |
| runs-on: ubuntu-latest | |
| if: ${{ vars.PROJECT_APP_CLIENT_ID != '' && vars.PROJECT_OWNER != '' }} | |
| steps: | |
| - name: Generate App token | |
| id: app-token | |
| continue-on-error: true | |
| uses: actions/create-github-app-token@v3 | |
| with: | |
| client-id: ${{ vars.PROJECT_APP_CLIENT_ID }} | |
| private-key: ${{ secrets.PROJECT_APP_PRIVATE_KEY }} | |
| owner: ${{ vars.PROJECT_OWNER }} | |
| - name: App not installed — skipping project sync | |
| if: ${{ steps.app-token.outcome != 'success' }} | |
| run: | | |
| echo "::warning::FastLED Project Sync App is not installed on '${{ vars.PROJECT_OWNER }}'." | |
| echo "::warning::Install it at https://github.com/organizations/${{ vars.PROJECT_OWNER }}/settings/installations to enable auto-add-to-project." | |
| - name: Add to project | |
| if: ${{ steps.app-token.outcome == 'success' }} | |
| uses: actions/add-to-project@v1.0.2 | |
| with: | |
| project-url: https://github.com/orgs/${{ vars.PROJECT_OWNER }}/projects/${{ vars.PROJECT_NUMBER }} | |
| github-token: ${{ steps.app-token.outputs.token }} |
🧰 Tools
🪛 actionlint (1.7.12)
[error] 1-1: "jobs" section is missing in workflow
(syntax-check)
[error] 1-1: "on" section is missing in workflow
(syntax-check)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/add-to-project.yml at line 1, The workflow file was
flattened onto a single line breaking YAML structure; restore proper YAML by
putting top-level keys (name, on, env, permissions, jobs) each on their own
lines with correct indentation, re-indent the jobs.add block and its steps, and
ensure the step with id "app-token" and the "Add to project" step (uses:
actions/add-to-project@v1.0.2) are nested under jobs -> add -> steps as a
sequence; validate with a YAML linter/actionlint before committing.
Use a neutral skip warning.
On fork PRs, pull_request runs without secrets.PROJECT_APP_PRIVATE_KEY, so create-github-app-token is expected to fail even when the App is installed correctly. The current warning mislabels that expected path as an installation problem.
📝 Proposed fix
- - name: App not installed — skipping project sync
+ - name: App token unavailable — skipping project sync
if: ${{ steps.app-token.outcome != 'success' }}
run: |
- echo "::warning::FastLED Project Sync App is not installed on '${{ vars.PROJECT_OWNER }}'."
- echo "::warning::Install it at https://github.com/organizations/${{ vars.PROJECT_OWNER }}/settings/installations to enable auto-add-to-project."
+ echo "::warning::Skipping project sync because the App token could not be created in this workflow context."🧰 Tools
🪛 actionlint (1.7.12)
[error] 1-1: "jobs" section is missing in workflow
(syntax-check)
[error] 1-1: "on" section is missing in workflow
(syntax-check)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/add-to-project.yml at line 1, The skip warning message in
the workflow step named "App not installed — skipping project sync" incorrectly
asserts the App is not installed when actions/create-github-app-token (step id
app-token) fails; update that step's run output to a neutral message like
"Skipping project sync: unable to create App token (this can occur for fork PRs
or when the private key secret is unavailable)" and optionally include the step
outcome to aid debugging, so replace the current install-focused warnings with a
neutral skip explanation referencing the app-token creation failure.
Summary
pull_request_targettopull_requestValidation
Summary by CodeRabbit