Skip to content
Merged
Show file tree
Hide file tree
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
7 changes: 7 additions & 0 deletions .github/workflows/upgrade.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,13 @@ jobs:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PAT_TOKEN: ${{ secrets.PAT_TOKEN }}
SKIP_HOME_MANAGER_SWITCH: "true"
- name: Cancel stale runs on upgrade branch
if: github.event_name != 'pull_request'
run: |
gh run list --branch chore/upgrade --status queued --json databaseId -q '.[].databaseId' | xargs -rn1 gh run cancel || true

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2: These list/cancel commands have no --workflow filter, so they cancel queued/in-progress runs of all workflows whose head branch is chore/upgrade, not just the upgrade runs this change is about. If an unrelated workflow (e.g. shell/renovate) has a legitimate in-progress run on that PR branch, it gets cancelled and reports a 'cancelled' (non-passing) check, which can itself block auto-merge. Scope both pipelines to this workflow with --workflow upgrade.yml unless broader cancellation is deliberate.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .github/workflows/upgrade.yml, line 46:

<comment>These list/cancel commands have no `--workflow` filter, so they cancel queued/in-progress runs of *all* workflows whose head branch is chore/upgrade, not just the upgrade runs this change is about. If an unrelated workflow (e.g. shell/renovate) has a legitimate in-progress run on that PR branch, it gets cancelled and reports a 'cancelled' (non-passing) check, which can itself block auto-merge. Scope both pipelines to this workflow with `--workflow upgrade.yml` unless broader cancellation is deliberate.</comment>

<file context>
@@ -40,6 +40,13 @@ jobs:
+      - name: Cancel stale runs on upgrade branch
+        if: github.event_name != 'pull_request'
+        run: |
+          gh run list --branch chore/upgrade --status queued --json databaseId -q '.[].databaseId' | xargs -rn1 gh run cancel || true
+          gh run list --branch chore/upgrade --status in_progress --json databaseId -q '.[].databaseId' | xargs -rn1 gh run cancel || true
+        env:
</file context>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2: The cancellation only covers up to the default gh run list result limit (default 30) per status. If the orphaned/queued accumulation this step is meant to clear exceeds that many runs, the remainder stay queued/in-progress and can still block auto-merge — the exact failure this change targets. Add an explicit --limit (e.g. --limit 1000) to both list-cancel pipelines.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .github/workflows/upgrade.yml, line 46:

<comment>The cancellation only covers up to the default `gh run list` result limit (default 30) per status. If the orphaned/queued accumulation this step is meant to clear exceeds that many runs, the remainder stay queued/in-progress and can still block auto-merge — the exact failure this change targets. Add an explicit `--limit` (e.g. `--limit 1000`) to both list-cancel pipelines.</comment>

<file context>
@@ -40,6 +40,13 @@ jobs:
+      - name: Cancel stale runs on upgrade branch
+        if: github.event_name != 'pull_request'
+        run: |
+          gh run list --branch chore/upgrade --status queued --json databaseId -q '.[].databaseId' | xargs -rn1 gh run cancel || true
+          gh run list --branch chore/upgrade --status in_progress --json databaseId -q '.[].databaseId' | xargs -rn1 gh run cancel || true
+        env:
</file context>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2: This new step can cancel the very workflow run that is executing it. Most triggers are safe (push→main, schedule→default branch), but workflow_dispatch lets users select any ref, including chore/upgrade. When dispatched on that branch, github.ref is chore/upgrade, so gh run list --branch chore/upgrade --status in_progress will match the current run and cancel it mid-execution, killing the upgrade before Create Pull Request/Enable Auto-Merge run. Consider adding --exclude-current to the gh run list invocations so the step only cancels other stale runs and never itself.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .github/workflows/upgrade.yml, line 46:

<comment>This new step can cancel the very workflow run that is executing it. Most triggers are safe (push→main, schedule→default branch), but `workflow_dispatch` lets users select any ref, including `chore/upgrade`. When dispatched on that branch, `github.ref` is `chore/upgrade`, so `gh run list --branch chore/upgrade --status in_progress` will match the current run and cancel it mid-execution, killing the upgrade before `Create Pull Request`/`Enable Auto-Merge` run. Consider adding `--exclude-current` to the `gh run list` invocations so the step only cancels other stale runs and never itself.</comment>

<file context>
@@ -40,6 +40,13 @@ jobs:
+      - name: Cancel stale runs on upgrade branch
+        if: github.event_name != 'pull_request'
+        run: |
+          gh run list --branch chore/upgrade --status queued --json databaseId -q '.[].databaseId' | xargs -rn1 gh run cancel || true
+          gh run list --branch chore/upgrade --status in_progress --json databaseId -q '.[].databaseId' | xargs -rn1 gh run cancel || true
+        env:
</file context>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2: The || true here swallows all failures from gh run list/gh run cancel, including auth/API errors, not just the expected race where a run finishes before it can be cancelled. If PAT_TOKEN lacks actions: write or the API call fails, stale runs will silently remain active while the workflow proceeds to create the PR, defeating the purpose of this step.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .github/workflows/upgrade.yml, line 46:

