From bfef03e290637ed02cd144a9b51f8b446abd0efd Mon Sep 17 00:00:00 2001 From: Muiris Woulfe Date: Mon, 20 Apr 2026 14:43:57 +0100 Subject: [PATCH 01/15] feat: add agentic workflow for CI dependency refresh MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implements the update-ci-dependencies skill via gh-aw. Triggered on Release – Initiate completion (and workflow_dispatch) so refreshed CI pins land on the release pull request automatically. --- .github/workflows/update-ci-dependencies.md | 95 +++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 .github/workflows/update-ci-dependencies.md diff --git a/.github/workflows/update-ci-dependencies.md b/.github/workflows/update-ci-dependencies.md new file mode 100644 index 000000000..669ae1d17 --- /dev/null +++ b/.github/workflows/update-ci-dependencies.md @@ -0,0 +1,95 @@ +--- +name: Update CI Dependencies +description: >- + Refreshes pinned CI/CD dependencies – SHA-pinned GitHub Actions in + .github/workflows/, task versions and 1ES template refs in + .github/azure-devops/ – and audits Node.js runtime consistency across + workflows, pipelines, package.json, and .nvmrc. Triggered when + Release – Initiate completes so updates land on the release pull request + it opens; workflow_dispatch is available as a manual retrigger while a + release pull request is open. + +on: + workflow_run: + workflows: + - "Release – Initiate" + types: + - completed + branches: + - "**" + workflow_dispatch: null + +permissions: + contents: read + pull-requests: read + actions: read + +engine: copilot + +tools: + edit: + bash: + - "git *" + - "gh api *" + - "gh pr list *" + - "gh pr view *" + - "jq *" + +checkout: + fetch: + - "*" + fetch-depth: 0 + +safe-outputs: + push-to-pull-request-branch: + target: "*" + labels: + - release + max: 1 + if-no-changes: ignore + protected-files: + policy: fallback-to-issue + exclude: + - package.json + - .nvmrc + github-token-for-extra-empty-commit: ${{ secrets.PR_METRICS_TOKEN }} +--- + +# Update CI Dependencies + +Implements the `update-ci-dependencies` skill. Read +`.github/skills/update-ci-dependencies/SKILL.md` and follow its **Process**, +**Node.js Version Consistency**, **Output Format**, and **Constraints** +sections exactly. This workflow file adds only the invocation-specific +rules below. + +## Invocation Context + +- Triggered by `Release – Initiate` completing or by a manual + `workflow_dispatch`. +- Target: the open pull request that carries the `release` label (created + by `Release – Initiate`, with title `[Autogenerated] Release v`). +- If no pull request with the `release` label is currently open, stop and + produce no output. Do not open a new pull request. + +## Invocation-Specific Overrides + +- **Commit Message**: Use `chore: refresh CI pins`, not the + dependency-class-specific message the skill suggests, because a single + invocation may span multiple classes. +- **Output Target**: Push onto the existing release pull request's branch. + The `push-to-pull-request-branch` safe output in the frontmatter handles + this – do not call `gh pr create` yourself. +- **Allowed Writes**: Only `.github/workflows/*.yml`, + `.github/azure-devops/*.yml`, `package.json`, and `.nvmrc`. Everything + outside this set is off-limits for this invocation. +- **Node.js Version**: Audit only. If values diverge, align them on the + pin from the most recently bumped file (per `git log`). Never change the + value itself from this workflow. + +## Verification + +No manual verification is required. After the push, the `Build` workflow +reruns automatically (via the empty commit made with `PR_METRICS_TOKEN`) +and re-executes Super-Linter against the modified files. Any lint or +typing failure surfaces there. From 1269fe5186526cd177923d56c6a56206a8de1c2d Mon Sep 17 00:00:00 2001 From: Muiris Woulfe Date: Mon, 20 Apr 2026 15:11:22 +0100 Subject: [PATCH 02/15] chore(ci): update CI dependencies workflow formatting - Remove quotes around workflow name for consistency. - Simplify tool command syntax by removing quotes. - Enhance documentation for clarity and structure. - Ensure Node.js version consistency across workflows and pipelines. --- .github/workflows/update-ci-dependencies.md | 154 ++++++++++++++++---- 1 file changed, 123 insertions(+), 31 deletions(-) diff --git a/.github/workflows/update-ci-dependencies.md b/.github/workflows/update-ci-dependencies.md index 669ae1d17..e4f3cd474 100644 --- a/.github/workflows/update-ci-dependencies.md +++ b/.github/workflows/update-ci-dependencies.md @@ -12,7 +12,7 @@ description: >- on: workflow_run: workflows: - - "Release – Initiate" + - Release – Initiate types: - completed branches: @@ -29,20 +29,20 @@ engine: copilot tools: edit: bash: - - "git *" - - "gh api *" - - "gh pr list *" - - "gh pr view *" - - "jq *" + - git * + - gh api * + - gh pr list * + - gh pr view * + - jq * checkout: fetch: - - "*" + - * fetch-depth: 0 safe-outputs: push-to-pull-request-branch: - target: "*" + target: * labels: - release max: 1 @@ -57,39 +57,131 @@ safe-outputs: # Update CI Dependencies -Implements the `update-ci-dependencies` skill. Read -`.github/skills/update-ci-dependencies/SKILL.md` and follow its **Process**, -**Node.js Version Consistency**, **Output Format**, and **Constraints** -sections exactly. This workflow file adds only the invocation-specific -rules below. +Refresh pinned versions in GitHub Actions workflows and Azure DevOps pipelines, +and enforce Node.js runtime consistency across workflows, pipelines, +`package.json`, and `.nvmrc`. ## Invocation Context - Triggered by `Release – Initiate` completing or by a manual `workflow_dispatch`. -- Target: the open pull request that carries the `release` label (created - by `Release – Initiate`, with title `[Autogenerated] Release v`). +- Target: the open pull request that carries the `release` label (created by + `Release – Initiate`, with title `[Autogenerated] Release v`). - If no pull request with the `release` label is currently open, stop and produce no output. Do not open a new pull request. +## Inventory + +Catalog every pinned version before editing. Use `grep` to locate each pattern. + +### GitHub Workflows + +Files under `.github/workflows/*.yml`: + +- **SHA-Pinned Actions**: `uses: owner/repo@<40-char SHA> # vX.Y.Z`. The SHA and + the trailing version comment must stay in sync. +- **Other Pinned Tools**: Literal `version:` or `ref:` values in step inputs. + +### Azure DevOps Pipelines + +Files under `.github/azure-devops/*.yml`: + +- **Task Versions**: Entries of the form `task: TaskName@N` (for example, + `Npm@1`, `UseNode@1`, `EsrpCodeSigning@6`). Only the major version is + declared; the latest minor or patch resolves at runtime. +- **Template Refs**: `ref: refs/tags/` inside `resources.repositories`. 1ES + templates use the moving `release` tag; pin a specific tag only when + compliance requires it. + +## Process + +1. Confirm a single open pull request labelled `release` with the + `[Autogenerated] Release v` title prefix exists. If none matches, stop and + produce no output. +1. For each SHA-pinned GitHub Action, resolve the latest release and tag SHA: + + ```bash + gh api repos///releases/latest --jq '.tag_name' + gh api repos///git/refs/tags/ --jq '.object.sha' + ``` + + Update the SHA and the trailing `# vX.Y.Z` comment in one edit – never one + without the other. If the tag points to an annotated tag object, dereference + it with a second `gh api` call against the tag object. + +1. For each Azure DevOps task, check the task's latest major version in the + [Azure Pipelines task reference][ado-tasks]. Bump the major version only + after reviewing its release notes and adjusting inputs accordingly. This + includes `UseNode@1` itself (the task version), but never the `version:` + input it receives. +1. For template refs, list available tags and compare with the current pin: + + ```bash + git ls-remote --tags + ``` + + The 1ES templates are hosted in Azure DevOps; authenticate via `az` if the + listing is restricted. + +1. Save changes while preserving formatting: trailing newlines, comment spacing, + and two-space indentation. + +## Node.js Version Consistency + +The pinned Node.js runtime must match everywhere it appears. This workflow does +not bump Node.js to a newer version – that is a deliberate, standalone change – +but it flags and resolves inconsistencies. + +Locate every occurrence with `grep`: + +- `.github/workflows/*.yml` – `node-version: X.Y.Z` under `actions/setup-node`. +- `.github/azure-devops/*.yml` – `UseNode@1` with `version: X.Y.Z`. +- `package.json` – `engines.node`. +- `.nvmrc` if present. + +If values diverge, align them on the single intended pin. Prefer the value +already set by the most recent deliberate bump (check `git log` on whichever +file changed most recently). Do not change the value itself. + ## Invocation-Specific Overrides -- **Commit Message**: Use `chore: refresh CI pins`, not the - dependency-class-specific message the skill suggests, because a single - invocation may span multiple classes. -- **Output Target**: Push onto the existing release pull request's branch. - The `push-to-pull-request-branch` safe output in the frontmatter handles - this – do not call `gh pr create` yourself. -- **Allowed Writes**: Only `.github/workflows/*.yml`, - `.github/azure-devops/*.yml`, `package.json`, and `.nvmrc`. Everything - outside this set is off-limits for this invocation. -- **Node.js Version**: Audit only. If values diverge, align them on the - pin from the most recently bumped file (per `git log`). Never change the - value itself from this workflow. +- **Commit Message**: Use `chore: refresh CI pins`, not a + dependency-class-specific message, because a single invocation may span + multiple classes. +- **Output Target**: Push onto the existing release pull request's branch. The + `push-to-pull-request-branch` safe output in the frontmatter handles this – do + not call `gh pr create` yourself. + +## Constraints + +- **Never Desynchronize SHA and Version Comment**: Always update both in the + same edit. +- **Never Blindly Bump an Azure DevOps Task Major Version**: Review the release + notes and adjust inputs first. +- **Never Bump the Node.js Runtime Value**: Audit only. A runtime bump is a + separate, deliberate change made elsewhere. +- **Never Duplicate a Dependabot Pull Request**: If Dependabot already has an + open pull request for an action, rebase or merge it rather than producing a + competing change. +- **Never Hard-Pin a 1ES Template Ref Without Justification**: The `release` tag + is intentionally moving. +- **Never Modify Files Outside the Allowed Set**: Only + `.github/workflows/*.yml`, `.github/azure-devops/*.yml`, `package.json`, and + `.nvmrc` may be edited. + +## Quick Reference + +| Dependency Type | Files | Update Source | +|-------------------|------------------------------|------------------------| +| GitHub Action | `.github/workflows/*.yml` | `gh api` latest tag | +| Azure DevOps Task | `.github/azure-devops/*.yml` | ADO task reference | +| 1ES Template Ref | `.github/azure-devops/*.yml` | `git ls-remote --tags` | ## Verification -No manual verification is required. After the push, the `Build` workflow -reruns automatically (via the empty commit made with `PR_METRICS_TOKEN`) -and re-executes Super-Linter against the modified files. Any lint or -typing failure surfaces there. +No manual verification is required. After the push, the `Build` workflow reruns +automatically (via the empty commit made with `PR_METRICS_TOKEN`) and +re-executes Super-Linter against the modified files. Any lint or typing failure +surfaces there. + +[ado-tasks]: https://learn.microsoft.com/azure/devops/pipelines/tasks/reference/ From c51761e6f2c856f3b9f2c2fcea6644686475bb89 Mon Sep 17 00:00:00 2001 From: Muiris Woulfe Date: Mon, 20 Apr 2026 15:19:58 +0100 Subject: [PATCH 03/15] chore: fix linting --- .github/workflows/update-ci-dependencies.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/update-ci-dependencies.md b/.github/workflows/update-ci-dependencies.md index e4f3cd474..23ca807d0 100644 --- a/.github/workflows/update-ci-dependencies.md +++ b/.github/workflows/update-ci-dependencies.md @@ -166,13 +166,13 @@ file changed most recently). Do not change the value itself. - **Never Hard-Pin a 1ES Template Ref Without Justification**: The `release` tag is intentionally moving. - **Never Modify Files Outside the Allowed Set**: Only - `.github/workflows/*.yml`, `.github/azure-devops/*.yml`, `package.json`, and - `.nvmrc` may be edited. + `.github/workflows/*.yml`, `.github/azure-devops/*.yml`, `package.json`, and + `.nvmrc` may be edited. ## Quick Reference | Dependency Type | Files | Update Source | -|-------------------|------------------------------|------------------------| +| ----------------- | ---------------------------- | ---------------------- | | GitHub Action | `.github/workflows/*.yml` | `gh api` latest tag | | Azure DevOps Task | `.github/azure-devops/*.yml` | ADO task reference | | 1ES Template Ref | `.github/azure-devops/*.yml` | `git ls-remote --tags` | From c4fd7969eb39df41556cc2b3e614e912b2320456 Mon Sep 17 00:00:00 2001 From: Muiris Woulfe Date: Mon, 20 Apr 2026 15:23:51 +0100 Subject: [PATCH 04/15] chore: add copyright header to CI dependencies workflow --- .github/workflows/update-ci-dependencies.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/update-ci-dependencies.md b/.github/workflows/update-ci-dependencies.md index 23ca807d0..1be6d4523 100644 --- a/.github/workflows/update-ci-dependencies.md +++ b/.github/workflows/update-ci-dependencies.md @@ -1,4 +1,7 @@ --- +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + name: Update CI Dependencies description: >- Refreshes pinned CI/CD dependencies – SHA-pinned GitHub Actions in From bbd42ef49910e2f3af4fcb0fee9ad8425a2ab291 Mon Sep 17 00:00:00 2001 From: Muiris Woulfe Date: Mon, 20 Apr 2026 17:09:53 +0100 Subject: [PATCH 05/15] fix: quote wildcard values in agentic workflow frontmatter Bare `*` values in `checkout.fetch` and `safe-outputs.push-to-pull-request-branch.target` were being parsed as YAML alias references, which made the frontmatter fail to load. Quoting them as `"*"` makes them valid string scalars. --- .github/workflows/update-ci-dependencies.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/update-ci-dependencies.md b/.github/workflows/update-ci-dependencies.md index 1be6d4523..c5587b781 100644 --- a/.github/workflows/update-ci-dependencies.md +++ b/.github/workflows/update-ci-dependencies.md @@ -40,12 +40,12 @@ tools: checkout: fetch: - - * + - "*" fetch-depth: 0 safe-outputs: push-to-pull-request-branch: - target: * + target: "*" labels: - release max: 1 From c634b107cd9e98e5530860ebea7fa15e5687a7df Mon Sep 17 00:00:00 2001 From: Muiris Woulfe Date: Mon, 20 Apr 2026 17:24:26 +0100 Subject: [PATCH 06/15] fix: match release PR title prefix in agentic workflow context MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `Release – Initiate` creates PRs with titles like `[Autogenerated] Release v with Package Updates`, not plain `[Autogenerated] Release v`. The `Process` section already filters on the `[Autogenerated] Release v` prefix, so align the `Invocation Context` description with that behaviour. --- .github/workflows/update-ci-dependencies.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/update-ci-dependencies.md b/.github/workflows/update-ci-dependencies.md index c5587b781..785253173 100644 --- a/.github/workflows/update-ci-dependencies.md +++ b/.github/workflows/update-ci-dependencies.md @@ -69,7 +69,7 @@ and enforce Node.js runtime consistency across workflows, pipelines, - Triggered by `Release – Initiate` completing or by a manual `workflow_dispatch`. - Target: the open pull request that carries the `release` label (created by - `Release – Initiate`, with title `[Autogenerated] Release v`). + `Release – Initiate`, with a title beginning `[Autogenerated] Release v`). - If no pull request with the `release` label is currently open, stop and produce no output. Do not open a new pull request. From a753647a121de8178c7335fba2ecd2bc9793422f Mon Sep 17 00:00:00 2001 From: Muiris Woulfe Date: Tue, 21 Apr 2026 15:51:52 +0100 Subject: [PATCH 07/15] feat: compile update-ci-dependencies agentic workflow --- .gitattributes | 1 + .github/agents/agentic-workflows.agent.md | 178 +++ .github/aw/actions-lock.json | 14 + .../workflows/update-ci-dependencies.lock.yml | 1287 +++++++++++++++++ .github/workflows/update-ci-dependencies.md | 20 +- .gitignore | 3 + 6 files changed, 1495 insertions(+), 8 deletions(-) create mode 100644 .gitattributes create mode 100644 .github/agents/agentic-workflows.agent.md create mode 100644 .github/aw/actions-lock.json create mode 100644 .github/workflows/update-ci-dependencies.lock.yml diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..c1965c216 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +.github/workflows/*.lock.yml linguist-generated=true merge=ours \ No newline at end of file diff --git a/.github/agents/agentic-workflows.agent.md b/.github/agents/agentic-workflows.agent.md new file mode 100644 index 000000000..e2e2b2b58 --- /dev/null +++ b/.github/agents/agentic-workflows.agent.md @@ -0,0 +1,178 @@ +--- +description: GitHub Agentic Workflows (gh-aw) - Create, debug, and upgrade AI-powered workflows with intelligent prompt routing +disable-model-invocation: true +--- + +# GitHub Agentic Workflows Agent + +This agent helps you work with **GitHub Agentic Workflows (gh-aw)**, a CLI extension for creating AI-powered workflows in natural language using markdown files. + +## What This Agent Does + +This is a **dispatcher agent** that routes your request to the appropriate specialized prompt based on your task: + +- **Creating new workflows**: Routes to `create` prompt +- **Updating existing workflows**: Routes to `update` prompt +- **Debugging workflows**: Routes to `debug` prompt +- **Upgrading workflows**: Routes to `upgrade-agentic-workflows` prompt +- **Creating report-generating workflows**: Routes to `report` prompt — consult this whenever the workflow posts status updates, audits, analyses, or any structured output as issues, discussions, or comments +- **Creating shared components**: Routes to `create-shared-agentic-workflow` prompt +- **Fixing Dependabot PRs**: Routes to `dependabot` prompt — use this when Dependabot opens PRs that modify generated manifest files (`.github/workflows/package.json`, `.github/workflows/requirements.txt`, `.github/workflows/go.mod`). Never merge those PRs directly; instead update the source `.md` files and rerun `gh aw compile --dependabot` to bundle all fixes +- **Analyzing test coverage**: Routes to `test-coverage` prompt — consult this whenever the workflow reads, analyzes, or reports on test coverage data from PRs or CI runs + +Workflows may optionally include: + +- **Project tracking / monitoring** (GitHub Projects updates, status reporting) +- **Orchestration / coordination** (one workflow assigning agents or dispatching and coordinating other workflows) + +## Files This Applies To + +- Workflow files: `.github/workflows/*.md` and `.github/workflows/**/*.md` +- Workflow lock files: `.github/workflows/*.lock.yml` +- Shared components: `.github/workflows/shared/*.md` +- Configuration: https://github.com/github/gh-aw/blob/v0.68.3/.github/aw/github-agentic-workflows.md + +## Problems This Solves + +- **Workflow Creation**: Design secure, validated agentic workflows with proper triggers, tools, and permissions +- **Workflow Debugging**: Analyze logs, identify missing tools, investigate failures, and fix configuration issues +- **Version Upgrades**: Migrate workflows to new gh-aw versions, apply codemods, fix breaking changes +- **Component Design**: Create reusable shared workflow components that wrap MCP servers + +## How to Use + +When you interact with this agent, it will: + +1. **Understand your intent** - Determine what kind of task you're trying to accomplish +2. **Route to the right prompt** - Load the specialized prompt file for your task +3. **Execute the task** - Follow the detailed instructions in the loaded prompt + +## Available Prompts + +### Create New Workflow +**Load when**: User wants to create a new workflow from scratch, add automation, or design a workflow that doesn't exist yet + +**Prompt file**: https://github.com/github/gh-aw/blob/v0.68.3/.github/aw/create-agentic-workflow.md + +**Use cases**: +- "Create a workflow that triages issues" +- "I need a workflow to label pull requests" +- "Design a weekly research automation" + +### Update Existing Workflow +**Load when**: User wants to modify, improve, or refactor an existing workflow + +**Prompt file**: https://github.com/github/gh-aw/blob/v0.68.3/.github/aw/update-agentic-workflow.md + +**Use cases**: +- "Add web-fetch tool to the issue-classifier workflow" +- "Update the PR reviewer to use discussions instead of issues" +- "Improve the prompt for the weekly-research workflow" + +### Debug Workflow +**Load when**: User needs to investigate, audit, debug, or understand a workflow, troubleshoot issues, analyze logs, or fix errors + +**Prompt file**: https://github.com/github/gh-aw/blob/v0.68.3/.github/aw/debug-agentic-workflow.md + +**Use cases**: +- "Why is this workflow failing?" +- "Analyze the logs for workflow X" +- "Investigate missing tool calls in run #12345" + +### Upgrade Agentic Workflows +**Load when**: User wants to upgrade workflows to a new gh-aw version or fix deprecations + +**Prompt file**: https://github.com/github/gh-aw/blob/v0.68.3/.github/aw/upgrade-agentic-workflows.md + +**Use cases**: +- "Upgrade all workflows to the latest version" +- "Fix deprecated fields in workflows" +- "Apply breaking changes from the new release" + +### Create a Report-Generating Workflow +**Load when**: The workflow being created or updated produces reports — recurring status updates, audit summaries, analyses, or any structured output posted as a GitHub issue, discussion, or comment + +**Prompt file**: https://github.com/github/gh-aw/blob/v0.68.3/.github/aw/report.md + +**Use cases**: +- "Create a weekly CI health report" +- "Post a daily security audit to Discussions" +- "Add a status update comment to open PRs" + +### Create Shared Agentic Workflow +**Load when**: User wants to create a reusable workflow component or wrap an MCP server + +**Prompt file**: https://github.com/github/gh-aw/blob/v0.68.3/.github/aw/create-shared-agentic-workflow.md + +**Use cases**: +- "Create a shared component for Notion integration" +- "Wrap the Slack MCP server as a reusable component" +- "Design a shared workflow for database queries" + +### Fix Dependabot PRs +**Load when**: User needs to close or fix open Dependabot PRs that update dependencies in generated manifest files (`.github/workflows/package.json`, `.github/workflows/requirements.txt`, `.github/workflows/go.mod`) + +**Prompt file**: https://github.com/github/gh-aw/blob/v0.68.3/.github/aw/dependabot.md + +**Use cases**: +- "Fix the open Dependabot PRs for npm dependencies" +- "Bundle and close the Dependabot PRs for workflow dependencies" +- "Update @playwright/test to fix the Dependabot PR" + +### Analyze Test Coverage +**Load when**: The workflow reads, analyzes, or reports test coverage — whether triggered by a PR, a schedule, or a slash command. Always consult this prompt before designing the coverage data strategy. + +**Prompt file**: https://github.com/github/gh-aw/blob/v0.68.3/.github/aw/test-coverage.md + +**Use cases**: +- "Create a workflow that comments coverage on PRs" +- "Analyze coverage trends over time" +- "Add a coverage gate that blocks PRs below a threshold" + +## Instructions + +When a user interacts with you: + +1. **Identify the task type** from the user's request +2. **Load the appropriate prompt** from the GitHub repository URLs listed above +3. **Follow the loaded prompt's instructions** exactly +4. **If uncertain**, ask clarifying questions to determine the right prompt + +## Quick Reference + +```bash +# Initialize repository for agentic workflows +gh aw init + +# Generate the lock file for a workflow +gh aw compile [workflow-name] + +# Debug workflow runs +gh aw logs [workflow-name] +gh aw audit + +# Upgrade workflows +gh aw fix --write +gh aw compile --validate +``` + +## Key Features of gh-aw + +- **Natural Language Workflows**: Write workflows in markdown with YAML frontmatter +- **AI Engine Support**: Copilot, Claude, Codex, or custom engines +- **MCP Server Integration**: Connect to Model Context Protocol servers for tools +- **Safe Outputs**: Structured communication between AI and GitHub API +- **Strict Mode**: Security-first validation and sandboxing +- **Shared Components**: Reusable workflow building blocks +- **Repo Memory**: Persistent git-backed storage for agents +- **Sandboxed Execution**: All workflows run in the Agent Workflow Firewall (AWF) sandbox, enabling full `bash` and `edit` tools by default + +## Important Notes + +- Always reference the instructions file at https://github.com/github/gh-aw/blob/v0.68.3/.github/aw/github-agentic-workflows.md for complete documentation +- Use the MCP tool `agentic-workflows` when running in GitHub Copilot Cloud +- Workflows must be compiled to `.lock.yml` files before running in GitHub Actions +- **Bash tools are enabled by default** - Don't restrict bash commands unnecessarily since workflows are sandboxed by the AWF +- Follow security best practices: minimal permissions, explicit network access, no template injection +- **Network configuration**: Use ecosystem identifiers (`node`, `python`, `go`, etc.) or explicit FQDNs in `network.allowed`. Bare shorthands like `npm` or `pypi` are **not** valid. See https://github.com/github/gh-aw/blob/v0.68.3/.github/aw/network.md for the full list of valid ecosystem identifiers and domain patterns. +- **Single-file output**: When creating a workflow, produce exactly **one** workflow `.md` file. Do not create separate documentation files (architecture docs, runbooks, usage guides, etc.). If documentation is needed, add a brief `## Usage` section inside the workflow file itself. diff --git a/.github/aw/actions-lock.json b/.github/aw/actions-lock.json new file mode 100644 index 000000000..73df5e9d5 --- /dev/null +++ b/.github/aw/actions-lock.json @@ -0,0 +1,14 @@ +{ + "entries": { + "actions/github-script@v9": { + "repo": "actions/github-script", + "version": "v9", + "sha": "373c709c69115d41ff229c7e5df9f8788daa9553" + }, + "github/gh-aw-actions/setup@v0.68.3": { + "repo": "github/gh-aw-actions/setup", + "version": "v0.68.3", + "sha": "ba90f2186d7ad780ec640f364005fa24e797b360" + } + } +} diff --git a/.github/workflows/update-ci-dependencies.lock.yml b/.github/workflows/update-ci-dependencies.lock.yml new file mode 100644 index 000000000..8b1a8610e --- /dev/null +++ b/.github/workflows/update-ci-dependencies.lock.yml @@ -0,0 +1,1287 @@ +# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"5196b45c82e0a498df2af601868f6c54c182e1530fc9cad58fe4a21f492b3e1d","compiler_version":"v0.68.3","strict":true,"agent_id":"copilot"} +# gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN","PR_METRICS_TOKEN"],"actions":[{"repo":"actions/checkout","sha":"de0fac2e4500dabe0009e67214ff5f5447ce83dd","version":"v6.0.2"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"373c709c69115d41ff229c7e5df9f8788daa9553","version":"v9"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"ba90f2186d7ad780ec640f364005fa24e797b360","version":"v0.68.3"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.25.20"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.25.20"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.25.20"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.2.19"},{"image":"ghcr.io/github/github-mcp-server:v0.32.0"},{"image":"node:lts-alpine"}]} +# ___ _ _ +# / _ \ | | (_) +# | |_| | __ _ ___ _ __ | |_ _ ___ +# | _ |/ _` |/ _ \ '_ \| __| |/ __| +# | | | | (_| | __/ | | | |_| | (__ +# \_| |_/\__, |\___|_| |_|\__|_|\___| +# __/ | +# _ _ |___/ +# | | | | / _| | +# | | | | ___ _ __ _ __| |_| | _____ ____ +# | |/\| |/ _ \ '__| |/ /| _| |/ _ \ \ /\ / / ___| +# \ /\ / (_) | | | | ( | | | | (_) \ V V /\__ \ +# \/ \/ \___/|_| |_|\_\|_| |_|\___/ \_/\_/ |___/ +# +# This file was automatically generated by gh-aw (v0.68.3). DO NOT EDIT. +# +# To update this file, edit the corresponding .md file and run: +# gh aw compile +# Not all edits will cause changes to this file. +# +# For more information: https://github.github.com/gh-aw/introduction/overview/ +# +# Refreshes pinned CI/CD dependencies – SHA-pinned GitHub Actions in .github/workflows/, task versions and 1ES template refs in .github/azure-devops/ – and audits Node.js runtime consistency across workflows, pipelines, package.json, and .nvmrc. Triggered when Release – Initiate completes so updates land on the release pull request it opens; workflow_dispatch is available as a manual retrigger while a release pull request is open. +# +# Secrets used: +# - COPILOT_GITHUB_TOKEN +# - GH_AW_GITHUB_MCP_SERVER_TOKEN +# - GH_AW_GITHUB_TOKEN +# - GITHUB_TOKEN +# - PR_METRICS_TOKEN +# +# Custom actions used: +# - actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 +# - actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 +# - actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9 +# - actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 +# - github/gh-aw-actions/setup@ba90f2186d7ad780ec640f364005fa24e797b360 # v0.68.3 +# +# Container images used: +# - ghcr.io/github/gh-aw-firewall/agent:0.25.20 +# - ghcr.io/github/gh-aw-firewall/api-proxy:0.25.20 +# - ghcr.io/github/gh-aw-firewall/squid:0.25.20 +# - ghcr.io/github/gh-aw-mcpg:v0.2.19 +# - ghcr.io/github/github-mcp-server:v0.32.0 +# - node:lts-alpine + +name: "Update CI Dependencies" +"on": + workflow_dispatch: + inputs: + aw_context: + default: "" + description: Agent caller context (used internally by Agentic Workflows). + required: false + type: string + workflow_run: + # zizmor: ignore[dangerous-triggers] - workflow_run trigger is secured with role and fork validation + branches: + - "**" + types: + - completed + workflows: + - Release – Initiate + +permissions: {} + +concurrency: + group: "gh-aw-${{ github.workflow }}" + +run-name: "Update CI Dependencies" + +jobs: + activation: + needs: pre_activation + # zizmor: ignore[dangerous-triggers] - workflow_run trigger is secured with role and fork validation + if: > + (needs.pre_activation.outputs.activated == 'true') && (github.event_name != 'workflow_run' || github.event.workflow_run.repository.id == github.repository_id && + (!(github.event.workflow_run.repository.fork))) + runs-on: ubuntu-slim + permissions: + actions: read + contents: read + outputs: + comment_id: "" + comment_repo: "" + lockdown_check_failed: ${{ steps.generate_aw_info.outputs.lockdown_check_failed == 'true' }} + model: ${{ steps.generate_aw_info.outputs.model }} + secret_verification_result: ${{ steps.validate-secret.outputs.verification_result }} + setup-trace-id: ${{ steps.setup.outputs.trace-id }} + stale_lock_file_failed: ${{ steps.check-lock-file.outputs.stale_lock_file_failed == 'true' }} + steps: + - name: Setup Scripts + id: setup + uses: github/gh-aw-actions/setup@ba90f2186d7ad780ec640f364005fa24e797b360 # v0.68.3 + with: + destination: ${{ runner.temp }}/gh-aw/actions + job-name: ${{ github.job }} + trace-id: ${{ needs.pre_activation.outputs.setup-trace-id }} + - name: Generate agentic run info + id: generate_aw_info + env: + GH_AW_INFO_ENGINE_ID: "copilot" + GH_AW_INFO_ENGINE_NAME: "GitHub Copilot CLI" + GH_AW_INFO_MODEL: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || 'auto' }} + GH_AW_INFO_VERSION: "1.0.21" + GH_AW_INFO_AGENT_VERSION: "1.0.21" + GH_AW_INFO_CLI_VERSION: "v0.68.3" + GH_AW_INFO_WORKFLOW_NAME: "Update CI Dependencies" + GH_AW_INFO_EXPERIMENTAL: "false" + GH_AW_INFO_SUPPORTS_TOOLS_ALLOWLIST: "true" + GH_AW_INFO_STAGED: "false" + GH_AW_INFO_ALLOWED_DOMAINS: '["defaults"]' + GH_AW_INFO_FIREWALL_ENABLED: "true" + GH_AW_INFO_AWF_VERSION: "v0.25.20" + GH_AW_INFO_AWMG_VERSION: "" + GH_AW_INFO_FIREWALL_TYPE: "squid" + GH_AW_COMPILED_STRICT: "true" + uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9 + with: + script: | + const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_aw_info.cjs'); + await main(core, context); + - name: Validate COPILOT_GITHUB_TOKEN secret + id: validate-secret + run: bash "${RUNNER_TEMP}/gh-aw/actions/validate_multi_secret.sh" COPILOT_GITHUB_TOKEN 'GitHub Copilot CLI' https://github.github.com/gh-aw/reference/engines/#github-copilot-default + env: + COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }} + - name: Checkout .github and .agents folders + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + sparse-checkout: | + .github + .agents + sparse-checkout-cone-mode: true + fetch-depth: 1 + - name: Check workflow lock file + id: check-lock-file + uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9 + env: + GH_AW_WORKFLOW_FILE: "update-ci-dependencies.lock.yml" + GH_AW_CONTEXT_WORKFLOW_REF: "${{ github.workflow_ref }}" + with: + script: | + const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require('${{ runner.temp }}/gh-aw/actions/check_workflow_timestamp_api.cjs'); + await main(); + - name: Check compile-agentic version + uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9 + env: + GH_AW_COMPILED_VERSION: "v0.68.3" + with: + script: | + const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require('${{ runner.temp }}/gh-aw/actions/check_version_updates.cjs'); + await main(); + - name: Create prompt with built-in context + env: + GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_SAFE_OUTPUTS: ${{ runner.temp }}/gh-aw/safeoutputs/outputs.jsonl + GH_AW_GITHUB_ACTOR: ${{ github.actor }} + GH_AW_GITHUB_EVENT_COMMENT_ID: ${{ github.event.comment.id }} + GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER: ${{ github.event.discussion.number }} + GH_AW_GITHUB_EVENT_ISSUE_NUMBER: ${{ github.event.issue.number }} + GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER: ${{ github.event.pull_request.number }} + GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} + GH_AW_GITHUB_RUN_ID: ${{ github.run_id }} + GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }} + # poutine:ignore untrusted_checkout_exec + run: | + bash "${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh" + { + cat << 'GH_AW_PROMPT_24da50bb34eefe08_EOF' + + GH_AW_PROMPT_24da50bb34eefe08_EOF + cat "${RUNNER_TEMP}/gh-aw/prompts/xpia.md" + cat "${RUNNER_TEMP}/gh-aw/prompts/temp_folder_prompt.md" + cat "${RUNNER_TEMP}/gh-aw/prompts/markdown.md" + cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_prompt.md" + cat << 'GH_AW_PROMPT_24da50bb34eefe08_EOF' + + Tools: push_to_pull_request_branch, missing_tool, missing_data, noop + GH_AW_PROMPT_24da50bb34eefe08_EOF + cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_push_to_pr_branch.md" + cat << 'GH_AW_PROMPT_24da50bb34eefe08_EOF' + + + The following GitHub context information is available for this workflow: + {{#if __GH_AW_GITHUB_ACTOR__ }} + - **actor**: __GH_AW_GITHUB_ACTOR__ + {{/if}} + {{#if __GH_AW_GITHUB_REPOSITORY__ }} + - **repository**: __GH_AW_GITHUB_REPOSITORY__ + {{/if}} + {{#if __GH_AW_GITHUB_WORKSPACE__ }} + - **workspace**: __GH_AW_GITHUB_WORKSPACE__ + {{/if}} + {{#if __GH_AW_GITHUB_EVENT_ISSUE_NUMBER__ }} + - **issue-number**: #__GH_AW_GITHUB_EVENT_ISSUE_NUMBER__ + {{/if}} + {{#if __GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER__ }} + - **discussion-number**: #__GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER__ + {{/if}} + {{#if __GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER__ }} + - **pull-request-number**: #__GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER__ + {{/if}} + {{#if __GH_AW_GITHUB_EVENT_COMMENT_ID__ }} + - **comment-id**: __GH_AW_GITHUB_EVENT_COMMENT_ID__ + {{/if}} + {{#if __GH_AW_GITHUB_RUN_ID__ }} + - **workflow-run-id**: __GH_AW_GITHUB_RUN_ID__ + {{/if}} + - **checkouts**: The following repositories have been checked out and are available in the workspace: + - `$GITHUB_WORKSPACE` → `__GH_AW_GITHUB_REPOSITORY__` (cwd) [full history, all branches available as remote-tracking refs] [additional refs fetched: *] + - **Note**: If a branch you need is not in the list above and is not listed as an additional fetched ref, it has NOT been checked out. For private repositories you cannot fetch it without proper authentication. If the branch is required and not available, exit with an error and ask the user to add it to the `fetch:` option of the `checkout:` configuration (e.g., `fetch: ["refs/pulls/open/*"]` for all open PR refs, or `fetch: ["main", "feature/my-branch"]` for specific branches). + + + GH_AW_PROMPT_24da50bb34eefe08_EOF + cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md" + cat << 'GH_AW_PROMPT_24da50bb34eefe08_EOF' + + {{#runtime-import .github/workflows/update-ci-dependencies.md}} + GH_AW_PROMPT_24da50bb34eefe08_EOF + } > "$GH_AW_PROMPT" + - name: Interpolate variables and render templates + uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9 + env: + GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + with: + script: | + const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require('${{ runner.temp }}/gh-aw/actions/interpolate_prompt.cjs'); + await main(); + - name: Substitute placeholders + uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9 + env: + GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_GITHUB_ACTOR: ${{ github.actor }} + GH_AW_GITHUB_EVENT_COMMENT_ID: ${{ github.event.comment.id }} + GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER: ${{ github.event.discussion.number }} + GH_AW_GITHUB_EVENT_ISSUE_NUMBER: ${{ github.event.issue.number }} + GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER: ${{ github.event.pull_request.number }} + GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} + GH_AW_GITHUB_RUN_ID: ${{ github.run_id }} + GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }} + GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED: ${{ needs.pre_activation.outputs.activated }} + with: + script: | + const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io, getOctokit); + + const substitutePlaceholders = require('${{ runner.temp }}/gh-aw/actions/substitute_placeholders.cjs'); + + // Call the substitution function + return await substitutePlaceholders({ + file: process.env.GH_AW_PROMPT, + substitutions: { + GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, + GH_AW_GITHUB_EVENT_COMMENT_ID: process.env.GH_AW_GITHUB_EVENT_COMMENT_ID, + GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER: process.env.GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER, + GH_AW_GITHUB_EVENT_ISSUE_NUMBER: process.env.GH_AW_GITHUB_EVENT_ISSUE_NUMBER, + GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER: process.env.GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER, + GH_AW_GITHUB_REPOSITORY: process.env.GH_AW_GITHUB_REPOSITORY, + GH_AW_GITHUB_RUN_ID: process.env.GH_AW_GITHUB_RUN_ID, + GH_AW_GITHUB_WORKSPACE: process.env.GH_AW_GITHUB_WORKSPACE, + GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED: process.env.GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED + } + }); + - name: Validate prompt placeholders + env: + GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + # poutine:ignore untrusted_checkout_exec + run: bash "${RUNNER_TEMP}/gh-aw/actions/validate_prompt_placeholders.sh" + - name: Print prompt + env: + GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + # poutine:ignore untrusted_checkout_exec + run: bash "${RUNNER_TEMP}/gh-aw/actions/print_prompt_summary.sh" + - name: Upload activation artifact + if: success() + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: activation + path: | + /tmp/gh-aw/aw_info.json + /tmp/gh-aw/aw-prompts/prompt.txt + /tmp/gh-aw/github_rate_limits.jsonl + if-no-files-found: ignore + retention-days: 1 + + agent: + needs: activation + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + pull-requests: read + concurrency: + group: "gh-aw-copilot-${{ github.workflow }}" + env: + DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} + GH_AW_ASSETS_ALLOWED_EXTS: "" + GH_AW_ASSETS_BRANCH: "" + GH_AW_ASSETS_MAX_SIZE_KB: 0 + GH_AW_MCP_LOG_DIR: /tmp/gh-aw/mcp-logs/safeoutputs + GH_AW_WORKFLOW_ID_SANITIZED: updatecidependencies + outputs: + agentic_engine_timeout: ${{ steps.detect-copilot-errors.outputs.agentic_engine_timeout || 'false' }} + checkout_pr_success: ${{ steps.checkout-pr.outputs.checkout_pr_success || 'true' }} + effective_tokens: ${{ steps.parse-mcp-gateway.outputs.effective_tokens }} + has_patch: ${{ steps.collect_output.outputs.has_patch }} + inference_access_error: ${{ steps.detect-copilot-errors.outputs.inference_access_error || 'false' }} + mcp_policy_error: ${{ steps.detect-copilot-errors.outputs.mcp_policy_error || 'false' }} + model: ${{ needs.activation.outputs.model }} + model_not_supported_error: ${{ steps.detect-copilot-errors.outputs.model_not_supported_error || 'false' }} + output: ${{ steps.collect_output.outputs.output }} + output_types: ${{ steps.collect_output.outputs.output_types }} + setup-trace-id: ${{ steps.setup.outputs.trace-id }} + steps: + - name: Setup Scripts + id: setup + uses: github/gh-aw-actions/setup@ba90f2186d7ad780ec640f364005fa24e797b360 # v0.68.3 + with: + destination: ${{ runner.temp }}/gh-aw/actions + job-name: ${{ github.job }} + trace-id: ${{ needs.activation.outputs.setup-trace-id }} + - name: Set runtime paths + id: set-runtime-paths + run: | + { + echo "GH_AW_SAFE_OUTPUTS=${RUNNER_TEMP}/gh-aw/safeoutputs/outputs.jsonl" + echo "GH_AW_SAFE_OUTPUTS_CONFIG_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" + echo "GH_AW_SAFE_OUTPUTS_TOOLS_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/tools.json" + } >> "$GITHUB_OUTPUT" + - name: Checkout repository + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + fetch-depth: 0 + - name: Fetch additional refs + env: + GH_AW_FETCH_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} + run: | + header=$(printf "x-access-token:%s" "${GH_AW_FETCH_TOKEN}" | base64 -w 0) + git -c "http.extraheader=Authorization: Basic ${header}" fetch origin '+refs/heads/*:refs/remotes/origin/*' + - name: Create gh-aw temp directory + run: bash "${RUNNER_TEMP}/gh-aw/actions/create_gh_aw_tmp_dir.sh" + - name: Configure gh CLI for GitHub Enterprise + run: bash "${RUNNER_TEMP}/gh-aw/actions/configure_gh_for_ghe.sh" + env: + GH_TOKEN: ${{ github.token }} + - name: Configure Git credentials + env: + REPO_NAME: ${{ github.repository }} + SERVER_URL: ${{ github.server_url }} + GITHUB_TOKEN: ${{ github.token }} + run: | + git config --global user.email "github-actions[bot]@users.noreply.github.com" + git config --global user.name "github-actions[bot]" + git config --global am.keepcr true + # Re-authenticate git with GitHub token + SERVER_URL_STRIPPED="${SERVER_URL#https://}" + git remote set-url origin "https://x-access-token:${GITHUB_TOKEN}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git" + echo "Git configured with standard GitHub Actions identity" + - name: Checkout PR branch + id: checkout-pr + if: | + github.event.pull_request || github.event.issue.pull_request + uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9 + env: + GH_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} + with: + github-token: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} + script: | + const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require('${{ runner.temp }}/gh-aw/actions/checkout_pr_branch.cjs'); + await main(); + - name: Install GitHub Copilot CLI + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.21 + env: + GH_HOST: github.com + - name: Install AWF binary + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.25.20 + - name: Determine automatic lockdown mode for GitHub MCP Server + id: determine-automatic-lockdown + uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9 + env: + GH_AW_GITHUB_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN }} + GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }} + with: + script: | + const determineAutomaticLockdown = require('${{ runner.temp }}/gh-aw/actions/determine_automatic_lockdown.cjs'); + await determineAutomaticLockdown(github, context, core); + - name: Download container images + run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.25.20 ghcr.io/github/gh-aw-firewall/api-proxy:0.25.20 ghcr.io/github/gh-aw-firewall/squid:0.25.20 ghcr.io/github/gh-aw-mcpg:v0.2.19 ghcr.io/github/github-mcp-server:v0.32.0 node:lts-alpine + - name: Write Safe Outputs Config + env: + PR_METRICS_TOKEN: ${{ secrets.PR_METRICS_TOKEN }} + run: | + mkdir -p "${RUNNER_TEMP}/gh-aw/safeoutputs" + mkdir -p /tmp/gh-aw/safeoutputs + mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs + cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << GH_AW_SAFE_OUTPUTS_CONFIG_e3baffdb24bb6476_EOF + {"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"push_to_pull_request_branch":{"allowed_files":[".github/workflows/*.yml",".github/azure-devops/*.yml","package.json",".nvmrc"],"github-token":"${PR_METRICS_TOKEN}","if_no_changes":"ignore","labels":["release"],"max":1,"max_patch_size":1024,"protected_files":["package.json","bun.lockb","bunfig.toml","deno.json","deno.jsonc","deno.lock","global.json","NuGet.Config","Directory.Packages.props","mix.exs","mix.lock","go.mod","go.sum","stack.yaml","stack.yaml.lock","pom.xml","build.gradle","build.gradle.kts","settings.gradle","settings.gradle.kts","gradle.properties","package-lock.json","yarn.lock","pnpm-lock.yaml","npm-shrinkwrap.json","requirements.txt","Pipfile","Pipfile.lock","pyproject.toml","setup.py","setup.cfg","Gemfile","Gemfile.lock","uv.lock","CODEOWNERS"],"protected_files_policy":"allowed","protected_path_prefixes":[".github/",".agents/"],"target":"*"},"report_incomplete":{}} + GH_AW_SAFE_OUTPUTS_CONFIG_e3baffdb24bb6476_EOF + - name: Write Safe Outputs Tools + env: + GH_AW_TOOLS_META_JSON: | + { + "description_suffixes": { + "push_to_pull_request_branch": " CONSTRAINTS: Maximum 1 push(es) can be made." + }, + "repo_params": {}, + "dynamic_tools": [] + } + GH_AW_VALIDATION_JSON: | + { + "missing_data": { + "defaultMax": 20, + "fields": { + "alternatives": { + "type": "string", + "sanitize": true, + "maxLength": 256 + }, + "context": { + "type": "string", + "sanitize": true, + "maxLength": 256 + }, + "data_type": { + "type": "string", + "sanitize": true, + "maxLength": 128 + }, + "reason": { + "type": "string", + "sanitize": true, + "maxLength": 256 + } + } + }, + "missing_tool": { + "defaultMax": 20, + "fields": { + "alternatives": { + "type": "string", + "sanitize": true, + "maxLength": 512 + }, + "reason": { + "required": true, + "type": "string", + "sanitize": true, + "maxLength": 256 + }, + "tool": { + "type": "string", + "sanitize": true, + "maxLength": 128 + } + } + }, + "noop": { + "defaultMax": 1, + "fields": { + "message": { + "required": true, + "type": "string", + "sanitize": true, + "maxLength": 65000 + } + } + }, + "push_to_pull_request_branch": { + "defaultMax": 1, + "fields": { + "branch": { + "required": true, + "type": "string", + "sanitize": true, + "maxLength": 256 + }, + "message": { + "required": true, + "type": "string", + "sanitize": true, + "maxLength": 65000 + }, + "pull_request_number": { + "issueOrPRNumber": true + } + } + }, + "report_incomplete": { + "defaultMax": 5, + "fields": { + "details": { + "type": "string", + "sanitize": true, + "maxLength": 65000 + }, + "reason": { + "required": true, + "type": "string", + "sanitize": true, + "maxLength": 1024 + } + } + } + } + uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9 + with: + script: | + const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_safe_outputs_tools.cjs'); + await main(); + - name: Generate Safe Outputs MCP Server Config + id: safe-outputs-config + run: | + # Generate a secure random API key (360 bits of entropy, 40+ chars) + # Mask immediately to prevent timing vulnerabilities + API_KEY=$(openssl rand -base64 45 | tr -d '/+=') + echo "::add-mask::${API_KEY}" + + PORT=3001 + + # Set outputs for next steps + { + echo "safe_outputs_api_key=${API_KEY}" + echo "safe_outputs_port=${PORT}" + } >> "$GITHUB_OUTPUT" + + echo "Safe Outputs MCP server will run on port ${PORT}" + + - name: Start Safe Outputs MCP HTTP Server + id: safe-outputs-start + env: + DEBUG: '*' + GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }} + GH_AW_SAFE_OUTPUTS_PORT: ${{ steps.safe-outputs-config.outputs.safe_outputs_port }} + GH_AW_SAFE_OUTPUTS_API_KEY: ${{ steps.safe-outputs-config.outputs.safe_outputs_api_key }} + GH_AW_SAFE_OUTPUTS_TOOLS_PATH: ${{ runner.temp }}/gh-aw/safeoutputs/tools.json + GH_AW_SAFE_OUTPUTS_CONFIG_PATH: ${{ runner.temp }}/gh-aw/safeoutputs/config.json + GH_AW_MCP_LOG_DIR: /tmp/gh-aw/mcp-logs/safeoutputs + run: | + # Environment variables are set above to prevent template injection + export DEBUG + export GH_AW_SAFE_OUTPUTS + export GH_AW_SAFE_OUTPUTS_PORT + export GH_AW_SAFE_OUTPUTS_API_KEY + export GH_AW_SAFE_OUTPUTS_TOOLS_PATH + export GH_AW_SAFE_OUTPUTS_CONFIG_PATH + export GH_AW_MCP_LOG_DIR + + bash "${RUNNER_TEMP}/gh-aw/actions/start_safe_outputs_server.sh" + + - name: Start MCP Gateway + id: start-mcp-gateway + env: + GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }} + GH_AW_SAFE_OUTPUTS_API_KEY: ${{ steps.safe-outputs-start.outputs.api_key }} + GH_AW_SAFE_OUTPUTS_PORT: ${{ steps.safe-outputs-start.outputs.port }} + GITHUB_MCP_GUARD_MIN_INTEGRITY: ${{ steps.determine-automatic-lockdown.outputs.min_integrity }} + GITHUB_MCP_GUARD_REPOS: ${{ steps.determine-automatic-lockdown.outputs.repos }} + GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} + run: | + set -eo pipefail + mkdir -p /tmp/gh-aw/mcp-config + + # Export gateway environment variables for MCP config and gateway script + export MCP_GATEWAY_PORT="80" + export MCP_GATEWAY_DOMAIN="host.docker.internal" + MCP_GATEWAY_API_KEY=$(openssl rand -base64 45 | tr -d '/+=') + echo "::add-mask::${MCP_GATEWAY_API_KEY}" + export MCP_GATEWAY_API_KEY + export MCP_GATEWAY_PAYLOAD_DIR="/tmp/gh-aw/mcp-payloads" + mkdir -p "${MCP_GATEWAY_PAYLOAD_DIR}" + export MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD="524288" + export DEBUG="*" + + export GH_AW_ENGINE="copilot" + export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host -v /var/run/docker.sock:/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e GH_AW_SAFE_OUTPUTS_PORT -e GH_AW_SAFE_OUTPUTS_API_KEY -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw ghcr.io/github/gh-aw-mcpg:v0.2.19' + + mkdir -p /home/runner/.copilot + cat << GH_AW_MCP_CONFIG_413712401644109d_EOF | bash "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.sh" + { + "mcpServers": { + "github": { + "type": "stdio", + "container": "ghcr.io/github/github-mcp-server:v0.32.0", + "env": { + "GITHUB_HOST": "\${GITHUB_SERVER_URL}", + "GITHUB_PERSONAL_ACCESS_TOKEN": "\${GITHUB_MCP_SERVER_TOKEN}", + "GITHUB_READ_ONLY": "1", + "GITHUB_TOOLSETS": "context,repos,issues,pull_requests" + }, + "guard-policies": { + "allow-only": { + "min-integrity": "$GITHUB_MCP_GUARD_MIN_INTEGRITY", + "repos": "$GITHUB_MCP_GUARD_REPOS" + } + } + }, + "safeoutputs": { + "type": "http", + "url": "http://host.docker.internal:$GH_AW_SAFE_OUTPUTS_PORT", + "headers": { + "Authorization": "\${GH_AW_SAFE_OUTPUTS_API_KEY}" + }, + "guard-policies": { + "write-sink": { + "accept": [ + "*" + ] + } + } + } + }, + "gateway": { + "port": $MCP_GATEWAY_PORT, + "domain": "${MCP_GATEWAY_DOMAIN}", + "apiKey": "${MCP_GATEWAY_API_KEY}", + "payloadDir": "${MCP_GATEWAY_PAYLOAD_DIR}" + } + } + GH_AW_MCP_CONFIG_413712401644109d_EOF + - name: Download activation artifact + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: activation + path: /tmp/gh-aw + - name: Clean git credentials + continue-on-error: true + run: bash "${RUNNER_TEMP}/gh-aw/actions/clean_git_credentials.sh" + - name: Execute GitHub Copilot CLI + id: agentic_execution + # Copilot CLI tool arguments (sorted): + # --allow-tool github + # --allow-tool safeoutputs + # --allow-tool shell(cat) + # --allow-tool shell(date) + # --allow-tool shell(echo) + # --allow-tool shell(gh api *) + # --allow-tool shell(gh pr list *) + # --allow-tool shell(gh pr view *) + # --allow-tool shell(git *) + # --allow-tool shell(git add:*) + # --allow-tool shell(git branch:*) + # --allow-tool shell(git checkout:*) + # --allow-tool shell(git commit:*) + # --allow-tool shell(git merge:*) + # --allow-tool shell(git rm:*) + # --allow-tool shell(git status) + # --allow-tool shell(git switch:*) + # --allow-tool shell(grep) + # --allow-tool shell(head) + # --allow-tool shell(jq *) + # --allow-tool shell(ls) + # --allow-tool shell(pwd) + # --allow-tool shell(sort) + # --allow-tool shell(tail) + # --allow-tool shell(uniq) + # --allow-tool shell(wc) + # --allow-tool shell(yq) + # --allow-tool write + timeout-minutes: 20 + run: | + set -o pipefail + touch /tmp/gh-aw/agent-step-summary.md + (umask 177 && touch /tmp/gh-aw/agent-stdio.log) + # shellcheck disable=SC1003 + sudo -E awf --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" --env-all --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --allow-domains api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,github.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,ppa.launchpad.net,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,telemetry.enterprise.githubcopilot.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.googleapis.com --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --image-tag 0.25.20 --skip-pull --enable-api-proxy \ + -- /bin/bash -c 'node ${RUNNER_TEMP}/gh-aw/actions/copilot_driver.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-tool github --allow-tool safeoutputs --allow-tool '\''shell(cat)'\'' --allow-tool '\''shell(date)'\'' --allow-tool '\''shell(echo)'\'' --allow-tool '\''shell(gh api *)'\'' --allow-tool '\''shell(gh pr list *)'\'' --allow-tool '\''shell(gh pr view *)'\'' --allow-tool '\''shell(git *)'\'' --allow-tool '\''shell(git add:*)'\'' --allow-tool '\''shell(git branch:*)'\'' --allow-tool '\''shell(git checkout:*)'\'' --allow-tool '\''shell(git commit:*)'\'' --allow-tool '\''shell(git merge:*)'\'' --allow-tool '\''shell(git rm:*)'\'' --allow-tool '\''shell(git status)'\'' --allow-tool '\''shell(git switch:*)'\'' --allow-tool '\''shell(grep)'\'' --allow-tool '\''shell(head)'\'' --allow-tool '\''shell(jq *)'\'' --allow-tool '\''shell(ls)'\'' --allow-tool '\''shell(pwd)'\'' --allow-tool '\''shell(sort)'\'' --allow-tool '\''shell(tail)'\'' --allow-tool '\''shell(uniq)'\'' --allow-tool '\''shell(wc)'\'' --allow-tool '\''shell(yq)'\'' --allow-tool write --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log + env: + COPILOT_AGENT_RUNNER_TYPE: STANDALONE + COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }} + COPILOT_MODEL: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || '' }} + GH_AW_MCP_CONFIG: /home/runner/.copilot/mcp-config.json + GH_AW_PHASE: agent + GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }} + GH_AW_VERSION: v0.68.3 + GITHUB_API_URL: ${{ github.api_url }} + GITHUB_AW: true + GITHUB_HEAD_REF: ${{ github.head_ref }} + GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} + GITHUB_REF_NAME: ${{ github.ref_name }} + GITHUB_SERVER_URL: ${{ github.server_url }} + GITHUB_STEP_SUMMARY: /tmp/gh-aw/agent-step-summary.md + GITHUB_WORKSPACE: ${{ github.workspace }} + GIT_AUTHOR_EMAIL: github-actions[bot]@users.noreply.github.com + GIT_AUTHOR_NAME: github-actions[bot] + GIT_COMMITTER_EMAIL: github-actions[bot]@users.noreply.github.com + GIT_COMMITTER_NAME: github-actions[bot] + XDG_CONFIG_HOME: /home/runner + - name: Detect Copilot errors + id: detect-copilot-errors + if: always() + continue-on-error: true + run: node "${RUNNER_TEMP}/gh-aw/actions/detect_copilot_errors.cjs" + - name: Configure Git credentials + env: + REPO_NAME: ${{ github.repository }} + SERVER_URL: ${{ github.server_url }} + GITHUB_TOKEN: ${{ github.token }} + run: | + git config --global user.email "github-actions[bot]@users.noreply.github.com" + git config --global user.name "github-actions[bot]" + git config --global am.keepcr true + # Re-authenticate git with GitHub token + SERVER_URL_STRIPPED="${SERVER_URL#https://}" + git remote set-url origin "https://x-access-token:${GITHUB_TOKEN}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git" + echo "Git configured with standard GitHub Actions identity" + - name: Copy Copilot session state files to logs + if: always() + continue-on-error: true + run: bash "${RUNNER_TEMP}/gh-aw/actions/copy_copilot_session_state.sh" + - name: Stop MCP Gateway + if: always() + continue-on-error: true + env: + MCP_GATEWAY_PORT: ${{ steps.start-mcp-gateway.outputs.gateway-port }} + MCP_GATEWAY_API_KEY: ${{ steps.start-mcp-gateway.outputs.gateway-api-key }} + GATEWAY_PID: ${{ steps.start-mcp-gateway.outputs.gateway-pid }} + run: | + bash "${RUNNER_TEMP}/gh-aw/actions/stop_mcp_gateway.sh" "$GATEWAY_PID" + - name: Redact secrets in logs + if: always() + uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9 + with: + script: | + const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require('${{ runner.temp }}/gh-aw/actions/redact_secrets.cjs'); + await main(); + env: + GH_AW_SECRET_NAMES: 'COPILOT_GITHUB_TOKEN,GH_AW_GITHUB_MCP_SERVER_TOKEN,GH_AW_GITHUB_TOKEN,GITHUB_TOKEN,PR_METRICS_TOKEN' + SECRET_COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }} + SECRET_GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }} + SECRET_GH_AW_GITHUB_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN }} + SECRET_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + SECRET_PR_METRICS_TOKEN: ${{ secrets.PR_METRICS_TOKEN }} + - name: Append agent step summary + if: always() + run: bash "${RUNNER_TEMP}/gh-aw/actions/append_agent_step_summary.sh" + - name: Copy Safe Outputs + if: always() + env: + GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }} + run: | + mkdir -p /tmp/gh-aw + cp "$GH_AW_SAFE_OUTPUTS" /tmp/gh-aw/safeoutputs.jsonl 2>/dev/null || true + - name: Ingest agent output + id: collect_output + if: always() + uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9 + env: + GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }} + GH_AW_ALLOWED_DOMAINS: "api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,github.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,ppa.launchpad.net,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,telemetry.enterprise.githubcopilot.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.googleapis.com" + GITHUB_SERVER_URL: ${{ github.server_url }} + GITHUB_API_URL: ${{ github.api_url }} + with: + script: | + const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require('${{ runner.temp }}/gh-aw/actions/collect_ndjson_output.cjs'); + await main(); + - name: Parse agent logs for step summary + if: always() + uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9 + env: + GH_AW_AGENT_OUTPUT: /tmp/gh-aw/sandbox/agent/logs/ + with: + script: | + const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_copilot_log.cjs'); + await main(); + - name: Parse MCP Gateway logs for step summary + if: always() + id: parse-mcp-gateway + uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9 + with: + script: | + const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_mcp_gateway_log.cjs'); + await main(); + - name: Print firewall logs + if: always() + continue-on-error: true + env: + AWF_LOGS_DIR: /tmp/gh-aw/sandbox/firewall/logs + run: | + # Fix permissions on firewall logs so they can be uploaded as artifacts + # AWF runs with sudo, creating files owned by root + sudo chmod -R a+r /tmp/gh-aw/sandbox/firewall/logs 2>/dev/null || true + # Only run awf logs summary if awf command exists (it may not be installed if workflow failed before install step) + if command -v awf &> /dev/null; then + awf logs summary | tee -a "$GITHUB_STEP_SUMMARY" + else + echo 'AWF binary not installed, skipping firewall log summary' + fi + - name: Parse token usage for step summary + if: always() + continue-on-error: true + uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9 + with: + script: | + const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_token_usage.cjs'); + await main(); + - name: Write agent output placeholder if missing + if: always() + run: | + if [ ! -f /tmp/gh-aw/agent_output.json ]; then + echo '{"items":[]}' > /tmp/gh-aw/agent_output.json + fi + - name: Upload agent artifacts + if: always() + continue-on-error: true + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: agent + path: | + /tmp/gh-aw/aw-prompts/prompt.txt + /tmp/gh-aw/sandbox/agent/logs/ + /tmp/gh-aw/redacted-urls.log + /tmp/gh-aw/mcp-logs/ + /tmp/gh-aw/agent_usage.json + /tmp/gh-aw/agent-stdio.log + /tmp/gh-aw/agent/ + /tmp/gh-aw/github_rate_limits.jsonl + /tmp/gh-aw/safeoutputs.jsonl + /tmp/gh-aw/agent_output.json + /tmp/gh-aw/aw-*.patch + /tmp/gh-aw/aw-*.bundle + /tmp/gh-aw/sandbox/firewall/logs/ + /tmp/gh-aw/sandbox/firewall/audit/ + if-no-files-found: ignore + + conclusion: + needs: + - activation + - agent + - detection + - safe_outputs + if: > + always() && (needs.agent.result != 'skipped' || needs.activation.outputs.lockdown_check_failed == 'true' || + needs.activation.outputs.stale_lock_file_failed == 'true') + runs-on: ubuntu-slim + permissions: + contents: write + pull-requests: write + concurrency: + group: "gh-aw-conclusion-update-ci-dependencies" + cancel-in-progress: false + outputs: + incomplete_count: ${{ steps.report_incomplete.outputs.incomplete_count }} + noop_message: ${{ steps.noop.outputs.noop_message }} + tools_reported: ${{ steps.missing_tool.outputs.tools_reported }} + total_count: ${{ steps.missing_tool.outputs.total_count }} + steps: + - name: Setup Scripts + id: setup + uses: github/gh-aw-actions/setup@ba90f2186d7ad780ec640f364005fa24e797b360 # v0.68.3 + with: + destination: ${{ runner.temp }}/gh-aw/actions + job-name: ${{ github.job }} + trace-id: ${{ needs.activation.outputs.setup-trace-id }} + - name: Download agent output artifact + id: download-agent-output + continue-on-error: true + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: agent + path: /tmp/gh-aw/ + - name: Setup agent output environment variable + id: setup-agent-output-env + if: steps.download-agent-output.outcome == 'success' + run: | + mkdir -p /tmp/gh-aw/ + find "/tmp/gh-aw/" -type f -print + echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" + - name: Process no-op messages + id: noop + uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9 + env: + GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }} + GH_AW_NOOP_MAX: "1" + GH_AW_WORKFLOW_NAME: "Update CI Dependencies" + GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }} + GH_AW_NOOP_REPORT_AS_ISSUE: "true" + with: + github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} + script: | + const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_noop_message.cjs'); + await main(); + - name: Log detection run + id: detection_runs + uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9 + env: + GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }} + GH_AW_WORKFLOW_NAME: "Update CI Dependencies" + GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + GH_AW_DETECTION_CONCLUSION: ${{ needs.detection.outputs.detection_conclusion }} + GH_AW_DETECTION_REASON: ${{ needs.detection.outputs.detection_reason }} + with: + github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} + script: | + const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_detection_runs.cjs'); + await main(); + - name: Record missing tool + id: missing_tool + uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9 + env: + GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }} + GH_AW_MISSING_TOOL_CREATE_ISSUE: "true" + GH_AW_WORKFLOW_NAME: "Update CI Dependencies" + with: + github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} + script: | + const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require('${{ runner.temp }}/gh-aw/actions/missing_tool.cjs'); + await main(); + - name: Record incomplete + id: report_incomplete + uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9 + env: + GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }} + GH_AW_REPORT_INCOMPLETE_CREATE_ISSUE: "true" + GH_AW_WORKFLOW_NAME: "Update CI Dependencies" + with: + github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} + script: | + const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require('${{ runner.temp }}/gh-aw/actions/report_incomplete_handler.cjs'); + await main(); + - name: Handle agent failure + id: handle_agent_failure + if: always() + uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9 + env: + GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }} + GH_AW_WORKFLOW_NAME: "Update CI Dependencies" + GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }} + GH_AW_WORKFLOW_ID: "update-ci-dependencies" + GH_AW_ENGINE_ID: "copilot" + GH_AW_SECRET_VERIFICATION_RESULT: ${{ needs.activation.outputs.secret_verification_result }} + GH_AW_CHECKOUT_PR_SUCCESS: ${{ needs.agent.outputs.checkout_pr_success }} + GH_AW_INFERENCE_ACCESS_ERROR: ${{ needs.agent.outputs.inference_access_error }} + GH_AW_MCP_POLICY_ERROR: ${{ needs.agent.outputs.mcp_policy_error }} + GH_AW_AGENTIC_ENGINE_TIMEOUT: ${{ needs.agent.outputs.agentic_engine_timeout }} + GH_AW_MODEL_NOT_SUPPORTED_ERROR: ${{ needs.agent.outputs.model_not_supported_error }} + GH_AW_CODE_PUSH_FAILURE_ERRORS: ${{ needs.safe_outputs.outputs.code_push_failure_errors }} + GH_AW_CODE_PUSH_FAILURE_COUNT: ${{ needs.safe_outputs.outputs.code_push_failure_count }} + GH_AW_LOCKDOWN_CHECK_FAILED: ${{ needs.activation.outputs.lockdown_check_failed }} + GH_AW_STALE_LOCK_FILE_FAILED: ${{ needs.activation.outputs.stale_lock_file_failed }} + GH_AW_GROUP_REPORTS: "false" + GH_AW_FAILURE_REPORT_AS_ISSUE: "true" + GH_AW_TIMEOUT_MINUTES: "20" + with: + github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} + script: | + const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_agent_failure.cjs'); + await main(); + + detection: + needs: + - activation + - agent + if: > + always() && needs.agent.result != 'skipped' && (needs.agent.outputs.output_types != '' || needs.agent.outputs.has_patch == 'true') + runs-on: ubuntu-latest + permissions: + contents: read + outputs: + detection_conclusion: ${{ steps.detection_conclusion.outputs.conclusion }} + detection_reason: ${{ steps.detection_conclusion.outputs.reason }} + detection_success: ${{ steps.detection_conclusion.outputs.success }} + steps: + - name: Setup Scripts + id: setup + uses: github/gh-aw-actions/setup@ba90f2186d7ad780ec640f364005fa24e797b360 # v0.68.3 + with: + destination: ${{ runner.temp }}/gh-aw/actions + job-name: ${{ github.job }} + trace-id: ${{ needs.activation.outputs.setup-trace-id }} + - name: Download agent output artifact + id: download-agent-output + continue-on-error: true + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: agent + path: /tmp/gh-aw/ + - name: Setup agent output environment variable + id: setup-agent-output-env + if: steps.download-agent-output.outcome == 'success' + run: | + mkdir -p /tmp/gh-aw/ + find "/tmp/gh-aw/" -type f -print + echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" + - name: Checkout repository for patch context + if: needs.agent.outputs.has_patch == 'true' + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + # --- Threat Detection --- + - name: Clean stale firewall files from agent artifact + run: | + rm -rf /tmp/gh-aw/sandbox/firewall/logs + rm -rf /tmp/gh-aw/sandbox/firewall/audit + - name: Download container images + run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.25.20 ghcr.io/github/gh-aw-firewall/api-proxy:0.25.20 ghcr.io/github/gh-aw-firewall/squid:0.25.20 + - name: Check if detection needed + id: detection_guard + if: always() + env: + OUTPUT_TYPES: ${{ needs.agent.outputs.output_types }} + HAS_PATCH: ${{ needs.agent.outputs.has_patch }} + run: | + if [[ -n "$OUTPUT_TYPES" || "$HAS_PATCH" == "true" ]]; then + echo "run_detection=true" >> "$GITHUB_OUTPUT" + echo "Detection will run: output_types=$OUTPUT_TYPES, has_patch=$HAS_PATCH" + else + echo "run_detection=false" >> "$GITHUB_OUTPUT" + echo "Detection skipped: no agent outputs or patches to analyze" + fi + - name: Clear MCP configuration for detection + if: always() && steps.detection_guard.outputs.run_detection == 'true' + run: | + rm -f /tmp/gh-aw/mcp-config/mcp-servers.json + rm -f /home/runner/.copilot/mcp-config.json + rm -f "$GITHUB_WORKSPACE/.gemini/settings.json" + - name: Prepare threat detection files + if: always() && steps.detection_guard.outputs.run_detection == 'true' + run: | + mkdir -p /tmp/gh-aw/threat-detection/aw-prompts + cp /tmp/gh-aw/aw-prompts/prompt.txt /tmp/gh-aw/threat-detection/aw-prompts/prompt.txt 2>/dev/null || true + cp /tmp/gh-aw/agent_output.json /tmp/gh-aw/threat-detection/agent_output.json 2>/dev/null || true + for f in /tmp/gh-aw/aw-*.patch; do + [ -f "$f" ] && cp "$f" /tmp/gh-aw/threat-detection/ 2>/dev/null || true + done + for f in /tmp/gh-aw/aw-*.bundle; do + [ -f "$f" ] && cp "$f" /tmp/gh-aw/threat-detection/ 2>/dev/null || true + done + echo "Prepared threat detection files:" + ls -la /tmp/gh-aw/threat-detection/ 2>/dev/null || true + - name: Setup threat detection + if: always() && steps.detection_guard.outputs.run_detection == 'true' + uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9 + env: + WORKFLOW_NAME: "Update CI Dependencies" + WORKFLOW_DESCRIPTION: "Refreshes pinned CI/CD dependencies – SHA-pinned GitHub Actions in .github/workflows/, task versions and 1ES template refs in .github/azure-devops/ – and audits Node.js runtime consistency across workflows, pipelines, package.json, and .nvmrc. Triggered when Release – Initiate completes so updates land on the release pull request it opens; workflow_dispatch is available as a manual retrigger while a release pull request is open." + HAS_PATCH: ${{ needs.agent.outputs.has_patch }} + with: + script: | + const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require('${{ runner.temp }}/gh-aw/actions/setup_threat_detection.cjs'); + await main(); + - name: Ensure threat-detection directory and log + if: always() && steps.detection_guard.outputs.run_detection == 'true' + run: | + mkdir -p /tmp/gh-aw/threat-detection + touch /tmp/gh-aw/threat-detection/detection.log + - name: Install GitHub Copilot CLI + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.21 + env: + GH_HOST: github.com + - name: Install AWF binary + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.25.20 + - name: Execute GitHub Copilot CLI + if: always() && steps.detection_guard.outputs.run_detection == 'true' + id: detection_agentic_execution + # Copilot CLI tool arguments (sorted): + timeout-minutes: 20 + run: | + set -o pipefail + touch /tmp/gh-aw/agent-step-summary.md + (umask 177 && touch /tmp/gh-aw/threat-detection/detection.log) + # shellcheck disable=SC1003 + sudo -E awf --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" --env-all --exclude-env COPILOT_GITHUB_TOKEN --allow-domains api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,github.com,host.docker.internal,telemetry.enterprise.githubcopilot.com --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --image-tag 0.25.20 --skip-pull --enable-api-proxy \ + -- /bin/bash -c 'node ${RUNNER_TEMP}/gh-aw/actions/copilot_driver.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --add-dir "${GITHUB_WORKSPACE}" --prompt "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log + env: + COPILOT_AGENT_RUNNER_TYPE: STANDALONE + COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }} + COPILOT_MODEL: ${{ vars.GH_AW_MODEL_DETECTION_COPILOT || '' }} + GH_AW_PHASE: detection + GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_VERSION: v0.68.3 + GITHUB_API_URL: ${{ github.api_url }} + GITHUB_AW: true + GITHUB_HEAD_REF: ${{ github.head_ref }} + GITHUB_REF_NAME: ${{ github.ref_name }} + GITHUB_SERVER_URL: ${{ github.server_url }} + GITHUB_STEP_SUMMARY: /tmp/gh-aw/agent-step-summary.md + GITHUB_WORKSPACE: ${{ github.workspace }} + GIT_AUTHOR_EMAIL: github-actions[bot]@users.noreply.github.com + GIT_AUTHOR_NAME: github-actions[bot] + GIT_COMMITTER_EMAIL: github-actions[bot]@users.noreply.github.com + GIT_COMMITTER_NAME: github-actions[bot] + XDG_CONFIG_HOME: /home/runner + - name: Upload threat detection log + if: always() && steps.detection_guard.outputs.run_detection == 'true' + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: detection + path: /tmp/gh-aw/threat-detection/detection.log + if-no-files-found: ignore + - name: Parse and conclude threat detection + id: detection_conclusion + if: always() + uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9 + env: + RUN_DETECTION: ${{ steps.detection_guard.outputs.run_detection }} + GH_AW_DETECTION_CONTINUE_ON_ERROR: "true" + with: + script: | + const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_threat_detection_results.cjs'); + await main(); + + pre_activation: + runs-on: ubuntu-slim + outputs: + activated: ${{ steps.check_membership.outputs.is_team_member == 'true' }} + matched_command: '' + setup-trace-id: ${{ steps.setup.outputs.trace-id }} + steps: + - name: Setup Scripts + id: setup + uses: github/gh-aw-actions/setup@ba90f2186d7ad780ec640f364005fa24e797b360 # v0.68.3 + with: + destination: ${{ runner.temp }}/gh-aw/actions + job-name: ${{ github.job }} + - name: Check team membership for workflow + id: check_membership + uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9 + env: + GH_AW_REQUIRED_ROLES: "admin,maintainer,write" + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require('${{ runner.temp }}/gh-aw/actions/check_membership.cjs'); + await main(); + + safe_outputs: + needs: + - activation + - agent + - detection + if: (!cancelled()) && needs.agent.result != 'skipped' && needs.detection.result == 'success' + runs-on: ubuntu-slim + permissions: + contents: write + pull-requests: write + timeout-minutes: 15 + env: + GH_AW_CALLER_WORKFLOW_ID: "${{ github.repository }}/update-ci-dependencies" + GH_AW_DETECTION_CONCLUSION: ${{ needs.detection.outputs.detection_conclusion }} + GH_AW_DETECTION_REASON: ${{ needs.detection.outputs.detection_reason }} + GH_AW_EFFECTIVE_TOKENS: ${{ needs.agent.outputs.effective_tokens }} + GH_AW_ENGINE_ID: "copilot" + GH_AW_ENGINE_MODEL: ${{ needs.agent.outputs.model }} + GH_AW_WORKFLOW_ID: "update-ci-dependencies" + GH_AW_WORKFLOW_NAME: "Update CI Dependencies" + outputs: + code_push_failure_count: ${{ steps.process_safe_outputs.outputs.code_push_failure_count }} + code_push_failure_errors: ${{ steps.process_safe_outputs.outputs.code_push_failure_errors }} + create_discussion_error_count: ${{ steps.process_safe_outputs.outputs.create_discussion_error_count }} + create_discussion_errors: ${{ steps.process_safe_outputs.outputs.create_discussion_errors }} + process_safe_outputs_processed_count: ${{ steps.process_safe_outputs.outputs.processed_count }} + process_safe_outputs_temporary_id_map: ${{ steps.process_safe_outputs.outputs.temporary_id_map }} + push_commit_sha: ${{ steps.process_safe_outputs.outputs.push_commit_sha }} + push_commit_url: ${{ steps.process_safe_outputs.outputs.push_commit_url }} + steps: + - name: Setup Scripts + id: setup + uses: github/gh-aw-actions/setup@ba90f2186d7ad780ec640f364005fa24e797b360 # v0.68.3 + with: + destination: ${{ runner.temp }}/gh-aw/actions + job-name: ${{ github.job }} + trace-id: ${{ needs.activation.outputs.setup-trace-id }} + - name: Download agent output artifact + id: download-agent-output + continue-on-error: true + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: agent + path: /tmp/gh-aw/ + - name: Setup agent output environment variable + id: setup-agent-output-env + if: steps.download-agent-output.outcome == 'success' + run: | + mkdir -p /tmp/gh-aw/ + find "/tmp/gh-aw/" -type f -print + echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" + - name: Download patch artifact + continue-on-error: true + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: agent + path: /tmp/gh-aw/ + - name: Checkout repository + if: (!cancelled()) && needs.agent.result != 'skipped' && contains(needs.agent.outputs.output_types, 'push_to_pull_request_branch') + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + ref: ${{ github.base_ref || github.event.pull_request.base.ref || github.ref_name || github.event.repository.default_branch }} + token: ${{ secrets.PR_METRICS_TOKEN }} + persist-credentials: false + fetch-depth: 1 + - name: Configure Git credentials + if: (!cancelled()) && needs.agent.result != 'skipped' && contains(needs.agent.outputs.output_types, 'push_to_pull_request_branch') + env: + REPO_NAME: ${{ github.repository }} + SERVER_URL: ${{ github.server_url }} + GIT_TOKEN: ${{ secrets.PR_METRICS_TOKEN }} + run: | + git config --global user.email "github-actions[bot]@users.noreply.github.com" + git config --global user.name "github-actions[bot]" + git config --global am.keepcr true + # Re-authenticate git with GitHub token + SERVER_URL_STRIPPED="${SERVER_URL#https://}" + git remote set-url origin "https://x-access-token:${GIT_TOKEN}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git" + echo "Git configured with standard GitHub Actions identity" + - name: Configure GH_HOST for enterprise compatibility + id: ghes-host-config + shell: bash + run: | + # Derive GH_HOST from GITHUB_SERVER_URL so the gh CLI targets the correct + # GitHub instance (GHES/GHEC). On github.com this is a harmless no-op. + GH_HOST="${GITHUB_SERVER_URL#https://}" + GH_HOST="${GH_HOST#http://}" + echo "GH_HOST=${GH_HOST}" >> "$GITHUB_ENV" + - name: Process Safe Outputs + id: process_safe_outputs + uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9 + env: + GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }} + GH_AW_ALLOWED_DOMAINS: "api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,github.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,ppa.launchpad.net,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,telemetry.enterprise.githubcopilot.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.googleapis.com" + GITHUB_SERVER_URL: ${{ github.server_url }} + GITHUB_API_URL: ${{ github.api_url }} + GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"true\"},\"push_to_pull_request_branch\":{\"allowed_files\":[\".github/workflows/*.yml\",\".github/azure-devops/*.yml\",\"package.json\",\".nvmrc\"],\"github-token\":\"${{ secrets.PR_METRICS_TOKEN }}\",\"if_no_changes\":\"ignore\",\"labels\":[\"release\"],\"max\":1,\"max_patch_size\":1024,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"AGENTS.md\"],\"protected_files_policy\":\"allowed\",\"protected_path_prefixes\":[\".github/\",\".agents/\"],\"target\":\"*\"},\"report_incomplete\":{}}" + GH_AW_CI_TRIGGER_TOKEN: ${{ secrets.PR_METRICS_TOKEN }} + GITHUB_TOKEN: ${{ secrets.PR_METRICS_TOKEN }} + with: + github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} + script: | + const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require('${{ runner.temp }}/gh-aw/actions/safe_output_handler_manager.cjs'); + await main(); + - name: Upload Safe Outputs Items + if: always() + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: safe-outputs-items + path: | + /tmp/gh-aw/safe-output-items.jsonl + /tmp/gh-aw/temporary-id-map.json + if-no-files-found: ignore + diff --git a/.github/workflows/update-ci-dependencies.md b/.github/workflows/update-ci-dependencies.md index 785253173..9d1a08837 100644 --- a/.github/workflows/update-ci-dependencies.md +++ b/.github/workflows/update-ci-dependencies.md @@ -50,11 +50,13 @@ safe-outputs: - release max: 1 if-no-changes: ignore - protected-files: - policy: fallback-to-issue - exclude: - - package.json - - .nvmrc + protected-files: allowed + allowed-files: + - .github/workflows/*.yml + - .github/azure-devops/*.yml + - package.json + - .nvmrc + github-token: ${{ secrets.PR_METRICS_TOKEN }} github-token-for-extra-empty-commit: ${{ secrets.PR_METRICS_TOKEN }} --- @@ -98,9 +100,11 @@ Files under `.github/azure-devops/*.yml`: ## Process -1. Confirm a single open pull request labelled `release` with the - `[Autogenerated] Release v` title prefix exists. If none matches, stop and - produce no output. +1. List open pull requests with `list_pull_requests` (state `open`), then filter + client side for both the `release` label and a title beginning with + `[Autogenerated] Release v`. Do not rely on GitHub search syntax for the + title – the brackets make it unreliable. Confirm exactly one pull request + matches; if none matches, stop and produce no output. 1. For each SHA-pinned GitHub Action, resolve the latest release and tag SHA: ```bash diff --git a/.gitignore b/.gitignore index fa6815dc4..1e85b94b3 100644 --- a/.gitignore +++ b/.gitignore @@ -139,3 +139,6 @@ typedocs # GitHub Actions Temporary Files github_conf/ super-linter-output/ + +# gh-aw Trial Artifacts +trials/ From 26444f14c2610f0cb0c14ffe66df83f8396da8e1 Mon Sep 17 00:00:00 2001 From: Muiris Woulfe Date: Tue, 21 Apr 2026 16:23:51 +0100 Subject: [PATCH 08/15] chore(ci): exclude gh-aw generated files from Super-Linter Add .github/agents/ and .github/workflows/*.lock.yml to FILTER_REGEX_EXCLUDE so Super-Linter skips files produced by gh aw compile, and give .gitattributes a trailing newline. --- .gitattributes | 2 +- .github/workflows/build.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitattributes b/.gitattributes index c1965c216..1b06f3ebf 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1 +1 @@ -.github/workflows/*.lock.yml linguist-generated=true merge=ours \ No newline at end of file +.github/workflows/*.lock.yml linguist-generated=true merge=ours diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e72a9d884..5fc76538c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -174,7 +174,7 @@ jobs: - name: Super-Linter uses: super-linter/super-linter@9e863354e3ff62e0727d37183162c4a88873df41 # v8.6.0 env: - FILTER_REGEX_EXCLUDE: .*dist/.* + FILTER_REGEX_EXCLUDE: .*(dist/|\.github/agents/|\.github/workflows/.*\.lock\.yml).* FIX_JSON_PRETTIER: true FIX_MARKDOWN_PRETTIER: true FIX_MARKDOWN: true From 7d11ddf1f419524f29496fd30eb87ccf34e1f074 Mon Sep 17 00:00:00 2001 From: Muiris Woulfe Date: Tue, 21 Apr 2026 16:32:05 +0100 Subject: [PATCH 09/15] chore(ci): skip autogenerated lock files from Checkov scan Super-Linter's FILTER_REGEX_EXCLUDE does not propagate to Checkov, which scans .github/workflows as a directory. Add a dedicated .checkov.yaml skip-path pattern so *.lock.yml files produced by gh aw compile are left to gh-aw's own policy guarantees. --- .github/linters/.checkov.yaml | 3 +++ .github/workflows/build.yml | 1 + 2 files changed, 4 insertions(+) create mode 100644 .github/linters/.checkov.yaml diff --git a/.github/linters/.checkov.yaml b/.github/linters/.checkov.yaml new file mode 100644 index 000000000..4c70f9ef9 --- /dev/null +++ b/.github/linters/.checkov.yaml @@ -0,0 +1,3 @@ +# Checkov configuration for Super-Linter. +skip-path: + - .*\.lock\.yml$ diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5fc76538c..045dec029 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -174,6 +174,7 @@ jobs: - name: Super-Linter uses: super-linter/super-linter@9e863354e3ff62e0727d37183162c4a88873df41 # v8.6.0 env: + CHECKOV_CONFIG_FILE: .checkov.yaml FILTER_REGEX_EXCLUDE: .*(dist/|\.github/agents/|\.github/workflows/.*\.lock\.yml).* FIX_JSON_PRETTIER: true FIX_MARKDOWN_PRETTIER: true From c4f5cf9a464678594c05014a750c8cc710d80bc8 Mon Sep 17 00:00:00 2001 From: Muiris Woulfe Date: Tue, 21 Apr 2026 16:39:21 +0100 Subject: [PATCH 10/15] chore(ci): use correct CHECKOV_FILE_NAME env for Super-Linter Super-Linter v8.6.0 resolves the Checkov config via CHECKOV_FILE_NAME relative to GITHUB_WORKSPACE, not CHECKOV_CONFIG_FILE. Point it at .github/linters/.checkov.yaml so the skip-path rule for *.lock.yml actually takes effect. --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 045dec029..12eb21095 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -174,7 +174,7 @@ jobs: - name: Super-Linter uses: super-linter/super-linter@9e863354e3ff62e0727d37183162c4a88873df41 # v8.6.0 env: - CHECKOV_CONFIG_FILE: .checkov.yaml + CHECKOV_FILE_NAME: .github/linters/.checkov.yaml FILTER_REGEX_EXCLUDE: .*(dist/|\.github/agents/|\.github/workflows/.*\.lock\.yml).* FIX_JSON_PRETTIER: true FIX_MARKDOWN_PRETTIER: true From c55fd3b7ba1b0bab5bcd35f232a72ee6ce3de1ad Mon Sep 17 00:00:00 2001 From: Muiris Woulfe Date: Tue, 21 Apr 2026 16:45:15 +0100 Subject: [PATCH 11/15] chore(ci): use bare .checkov.yaml filename for Super-Linter lookup Super-Linter resolves CHECKOV_FILE_NAME against LINTER_RULES_PATH (default .github/linters/), so the value must be a filename rather than a path. Mirrors the existing GITLEAKS_CONFIG_FILE convention. --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 12eb21095..fb8a935a6 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -174,7 +174,7 @@ jobs: - name: Super-Linter uses: super-linter/super-linter@9e863354e3ff62e0727d37183162c4a88873df41 # v8.6.0 env: - CHECKOV_FILE_NAME: .github/linters/.checkov.yaml + CHECKOV_FILE_NAME: .checkov.yaml FILTER_REGEX_EXCLUDE: .*(dist/|\.github/agents/|\.github/workflows/.*\.lock\.yml).* FIX_JSON_PRETTIER: true FIX_MARKDOWN_PRETTIER: true From 6c96d491e98340446cd91cb65642f9aabf9ae830 Mon Sep 17 00:00:00 2001 From: Muiris Woulfe Date: Tue, 21 Apr 2026 16:51:18 +0100 Subject: [PATCH 12/15] chore(ci): clear Super-Linter warnings Add a conventional-commits commitlint config so Super-Linter can run Git commit message validation instead of silently disabling it, and remove the deprecated VALIDATE_TYPESCRIPT_STANDARD env var. --- .github/linters/.commitlintrc.yml | 2 ++ .github/workflows/build.yml | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 .github/linters/.commitlintrc.yml diff --git a/.github/linters/.commitlintrc.yml b/.github/linters/.commitlintrc.yml new file mode 100644 index 000000000..9cb74a70c --- /dev/null +++ b/.github/linters/.commitlintrc.yml @@ -0,0 +1,2 @@ +extends: + - "@commitlint/config-conventional" diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index fb8a935a6..729499227 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -190,7 +190,6 @@ jobs: VALIDATE_BIOME_FORMAT: false VALIDATE_JSON: false VALIDATE_TYPESCRIPT_ES: false - VALIDATE_TYPESCRIPT_STANDARD: false - if: github.ref_name != 'main' name: Git – Test for Changes From 3581543b13f80e0498969b64d9c19897f9a0582e Mon Sep 17 00:00:00 2001 From: Muiris Woulfe Date: Tue, 21 Apr 2026 18:28:58 +0100 Subject: [PATCH 13/15] chore(ci): add copyright headers and align linter configs - Add Microsoft copyright headers to Checkov, commitlint, and Trivy configs to match the repo convention. - Ignore WTFPL (truncate-utf8-bytes transitive dep) in Trivy. - Fix natural-language hyphenation ("client-side") in the update-ci-dependencies workflow description. --- .github/linters/.checkov.yaml | 14 ++++++++++++-- .github/linters/.commitlintrc.yml | 4 ++++ .github/linters/trivy.yaml | 8 ++++++++ .github/workflows/update-ci-dependencies.md | 2 +- 4 files changed, 25 insertions(+), 3 deletions(-) diff --git a/.github/linters/.checkov.yaml b/.github/linters/.checkov.yaml index 4c70f9ef9..43c21712a 100644 --- a/.github/linters/.checkov.yaml +++ b/.github/linters/.checkov.yaml @@ -1,3 +1,13 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +--- # Checkov configuration for Super-Linter. -skip-path: - - .*\.lock\.yml$ +# +# Skip CKV_GHA_7 (empty workflow_dispatch inputs) because the only failure +# comes from the gh-aw-generated update-ci-dependencies.lock.yml, which uses +# an internal aw_context input managed by the Agentic Workflows framework. +# No editable workflow in this repo uses workflow_dispatch inputs, so this +# is effectively an exclusion of the autogenerated file. +skip-check: + - CKV_GHA_7 diff --git a/.github/linters/.commitlintrc.yml b/.github/linters/.commitlintrc.yml index 9cb74a70c..72bde9ed7 100644 --- a/.github/linters/.commitlintrc.yml +++ b/.github/linters/.commitlintrc.yml @@ -1,2 +1,6 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +--- extends: - "@commitlint/config-conventional" diff --git a/.github/linters/trivy.yaml b/.github/linters/trivy.yaml index 9ceb2eb0d..b6e1b8aa5 100644 --- a/.github/linters/trivy.yaml +++ b/.github/linters/trivy.yaml @@ -1,5 +1,13 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +--- scan: scanners: - misconfig - secret - license +license: + # WTFPL on transitive dep (truncate-utf8-bytes) — accepted for this repo. + ignored: + - WTFPL diff --git a/.github/workflows/update-ci-dependencies.md b/.github/workflows/update-ci-dependencies.md index 9d1a08837..056961b6d 100644 --- a/.github/workflows/update-ci-dependencies.md +++ b/.github/workflows/update-ci-dependencies.md @@ -101,7 +101,7 @@ Files under `.github/azure-devops/*.yml`: ## Process 1. List open pull requests with `list_pull_requests` (state `open`), then filter - client side for both the `release` label and a title beginning with + client-side for both the `release` label and a title beginning with `[Autogenerated] Release v`. Do not rely on GitHub search syntax for the title – the brackets make it unreliable. Confirm exactly one pull request matches; if none matches, stop and produce no output. From 9336be2460f8af42fa28f4823c1cd94f49a457c5 Mon Sep 17 00:00:00 2001 From: Muiris Woulfe Date: Tue, 21 Apr 2026 18:44:10 +0100 Subject: [PATCH 14/15] chore(ci): clear remaining Super-Linter warnings - Move .commitlintrc.yml to the repo root so Super-Linter's commitlint search picks it up. - Enable SAVE_SUPER_LINTER_SUMMARY since PR summary comments are on by default. - Disable Biome lint (ESLint/Stylelint own JS and CSS) and Python Black (Ruff covers Python; this repo has none anyway). --- .github/linters/.commitlintrc.yml => .commitlintrc.yml | 0 .github/workflows/build.yml | 3 +++ 2 files changed, 3 insertions(+) rename .github/linters/.commitlintrc.yml => .commitlintrc.yml (100%) diff --git a/.github/linters/.commitlintrc.yml b/.commitlintrc.yml similarity index 100% rename from .github/linters/.commitlintrc.yml rename to .commitlintrc.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 729499227..5625b6e0d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -185,10 +185,13 @@ jobs: GITHUB_TOKEN: ${{ secrets.PR_METRICS_TOKEN }} GITLEAKS_CONFIG_FILE: gitleaks.toml MARKDOWN_CONFIG_FILE: ../../.markdownlint.json + SAVE_SUPER_LINTER_SUMMARY: true SPELL_CODESPELL_CONFIG_FILE: .codespellrc # Disable linters that conflict with other linters. VALIDATE_BIOME_FORMAT: false + VALIDATE_BIOME_LINT: false VALIDATE_JSON: false + VALIDATE_PYTHON_BLACK: false VALIDATE_TYPESCRIPT_ES: false - if: github.ref_name != 'main' From 9622c4724cd320eaf46a08ba8d534280e287a898 Mon Sep 17 00:00:00 2001 From: Muiris Woulfe Date: Wed, 22 Apr 2026 10:11:28 +0100 Subject: [PATCH 15/15] fix(workflow): tighten allowed-files and drop az fallback guidance - Replace the .github/workflows/*.yml glob with an explicit list (build.yml, release-initiate.yml, release-publish.yml) so the agent cannot patch the gh-aw-generated update-ci-dependencies.lock.yml. - Remove the az authentication fallback from the template-ref step because az is not in the workflow's bash allowlist; tell the agent to leave the current ref in place and report the miss instead. --- .../workflows/update-ci-dependencies.lock.yml | 30 +++++++++---------- .github/workflows/update-ci-dependencies.md | 10 +++++-- 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/.github/workflows/update-ci-dependencies.lock.yml b/.github/workflows/update-ci-dependencies.lock.yml index 8b1a8610e..a2cc320b4 100644 --- a/.github/workflows/update-ci-dependencies.lock.yml +++ b/.github/workflows/update-ci-dependencies.lock.yml @@ -1,4 +1,4 @@ -# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"5196b45c82e0a498df2af601868f6c54c182e1530fc9cad58fe4a21f492b3e1d","compiler_version":"v0.68.3","strict":true,"agent_id":"copilot"} +# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"780110614c4161a11bfa5239f10bc587497548446d436c4211bb964db013cbb0","compiler_version":"v0.68.3","strict":true,"agent_id":"copilot"} # gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN","PR_METRICS_TOKEN"],"actions":[{"repo":"actions/checkout","sha":"de0fac2e4500dabe0009e67214ff5f5447ce83dd","version":"v6.0.2"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"373c709c69115d41ff229c7e5df9f8788daa9553","version":"v9"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"ba90f2186d7ad780ec640f364005fa24e797b360","version":"v0.68.3"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.25.20"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.25.20"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.25.20"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.2.19"},{"image":"ghcr.io/github/github-mcp-server:v0.32.0"},{"image":"node:lts-alpine"}]} # ___ _ _ # / _ \ | | (_) @@ -176,19 +176,19 @@ jobs: run: | bash "${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh" { - cat << 'GH_AW_PROMPT_24da50bb34eefe08_EOF' + cat << 'GH_AW_PROMPT_b6e8ca5241656eb9_EOF' - GH_AW_PROMPT_24da50bb34eefe08_EOF + GH_AW_PROMPT_b6e8ca5241656eb9_EOF cat "${RUNNER_TEMP}/gh-aw/prompts/xpia.md" cat "${RUNNER_TEMP}/gh-aw/prompts/temp_folder_prompt.md" cat "${RUNNER_TEMP}/gh-aw/prompts/markdown.md" cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_prompt.md" - cat << 'GH_AW_PROMPT_24da50bb34eefe08_EOF' + cat << 'GH_AW_PROMPT_b6e8ca5241656eb9_EOF' Tools: push_to_pull_request_branch, missing_tool, missing_data, noop - GH_AW_PROMPT_24da50bb34eefe08_EOF + GH_AW_PROMPT_b6e8ca5241656eb9_EOF cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_push_to_pr_branch.md" - cat << 'GH_AW_PROMPT_24da50bb34eefe08_EOF' + cat << 'GH_AW_PROMPT_b6e8ca5241656eb9_EOF' The following GitHub context information is available for this workflow: @@ -221,12 +221,12 @@ jobs: - **Note**: If a branch you need is not in the list above and is not listed as an additional fetched ref, it has NOT been checked out. For private repositories you cannot fetch it without proper authentication. If the branch is required and not available, exit with an error and ask the user to add it to the `fetch:` option of the `checkout:` configuration (e.g., `fetch: ["refs/pulls/open/*"]` for all open PR refs, or `fetch: ["main", "feature/my-branch"]` for specific branches). - GH_AW_PROMPT_24da50bb34eefe08_EOF + GH_AW_PROMPT_b6e8ca5241656eb9_EOF cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md" - cat << 'GH_AW_PROMPT_24da50bb34eefe08_EOF' + cat << 'GH_AW_PROMPT_b6e8ca5241656eb9_EOF' {{#runtime-import .github/workflows/update-ci-dependencies.md}} - GH_AW_PROMPT_24da50bb34eefe08_EOF + GH_AW_PROMPT_b6e8ca5241656eb9_EOF } > "$GH_AW_PROMPT" - name: Interpolate variables and render templates uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9 @@ -408,9 +408,9 @@ jobs: mkdir -p "${RUNNER_TEMP}/gh-aw/safeoutputs" mkdir -p /tmp/gh-aw/safeoutputs mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs - cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << GH_AW_SAFE_OUTPUTS_CONFIG_e3baffdb24bb6476_EOF - {"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"push_to_pull_request_branch":{"allowed_files":[".github/workflows/*.yml",".github/azure-devops/*.yml","package.json",".nvmrc"],"github-token":"${PR_METRICS_TOKEN}","if_no_changes":"ignore","labels":["release"],"max":1,"max_patch_size":1024,"protected_files":["package.json","bun.lockb","bunfig.toml","deno.json","deno.jsonc","deno.lock","global.json","NuGet.Config","Directory.Packages.props","mix.exs","mix.lock","go.mod","go.sum","stack.yaml","stack.yaml.lock","pom.xml","build.gradle","build.gradle.kts","settings.gradle","settings.gradle.kts","gradle.properties","package-lock.json","yarn.lock","pnpm-lock.yaml","npm-shrinkwrap.json","requirements.txt","Pipfile","Pipfile.lock","pyproject.toml","setup.py","setup.cfg","Gemfile","Gemfile.lock","uv.lock","CODEOWNERS"],"protected_files_policy":"allowed","protected_path_prefixes":[".github/",".agents/"],"target":"*"},"report_incomplete":{}} - GH_AW_SAFE_OUTPUTS_CONFIG_e3baffdb24bb6476_EOF + cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << GH_AW_SAFE_OUTPUTS_CONFIG_f78e6cc69a8774a8_EOF + {"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"push_to_pull_request_branch":{"allowed_files":[".github/workflows/build.yml",".github/workflows/release-initiate.yml",".github/workflows/release-publish.yml",".github/azure-devops/*.yml","package.json",".nvmrc"],"github-token":"${PR_METRICS_TOKEN}","if_no_changes":"ignore","labels":["release"],"max":1,"max_patch_size":1024,"protected_files":["package.json","bun.lockb","bunfig.toml","deno.json","deno.jsonc","deno.lock","global.json","NuGet.Config","Directory.Packages.props","mix.exs","mix.lock","go.mod","go.sum","stack.yaml","stack.yaml.lock","pom.xml","build.gradle","build.gradle.kts","settings.gradle","settings.gradle.kts","gradle.properties","package-lock.json","yarn.lock","pnpm-lock.yaml","npm-shrinkwrap.json","requirements.txt","Pipfile","Pipfile.lock","pyproject.toml","setup.py","setup.cfg","Gemfile","Gemfile.lock","uv.lock","CODEOWNERS"],"protected_files_policy":"allowed","protected_path_prefixes":[".github/",".agents/"],"target":"*"},"report_incomplete":{}} + GH_AW_SAFE_OUTPUTS_CONFIG_f78e6cc69a8774a8_EOF - name: Write Safe Outputs Tools env: GH_AW_TOOLS_META_JSON: | @@ -592,7 +592,7 @@ jobs: export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host -v /var/run/docker.sock:/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e GH_AW_SAFE_OUTPUTS_PORT -e GH_AW_SAFE_OUTPUTS_API_KEY -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw ghcr.io/github/gh-aw-mcpg:v0.2.19' mkdir -p /home/runner/.copilot - cat << GH_AW_MCP_CONFIG_413712401644109d_EOF | bash "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.sh" + cat << GH_AW_MCP_CONFIG_9a0b6a37dfb80cc1_EOF | bash "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.sh" { "mcpServers": { "github": { @@ -633,7 +633,7 @@ jobs: "payloadDir": "${MCP_GATEWAY_PAYLOAD_DIR}" } } - GH_AW_MCP_CONFIG_413712401644109d_EOF + GH_AW_MCP_CONFIG_9a0b6a37dfb80cc1_EOF - name: Download activation artifact uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: @@ -1265,7 +1265,7 @@ jobs: GH_AW_ALLOWED_DOMAINS: "api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,github.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,ppa.launchpad.net,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,telemetry.enterprise.githubcopilot.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.googleapis.com" GITHUB_SERVER_URL: ${{ github.server_url }} GITHUB_API_URL: ${{ github.api_url }} - GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"true\"},\"push_to_pull_request_branch\":{\"allowed_files\":[\".github/workflows/*.yml\",\".github/azure-devops/*.yml\",\"package.json\",\".nvmrc\"],\"github-token\":\"${{ secrets.PR_METRICS_TOKEN }}\",\"if_no_changes\":\"ignore\",\"labels\":[\"release\"],\"max\":1,\"max_patch_size\":1024,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"AGENTS.md\"],\"protected_files_policy\":\"allowed\",\"protected_path_prefixes\":[\".github/\",\".agents/\"],\"target\":\"*\"},\"report_incomplete\":{}}" + GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"true\"},\"push_to_pull_request_branch\":{\"allowed_files\":[\".github/workflows/build.yml\",\".github/workflows/release-initiate.yml\",\".github/workflows/release-publish.yml\",\".github/azure-devops/*.yml\",\"package.json\",\".nvmrc\"],\"github-token\":\"${{ secrets.PR_METRICS_TOKEN }}\",\"if_no_changes\":\"ignore\",\"labels\":[\"release\"],\"max\":1,\"max_patch_size\":1024,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"AGENTS.md\"],\"protected_files_policy\":\"allowed\",\"protected_path_prefixes\":[\".github/\",\".agents/\"],\"target\":\"*\"},\"report_incomplete\":{}}" GH_AW_CI_TRIGGER_TOKEN: ${{ secrets.PR_METRICS_TOKEN }} GITHUB_TOKEN: ${{ secrets.PR_METRICS_TOKEN }} with: diff --git a/.github/workflows/update-ci-dependencies.md b/.github/workflows/update-ci-dependencies.md index 056961b6d..aa4c73423 100644 --- a/.github/workflows/update-ci-dependencies.md +++ b/.github/workflows/update-ci-dependencies.md @@ -52,7 +52,9 @@ safe-outputs: if-no-changes: ignore protected-files: allowed allowed-files: - - .github/workflows/*.yml + - .github/workflows/build.yml + - .github/workflows/release-initiate.yml + - .github/workflows/release-publish.yml - .github/azure-devops/*.yml - package.json - .nvmrc @@ -127,8 +129,10 @@ Files under `.github/azure-devops/*.yml`: git ls-remote --tags ``` - The 1ES templates are hosted in Azure DevOps; authenticate via `az` if the - listing is restricted. + The 1ES templates are hosted in Azure DevOps. Use the credentials already + available to `git`. If tag listing is restricted with those credentials, + leave the current ref unchanged and report that the latest tag could not be + verified with the available access. 1. Save changes while preserving formatting: trailing newlines, comment spacing, and two-space indentation.