Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 106 additions & 0 deletions .github/workflows/ci-auto-fix.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
name: Auto-fix CI failures

on:
workflow_run:
workflows:
- Continuous Integration
types:
- completed

permissions:
contents: write
pull-requests: write

jobs:
auto-fix:
name: Refresh licensed cache and bundle
if: >-
github.event.workflow_run.event == 'pull_request' &&
github.event.workflow_run.conclusion == 'failure'
Comment on lines +17 to +19
Copy link

Copilot AI Jan 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The workflow runs on all CI failures, not just license or bundle related failures. This could result in unnecessary workflow runs and commits for failures unrelated to licenses or bundles. Consider adding logic to check if the failure is actually related to licenses or bundles before attempting fixes, or document this behavior if it's intentional.

This issue also appears in the following locations of the same file:

  • line 17

Copilot uses AI. Check for mistakes.
runs-on: ubuntu-latest
env:
PR_NUMBER: ${{ github.event.workflow_run.pull_requests[0].number }}
Copy link

Copilot AI Jan 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The workflow doesn't handle the case where github.event.workflow_run.pull_requests array is empty. If the workflow_run is not associated with a pull request, PR_NUMBER will be empty, and subsequent steps will fail or behave unexpectedly. Consider adding a check to ensure the array is not empty before proceeding.

Suggested change
PR_NUMBER: ${{ github.event.workflow_run.pull_requests[0].number }}

Copilot uses AI. Check for mistakes.
HEAD_REPO: ${{ github.event.workflow_run.head_repository.full_name }}
HEAD_BRANCH: ${{ github.event.workflow_run.head_branch }}
steps:
- name: Skip forks
id: repo-check
run: |
if [ "${HEAD_REPO}" != "${GITHUB_REPOSITORY}" ]; then
echo "same_repo=false" >> "$GITHUB_OUTPUT"
echo "Pull request comes from a fork; skipping auto-fix."
else
echo "same_repo=true" >> "$GITHUB_OUTPUT"
fi

- name: Checkout PR branch
if: steps.repo-check.outputs.same_repo == 'true'
uses: actions/checkout@v5
with:
repository: ${{ env.HEAD_REPO }}
ref: ${{ env.HEAD_BRANCH }}
token: ${{ secrets.GITHUB_TOKEN }}
fetch-depth: 0

- name: Setup Node.js
if: steps.repo-check.outputs.same_repo == 'true'
uses: actions/setup-node@v4
with:
node-version-file: .node-version
cache: npm

- name: Setup Ruby
if: steps.repo-check.outputs.same_repo == 'true'
uses: ruby/setup-ruby@v1
with:
ruby-version: '3.3'
Copy link

Copilot AI Jan 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Ruby version is hardcoded to '3.3', but the existing licensed.yml workflow uses 'ruby' which automatically detects the version from .ruby-version or .tool-versions files. Consider using 'ruby' for consistency with the existing workflow, or ensure both workflows use the same explicit version.

Suggested change
ruby-version: '3.3'
ruby-version: 'ruby'

Copilot uses AI. Check for mistakes.

- name: Install licensed
Comment on lines +52 to +58

Check failure

Code scanning / CodeQL

Checkout of untrusted code in a privileged context Critical

Potential execution of untrusted code on a privileged workflow (
workflow_run
)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I wonder if there's a good way to do this. The workflow is mirroring the manual steps a person has to take on their own computer or in a codespace today.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Locking the workflow down to only run for PRs authored by users with write/admin permission on the repo + Dependabot is the advice I got from our security folks.

if: steps.repo-check.outputs.same_repo == 'true'
run: gem install licensed
Copy link

Copilot AI Jan 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider using the licensee/setup-licensed action instead of manually installing licensed via gem, as this is consistent with the existing licensed.yml workflow and provides better version management and caching. The existing workflow uses licensee/setup-licensed@v1.3.2 with version: 4.x.

Suggested change
run: gem install licensed
uses: licensee/setup-licensed@v1.3.2
with:
version: 4.x

Copilot uses AI. Check for mistakes.

- name: Install npm dependencies
if: steps.repo-check.outputs.same_repo == 'true'
run: npm install
Copy link

Copilot AI Jan 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The step uses npm install which can update package-lock.json, but the other workflows in this repository use npm ci which provides a clean, reproducible install from the existing package-lock.json. Consider using npm ci for consistency, unless the intention is to allow package-lock.json updates as part of the auto-fix.

Suggested change
run: npm install
run: npm ci

Copilot uses AI. Check for mistakes.

- name: Update licensed cache
Comment on lines +62 to +66

Check failure

Code scanning / CodeQL

Checkout of untrusted code in a privileged context Critical

Potential execution of untrusted code on a privileged workflow (
workflow_run
)
if: steps.repo-check.outputs.same_repo == 'true'
run: licensed cache

- name: Commit licensed cache changes
if: steps.repo-check.outputs.same_repo == 'true'
env:
HEAD_REPO: ${{ env.HEAD_REPO }}
HEAD_BRANCH: ${{ env.HEAD_BRANCH }}
run: |
if git diff --quiet; then
Copy link

Copilot AI Jan 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The git diff --quiet command only checks unstaged changes, but licensed cache may create new untracked files. This check should use git diff --quiet && git diff --cached --quiet && [ -z "$(git ls-files --others --exclude-standard)" ] or alternatively git status --porcelain to properly detect all changes including untracked files.

This issue also appears in the following locations of the same file:

  • line 97

Copilot uses AI. Check for mistakes.
echo "No licensed cache changes to commit."
exit 0
fi

git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add -A
Copy link

Copilot AI Jan 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The git add -A command stages all changes in the entire repository. Since this step is specifically for committing licensed cache changes, it would be safer and more explicit to use git add .licenses/ to only stage the licensed cache directory. This prevents accidentally committing unrelated changes and makes the commit's intent clearer.

Suggested change
git add -A
git add .licenses/

Copilot uses AI. Check for mistakes.
git commit -m "chore: refresh licensed cache"
git push https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${HEAD_REPO}.git HEAD:${HEAD_BRANCH}
Copy link

Copilot AI Jan 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The push operation on line 85 could fail if another commit was pushed to the branch between the checkout and this push, resulting in a non-fast-forward error. Consider adding retry logic or pulling before pushing, or document that manual intervention may be needed in such cases.

This issue also appears in the following locations of the same file:

  • line 106

Copilot uses AI. Check for mistakes.

- name: Rebuild bundle
if: steps.repo-check.outputs.same_repo == 'true'
run: npm run bundle

- name: Commit bundle changes
Comment on lines +87 to +91

Check failure

Code scanning / CodeQL

Checkout of untrusted code in a privileged context Critical

Potential execution of untrusted code on a privileged workflow (
workflow_run
)
if: steps.repo-check.outputs.same_repo == 'true'
env:
HEAD_REPO: ${{ env.HEAD_REPO }}
HEAD_BRANCH: ${{ env.HEAD_BRANCH }}
run: |
if git diff --quiet; then
echo "No bundle changes to commit."
exit 0
fi

git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add -A
git commit -m "chore: rebuild bundle"
git push https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${HEAD_REPO}.git HEAD:${HEAD_BRANCH}
Loading