<comment>The `|| true` here swallows all failures from `gh run list`/`gh run cancel`, including auth/API errors, not just the expected race where a run finishes before it can be cancelled. If `PAT_TOKEN` lacks `actions: write` or the API call fails, stale runs will silently remain active while the workflow proceeds to create the PR, defeating the purpose of this step.</comment>

<file context>
@@ -40,6 +40,13 @@ jobs:
+      - name: Cancel stale runs on upgrade branch
+        if: github.event_name != 'pull_request'
+        run: |
+          gh run list --branch chore/upgrade --status queued --json databaseId -q '.[].databaseId' | xargs -rn1 gh run cancel || true
+          gh run list --branch chore/upgrade --status in_progress --json databaseId -q '.[].databaseId' | xargs -rn1 gh run cancel || true
+        env:
</file context>

gh run list --branch chore/upgrade --status in_progress --json databaseId -q '.[].databaseId' | xargs -rn1 gh run cancel || true
Comment on lines +46 to +47

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -eu
printf '%s\n' '--- workflow excerpt ---'
cat -n .github/workflows/upgrade.yml | sed -n '1,120p'
printf '%s\n' '--- workflow references ---'
rg -n --glob '.github/workflows/*.yml' --glob '.github/workflows/*.yaml' \
  'chore/upgrade|gh run (list|cancel)|permissions:|workflow_dispatch|schedule|pull_request|push:' .github/workflows

Repository: shunkakinoki/dotfiles

Length of output: 5894


🌐 Web query:

GitHub CLI gh run list --branch --status --json databaseId xargs gh run cancel exit codes documentation

💡 Result:

To list and cancel GitHub Actions workflow runs using the GitHub CLI (gh), you can chain commands together using xargs. The most efficient way to achieve this is by filtering the runs to get only their database IDs and passing them to the cancellation command [1][2]. Command Pattern A common and effective pattern for cancelling multiple workflow runs is: gh run list --branch --status --json databaseId -q '.[].databaseId' | xargs -I {} gh run cancel {} Explanation of Components: 1. gh run list: Lists recent workflow runs [3][4]. - --branch : Filters runs by the specified branch [3][4]. - --status : Filters runs by their state (e.g., queued, in_progress) [3][4]. - --json databaseId: Requests the output in JSON format, specifically including the databaseId field [3][5]. - -q '.[].databaseId': Uses a jq expression to extract only the database IDs from the JSON output [3][2]. 2. xargs -I {}: Takes the list of IDs from the previous command and passes each one as an argument to the subsequent command [1][2]. 3. gh run cancel {}: The command to cancel the workflow run associated with the provided ID [6][7]. Exit Codes for gh run cancel According to standard GitHub CLI documentation, the exit codes for the gh run cancel command are [8][9]: - 0: Successful execution. - 1: Error. - 2: Command canceled. - 4: Authentication required. Note that while these are the documented standard codes, specific environments or versions might occasionally exhibit additional behaviors [8][9]. It is recommended to ensure you are authenticated with the appropriate permissions (actions: write) before executing these commands [7]. If you encounter a large number of runs, you may also want to consider using the -P or --max-procs option with xargs to process cancellations in parallel, which can significantly speed up the operation [10].

Citations:


🏁 Script executed:

#!/bin/bash
set -eu
printf '%s\n' '--- workflow action and branch triggers ---'
for f in $(git ls-files '.github/workflows/*'); do
  printf '\n--- %s ---\n' "$f"
  sed -n '1,35p' "$f"
done
printf '%s\n' '--- repository references to PAT_TOKEN and upgrade branch ---'
rg -n 'PAT_TOKEN|chore/upgrade|create-pull-request|gh pr merge' .github Makefile README.md 2>/dev/null || true
printf '%s\n' '--- local command availability ---'
command -v gh || true
command -v xargs || true

Repository: shunkakinoki/dotfiles

Length of output: 10231


🏁 Script executed:

#!/bin/bash
set -eu
printf '%s\n' '--- gh run cancel help ---'
gh run cancel --help
printf '%s\n' '--- gh run list help ---'
gh run list --help
printf '%s\n' '--- shell pipeline behavior ---'
set +e
false | xargs -r true
printf 'pipeline_without_pipefail=%s\n' "$?"
set -o pipefail
false | xargs -r true
printf 'pipeline_with_pipefail=%s\n' "$?"

Repository: shunkakinoki/dotfiles

Length of output: 2925


🌐 Web query:

