Skip to content

feat: add actions-updater agentic workflow#18693

Closed
salmanmkc wants to merge 1 commit intogithub:mainfrom
salmanmkc:add-actions-updater-workflow
Closed

feat: add actions-updater agentic workflow#18693
salmanmkc wants to merge 1 commit intogithub:mainfrom
salmanmkc:add-actions-updater-workflow

Conversation

@salmanmkc
Copy link

Summary

Adds an agentic workflow (actions-updater.md) that scans .md workflow source files for outdated GitHub Actions and creates issues, similar to how Dependabot creates alerts for outdated dependencies.

How it works

Deterministic pre-filter (no agent tokens burned)

A check_outdated job runs first as regular GitHub Actions:

  1. Checks out .github/workflows/ (sparse checkout)
  2. Extracts all uses: directives from .md files with regex
  3. Resolves SHA-pinned refs to version tags (via comments or API)
  4. Checks latest versions via gh api
  5. Compares current vs latest versions
  6. Sets has_outdated=true/false output

The agent only runs if outdated actions are detected - zero token spend when everything is current.

Agent (only runs when needed)

  • Creates one issue per outdated action (grouped by action, not per file)
  • Each issue includes: current version, latest version, affected .md files, update instructions
  • Detects whether files use version tags or SHAs and tailors instructions accordingly
  • Issues include a hint to assign to CCA for automatic PR creation
  • Reminds to run gh aw compile after updates

Smart version detection

  • Tag refs - compared directly to latest release
  • SHA refs - resolved to tags via inline comments or GitHub API, then compared
  • Only scans .md files - ignores .yml/.lock.yml entirely

Inputs (workflow_dispatch)

  • repository: Target repo (owner/repo). Defaults to current repo.
  • organization: Scan all repos in an org - enables org-wide orchestration
  • dry-run: Report only, do not create issues

Schedule

Runs weekly on Monday at 6am UTC.

Copilot AI review requested due to automatic review settings February 27, 2026 13:36
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a new agentic workflow to detect outdated GitHub Action versions referenced in .md workflow sources and (when updates are found) open tracking issues for upgrades.

Changes:

  • Introduces .github/workflows/actions-updater.md with a deterministic check_outdated job that parses uses: references and checks latest tags/releases via gh api.
  • Adds an agent prompt section intended to create one issue per outdated action (optionally across a repository or organization) with update instructions and grouping rules.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +327 to +328
If all actions are up to date, create a single informational issue noting that all actions are current.

Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

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

The agent instructions say to "create a single informational issue" when everything is up to date, but the workflow is gated by if: needs.check_outdated.outputs.has_outdated == 'true', so the agent will never run in the all-up-to-date case. Either remove this instruction, or change the gating/logic so a no-op run can still optionally create that informational issue.

Copilot uses AI. Check for mistakes.
Comment on lines +7 to +21
workflow_dispatch:
inputs:
repository:
description: "Repository to scan (format: owner/repo). Defaults to current repo."
required: false
type: string
organization:
description: "Scan all repos in an organization (overrides repository input)"
required: false
type: string
dry-run:
description: "Only report outdated actions, don't create issues"
required: false
type: boolean
default: false
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

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

check_outdated ignores the repository and organization workflow_dispatch inputs (it always checks out and scans only the current repo). With the workflow-level if: needs.check_outdated.outputs.has_outdated == 'true', running the workflow for another repo/org can incorrectly skip the agent even when targets are outdated. Either incorporate the selected target(s) into the deterministic precheck, or change the gating so the agent runs when repository/organization are provided (and the agent does the scanning).

Copilot uses AI. Check for mistakes.
Comment on lines +87 to +90
# Extract unique action@version pairs from .md workflow files
grep -rhn 'uses:' .github/workflows/*.md 2>/dev/null \
| sed -n 's/.*uses:[[:space:]]*\([^@#"'"'"'[:space:]]*\)@\([^#"'"'"'[:space:]]*\).*/\1@\2/p' \
| sort -u > /tmp/current-actions.txt
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

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

The extractor only scans .github/workflows/*.md (non-recursive), so it misses action references in nested source files like .github/workflows/shared/**/*.md that can be imported into workflows. Consider scanning recursively (e.g., grep -r --include='*.md' .github/workflows) so the check covers all .md workflow sources.