site:cli.github.com/manual/gh_run_cancel gh run cancel completed run error exit status

💡 Result:

When you attempt to use the gh run cancel command on a workflow run that has already been completed, the GitHub CLI may return a non-zero exit status, typically indicating that the operation could not be performed [1]. The gh run cancel command is designed to cancel an active or in-progress workflow run [1]. If a run is already in a terminal state, such as completed, failed, or cancelled, the API request associated with the command will fail, resulting in an error reported by the CLI [1]. To handle this in automation or scripts, you should expect a non-zero exit code when targeting completed runs and can suppress the error output if necessary using standard shell redirection, such as: gh run cancel 2>/dev/null || echo "Run already completed or cannot be cancelled."

Citations:


🌐 Web query:

site:docs.github.com GitHub REST actions workflow runs cancel permissions actions write

💡 Result:

To cancel a GitHub Actions workflow run using the REST API, you must have the appropriate permissions. For GitHub Apps and fine-grained personal access tokens, you need the actions: write repository permission [1][2]. This permission allows you to cancel, re-run, or force-cancel workflow runs using the following API endpoints [3][4][1]: POST /repos/{owner}/{repo}/actions/runs/{run_id}/cancel POST /repos/{owner}/{repo}/actions/runs/{run_id}/force-cancel When using GITHUB_TOKEN within a workflow, you must explicitly set the permissions in your workflow YAML file to include actions: write [2]. For example: permissions: actions: write Without this configuration, the GITHUB_TOKEN will not have the necessary access to programmatically cancel workflow runs [2]. OAuth tokens and classic personal access tokens require the repo scope [3][4].

Citations:


Do not blanket-suppress cleanup errors. Remove || true. It hides gh run list and gh run cancel failures, including authentication and API errors. Tolerate only the expected race where a run completes before cancellation; report or fail on all other errors. Ensure PAT_TOKEN has actions: write, or stale runs can remain active while the workflow creates the pull request.

🤖 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/upgrade.yml around lines 46 - 47, Update the queued and
in_progress cleanup commands in the workflow to remove blanket `|| true`
suppression. Preserve tolerance only for the expected race where a run finishes
before cancellation, while allowing authentication, API, and other `gh run list`
or `gh run cancel` failures to report or fail; also ensure the PAT_TOKEN
configuration grants `actions: write` so active stale runs can be cancelled.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -eu
printf '%s\n' '--- workflow files ---'
git ls-files '.github/workflows/*'
printf '%s\n' '--- upgrade workflow ---'
cat -n .github/workflows/upgrade.yml
printf '%s\n' '--- related identifiers ---'
rg -n --glob '.github/workflows/**' --glob '*.yml' --glob '*.yaml' \
  'chore/upgrade|upgrade\.yml|workflow_dispatch|schedule:|pull_request|auto-merge|gh run list|gh run cancel' .

Repository: shunkakinoki/dotfiles

Length of output: 3501


🏁 Script executed:

#!/bin/bash
set -u
printf '%s\n' '--- workflow triggers and names ---'
for f in $(git ls-files '.github/workflows/*'); do
  printf '%s\n' "--- $f"
  sed -n '1,35p' "$f" | grep -E '^(name:|on:|  [a-zA-Z_-]+:|    - |      - )' || true
done

printf '%s\n' '--- gh availability and help ---'
if command -v gh >/dev/null 2>&1; then
  gh --version | head -n 1
  gh run list --help | sed -n '1,140p'
else
  echo 'gh is unavailable'
fi

printf '%s\n' '--- public Actions metadata ---'
if command -v gh >/dev/null 2>&1; then
  gh api repos/shunkakinoki/dotfiles/actions/workflows --jq '.workflows[] | [.id,.name,.path,.state] | `@tsv`' || true
  gh api 'repos/shunkakinoki/dotfiles/actions/runs?branch=chore%2Fupgrade&status=queued&per_page=100' \
    --jq '.workflow_runs[] | [.id,.name,.path,.event,.head_branch,.status,.conclusion] | `@tsv`' || true
  gh api 'repos/shunkakinoki/dotfiles/actions/runs?branch=chore%2Fupgrade&status=in_progress&per_page=100' \
    --jq '..workflow_runs[] | [.id,.name,.path,.event,.head_branch,.status,.conclusion] | `@tsv`' || true
else
  curl -fsSL 'https://api.github.com/repos/shunkakinoki/dotfiles/actions/workflows?per_page=100' \
    -H 'Accept: application/vnd.github+json' | jq -r '.workflows[] | [.id,.name,.path,.state] | `@tsv`' || true
fi

printf '%s\n' '--- pipeline-selection model ---'
python3 - <<'PY'
import json
runs = [
    {"databaseId": 101, "workflowName": "Upgrade", "workflowPath": ".github/workflows/upgrade.yml",
     "headBranch": "chore/upgrade", "status": "queued"},
    {"databaseId": 102, "workflowName": "Other", "workflowPath": ".github/workflows/other.yml",
     "headBranch": "chore/upgrade", "status": "queued"},
    {"databaseId": 103, "workflowName": "Upgrade", "workflowPath": ".github/workflows/upgrade.yml",
     "headBranch": "chore/upgrade", "status": "in_progress"},
]
for status in ("queued", "in_progress"):
    selected = [r["databaseId"] for r in runs if r["headBranch"] == "chore/upgrade" and r["status"] == status]
    print(status, json.dumps(selected))
PY

Repository: shunkakinoki/dotfiles

Length of output: 7596


🏁 Script executed:

#!/bin/bash
set -u
repo='shunkakinoki/dotfiles'

printf '%s\n' '--- pull requests for chore/upgrade ---'
gh pr list -R "$repo" --head chore/upgrade --state all \
  --json number,state,title,headRefName,baseRefName,statusCheckRollup \
  --limit 20 || true

printf '%s\n' '--- queued and in-progress runs on chore/upgrade ---'
for status in queued in_progress; do
  gh api "repos/$repo/actions/runs?branch=chore%2Fupgrade&status=$status&per_page=100" \
    --jq '.workflow_runs[] | [.id,.name,.path,.event,.head_branch,.head_sha,.status,.conclusion] | `@tsv`' || true
done

printf '%s\n' '--- Upgrade workflow runs ---'
gh run list -R "$repo" --workflow upgrade.yml --limit 100 \
  --json databaseId,event,headBranch,headSha,status,conclusion,createdAt,displayTitle \
  --jq '.[] | [.databaseId,.event,.headBranch,.headSha,.status,.conclusion,.createdAt,.displayTitle] | `@tsv`' || true

printf '%s\n' '--- branch-associated check runs ---'
sha="$(gh api "repos/$repo/git/ref/heads/chore%2Fupgrade" --jq '.object.sha' 2>/dev/null || true)"
if [ -n "$sha" ]; then
  gh api "repos/$repo/commits/$sha/check-runs?per_page=100" \
    --jq '.check_runs[] | [.id,.name,.status,.conclusion,.app.slug] | `@tsv`' || true
else
  echo 'chore/upgrade branch is not currently available'
fi

Repository: shunkakinoki/dotfiles

Length of output: 50378


🏁 Script executed:

#!/bin/bash
set -u
repo='shunkakinoki/dotfiles'

printf '%s\n' '--- required status checks on main ---'
gh api "repos/$repo/branches/main/protection/required_status_checks" \
  --jq '{contexts,checks}' 2>&1 || true

printf '%s\n' '--- compact Upgrade runs ---'
gh api "repos/$repo/actions/workflows/upgrade.yml/runs?per_page=100" \
  --jq '.workflow_runs[] | [.id,.event,.head_branch,.status,.conclusion,.created_at] | `@tsv`' \
  | head -n 30 || true

Repository: shunkakinoki/dotfiles

Length of output: 2947


Scope cancellation to upgrade.yml.

Lines 46–47 filter only by chore/upgrade. They can cancel queued or in-progress checks from unrelated workflows. Add the --workflow upgrade.yml filter and exclude ${{ github.run_id }} before cancellation.

🤖 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/upgrade.yml around lines 46 - 47, Update both `gh run
list` cancellation commands in the upgrade workflow to filter with `--workflow
upgrade.yml` and exclude `${{ github.run_id }}` from the selected database IDs
before invoking `gh run cancel`, preserving cancellation of other queued and
in-progress upgrade workflow runs.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Cleanup is capped by gh run list's default limit: gh run list returns at most ~20 rows per call unless --limit is set. If the stacking problem this step is meant to solve ever produces more than that many stale runs on chore/upgrade, the overflow stays queued/in-progress and can still block auto-merge — the exact failure this change targets. Add --limit 1000 (or similar) to both gh run list calls.

env:
GH_TOKEN: ${{ secrets.PAT_TOKEN }}
- name: Create Pull Request
if: github.event_name != 'pull_request'
id: cpr
Expand Down
3 changes: 1 addition & 2 deletions spec/hermes_hydrate_spec.sh
Original file line number Diff line number Diff line change
Expand Up @@ -196,9 +196,8 @@ End
It 'hydrates the default Mixture-of-Agents models from the canonical model list'
When run bash -c "sed -n '/^moa:/,/^credential_pool_strategies:/p' '$PWD/config/hermes/config.template.yaml'"
The output should include 'provider: cliproxy'
The output should include 'model: deepseek-v4-pro'
The output should include 'model: minimax-m3'
The output should include 'model: deepseek-v4-flash'
The output should include 'model: minimax-m3'
The output should not include 'opus'
End
End
Expand Down
Loading