Copilot uses AI. Check for mistakes.
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
# Extract unique action@version pairs from .md workflow files
grep -rhn 'uses:' .github/workflows/*.md 2>/dev/null \
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

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

This grep scans the entire .md file contents, including the markdown prompt section after the frontmatter delimiter. In this file that includes example lines like uses: {action}@{old_version}, which will be picked up as a fake action and trigger unnecessary API calls/"SKIP" noise. Consider limiting parsing to the YAML frontmatter section only (up to the second ---), or otherwise excluding fenced code blocks / the prompt body from the uses: extraction.

Suggested change
grep -rhn 'uses:' .github/workflows/*.md 2>/dev/null \
# Only consider the YAML frontmatter (before the second ---) to avoid prompt/example noise
find .github/workflows -name '*.md' -type f -print0 2>/dev/null \
| while IFS= read -r -d '' file; do
awk 'BEGIN{d=0} /^---[[:space:]]*$/{d++; if (d>=2) exit} {print}' "$file"
done \

Copilot uses AI. Check for mistakes.
Comment on lines +165 to +172
if [ "$OUTDATED" -gt 0 ]; then
echo "has_outdated=true" >> "$GITHUB_OUTPUT"
# Truncate to fit output limits
echo "outdated_list=$(printf '%b' "$OUTDATED_LIST" | head -50)" >> "$GITHUB_OUTPUT"
else
echo "has_outdated=false" >> "$GITHUB_OUTPUT"
fi
echo "outdated_count=${OUTDATED}" >> "$GITHUB_OUTPUT"
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

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

outdated_list is written to $GITHUB_OUTPUT using name=value, but the value is multi-line (OUTDATED_LIST accumulates \n). Multi-line outputs must use the <<EOF delimiter form; otherwise this can break output parsing and fail the step. Update this to use the documented multi-line output syntax when emitting outdated_list.

Copilot uses AI. Check for mistakes.
Comment on lines +114 to +120
resolved=$(gh api "repos/${action}/git/matching-refs/tags" --jq '.[].ref' 2>/dev/null | while read ref; do
tag_sha=$(gh api "repos/${action}/git/ref/${ref#refs/}" --jq '.object.sha' 2>/dev/null)
if [ "$tag_sha" = "$current" ]; then
echo "${ref#refs/tags/}"
break
fi
done | head -1)
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

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

The SHA→tag resolution compares the input SHA to git/ref's .object.sha, which is the tag object's SHA for annotated tags (not the commit SHA). This will fail to resolve many real tags. To make this reliable, dereference annotated tags by checking .object.type and, when it's tag, follow up with git/tags/{sha} to compare the underlying commit SHA (or use an endpoint that returns the peeled commit).

Copilot uses AI. Check for mistakes.

- **Repository input**: `${{ github.event.inputs.repository || github.repository }}`
- **Organization input**: `${{ github.event.inputs.organization }}`
- **Dry run**: `${{ github.event.inputs.dry-run }}`
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

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

The workflow_dispatch input name dry-run is referenced as ${{ github.event.inputs.dry-run }}. In GitHub Actions expressions, keys with hyphens generally require bracket notation (e.g., github.event.inputs['dry-run']) or using an input name without - (like dry_run). As written, this expression is likely to fail to evaluate and may break the run/compile.

Suggested change
- **Dry run**: `${{ github.event.inputs.dry-run }}`
- **Dry run**: `${{ github.event.inputs['dry-run'] }}`

Copilot uses AI. Check for mistakes.
Adds an agentic workflow that scans .md workflow source files for
outdated GitHub Actions and creates issues (like Dependabot).

- Deterministic pre-filter: checks versions via gh api before invoking agent
- Agent only runs when outdated actions are detected (saves tokens)
- Creates one issue per outdated action with update instructions
- Supports workflow_dispatch with repo/org inputs for org-wide scanning
- Issues can be assigned to CCA for automatic PR creation
@pelikhan
Copy link
Contributor

I think gh aw update can do all this now. I'm closing but let's discuss futher later.

@pelikhan pelikhan closed this Feb 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants