Add Copilot code review quality guidance (#3665)

* Add Copilot code review quality guidance

Add a repository-specific Copilot Code Review skill for repo-fit, provenance, differentiation, validation, and marketing-signal review. Wire it into the repo review instructions and CODEOWNERS, add an advisory PR quality-signal workflow, and tighten the Learning Hub updater instructions to reuse existing bot PRs instead of creating duplicate stale update PRs.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

* Fix PR review workflow feedback

Add constrained safe outputs for reusing and closing Learning Hub bot pull requests, and declare the quality-signal workflow name in source frontmatter.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

* Upgrade agentic workflows

Rebase the PR onto main and upgrade gh-aw to v0.88.8. Refresh setup actions, generated workflow locks, container pins, and updater permissions.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
Aaron Powell
2026-09-23 13:26:28 +10:00
committed by GitHub
co-authored by Copilot App
parent a89cd67e19
commit d7e4ad98ed
19 changed files with 6248 additions and 2370 deletions
File diff suppressed because one or more lines are too long
+106 -68
View File
@@ -1,4 +1,4 @@
# This file was automatically generated by pkg/workflow/maintenance_workflow.go (v0.84.3). DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md
# This file was automatically generated by pkg/workflow/maintenance_workflow.go (v0.88.8). DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md
#
# ___ _ _
# / _ \ | | (_)
@@ -44,9 +44,9 @@ on:
description: 'Optional maintenance operation to run'
required: false
type: choice
default: ''
default: 'none'
options:
- ''
- 'none'
- 'disable'
- 'enable'
- 'update'
@@ -88,13 +88,13 @@ permissions: {}
jobs:
close-expired-discussions:
if: ${{ (!(github.event.repository.fork)) && github.event_name != 'push' && (github.event_name != 'workflow_dispatch' && github.event_name != 'workflow_call' || inputs.operation == '') }}
if: ${{ (!(github.event.repository.fork)) && github.event_name != 'push' && (github.event_name != 'workflow_dispatch' && github.event_name != 'workflow_call' || inputs.operation == '' || inputs.operation == 'none') }}
runs-on: ubuntu-slim
permissions:
discussions: write
steps:
- name: Setup Scripts
uses: github/gh-aw-actions/setup@c863074b673419603d146aab585e2986ef08deec # v0.84.3
uses: github/gh-aw-actions/setup@5e508589e03a7757a7e05b26e834292f5445bfb6 # v0.88.8
with:
destination: ${{ runner.temp }}/gh-aw/actions
@@ -102,18 +102,20 @@ jobs:
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
script: |
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
const path = require('path');
const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
setupGlobals(core, github, context, exec, io, getOctokit);
const { main } = require('${{ runner.temp }}/gh-aw/actions/close_expired_discussions.cjs');
const { main } = require(path.join(actionsDir, 'close_expired_discussions.cjs'));
await main();
close-expired-issues:
if: ${{ (!(github.event.repository.fork)) && github.event_name != 'push' && (github.event_name != 'workflow_dispatch' && github.event_name != 'workflow_call' || inputs.operation == '') }}
if: ${{ (!(github.event.repository.fork)) && github.event_name != 'push' && (github.event_name != 'workflow_dispatch' && github.event_name != 'workflow_call' || inputs.operation == '' || inputs.operation == 'none') }}
runs-on: ubuntu-slim
permissions:
issues: write
steps:
- name: Setup Scripts
uses: github/gh-aw-actions/setup@c863074b673419603d146aab585e2986ef08deec # v0.84.3
uses: github/gh-aw-actions/setup@5e508589e03a7757a7e05b26e834292f5445bfb6 # v0.88.8
with:
destination: ${{ runner.temp }}/gh-aw/actions
@@ -121,18 +123,20 @@ jobs:
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
script: |
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
const path = require('path');
const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
setupGlobals(core, github, context, exec, io, getOctokit);
const { main } = require('${{ runner.temp }}/gh-aw/actions/close_expired_issues.cjs');
const { main } = require(path.join(actionsDir, 'close_expired_issues.cjs'));
await main();
close-expired-pull-requests:
if: ${{ (!(github.event.repository.fork)) && github.event_name != 'push' && (github.event_name != 'workflow_dispatch' && github.event_name != 'workflow_call' || inputs.operation == '') }}
if: ${{ (!(github.event.repository.fork)) && github.event_name != 'push' && (github.event_name != 'workflow_dispatch' && github.event_name != 'workflow_call' || inputs.operation == '' || inputs.operation == 'none') }}
runs-on: ubuntu-slim
permissions:
pull-requests: write
steps:
- name: Setup Scripts
uses: github/gh-aw-actions/setup@c863074b673419603d146aab585e2986ef08deec # v0.84.3
uses: github/gh-aw-actions/setup@5e508589e03a7757a7e05b26e834292f5445bfb6 # v0.88.8
with:
destination: ${{ runner.temp }}/gh-aw/actions
@@ -140,19 +144,21 @@ jobs:
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
script: |
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
const path = require('path');
const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
setupGlobals(core, github, context, exec, io, getOctokit);
const { main } = require('${{ runner.temp }}/gh-aw/actions/close_expired_pull_requests.cjs');
const { main } = require(path.join(actionsDir, 'close_expired_pull_requests.cjs'));
await main();
cleanup-cache-memory:
if: ${{ (!(github.event.repository.fork)) && github.event_name != 'push' && (github.event_name != 'workflow_dispatch' && github.event_name != 'workflow_call' || inputs.operation == '' || inputs.operation == 'clean_cache_memories') }}
if: ${{ (!(github.event.repository.fork)) && github.event_name != 'push' && (github.event_name != 'workflow_dispatch' && github.event_name != 'workflow_call' || inputs.operation == '' || inputs.operation == 'none' || inputs.operation == 'clean_cache_memories') }}
runs-on: ubuntu-slim
permissions:
actions: write
steps:
- name: Setup Scripts
uses: github/gh-aw-actions/setup@c863074b673419603d146aab585e2986ef08deec # v0.84.3
uses: github/gh-aw-actions/setup@5e508589e03a7757a7e05b26e834292f5445bfb6 # v0.88.8
with:
destination: ${{ runner.temp }}/gh-aw/actions
@@ -160,13 +166,15 @@ jobs:
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
script: |
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
const path = require('path');
const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
setupGlobals(core, github, context, exec, io, getOctokit);
const { main } = require('${{ runner.temp }}/gh-aw/actions/cleanup_cache_memory.cjs');
const { main } = require(path.join(actionsDir, 'cleanup_cache_memory.cjs'));
await main();
run_operation:
if: ${{ (github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call') && inputs.operation != '' && inputs.operation != 'safe_outputs' && inputs.operation != 'create_labels' && inputs.operation != 'activity_report' && inputs.operation != 'close_agentic_workflows_issues' && inputs.operation != 'clean_cache_memories' && inputs.operation != 'update_pull_request_branches' && inputs.operation != 'validate' && inputs.operation != 'forecast' && (!(github.event.repository.fork)) }}
if: ${{ (github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call') && inputs.operation != '' && inputs.operation != 'none' && inputs.operation != 'safe_outputs' && inputs.operation != 'create_labels' && inputs.operation != 'activity_report' && inputs.operation != 'close_agentic_workflows_issues' && inputs.operation != 'clean_cache_memories' && inputs.operation != 'update_pull_request_branches' && inputs.operation != 'validate' && inputs.operation != 'forecast' && (!(github.event.repository.fork)) }}
runs-on: ubuntu-slim
permissions:
actions: write
@@ -181,7 +189,7 @@ jobs:
persist-credentials: false
- name: Setup Scripts
uses: github/gh-aw-actions/setup@c863074b673419603d146aab585e2986ef08deec # v0.84.3
uses: github/gh-aw-actions/setup@5e508589e03a7757a7e05b26e834292f5445bfb6 # v0.88.8
with:
destination: ${{ runner.temp }}/gh-aw/actions
@@ -190,15 +198,17 @@ jobs:
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
const path = require('path');
const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
setupGlobals(core, github, context, exec, io, getOctokit);
const { main } = require('${{ runner.temp }}/gh-aw/actions/check_team_member.cjs');
const { main } = require(path.join(actionsDir, 'check_team_member.cjs'));
await main();
- name: Install gh-aw
uses: github/gh-aw-actions/setup-cli@c863074b673419603d146aab585e2986ef08deec # v0.84.3
uses: github/gh-aw-actions/setup-cli@5e508589e03a7757a7e05b26e834292f5445bfb6 # v0.88.8
with:
version: v0.84.3
version: v0.88.8
- name: Run operation
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
@@ -209,9 +219,11 @@ jobs:
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
const path = require('path');
const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
setupGlobals(core, github, context, exec, io, getOctokit);
const { main } = require('${{ runner.temp }}/gh-aw/actions/run_operation_update_upgrade.cjs');
const { main } = require(path.join(actionsDir, 'run_operation_update_upgrade.cjs'));
await main();
- name: Record outputs
@@ -228,7 +240,7 @@ jobs:
pull-requests: write
steps:
- name: Setup Scripts
uses: github/gh-aw-actions/setup@c863074b673419603d146aab585e2986ef08deec # v0.84.3
uses: github/gh-aw-actions/setup@5e508589e03a7757a7e05b26e834292f5445bfb6 # v0.88.8
with:
destination: ${{ runner.temp }}/gh-aw/actions
@@ -237,9 +249,11 @@ jobs:
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
const path = require('path');
const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
setupGlobals(core, github, context, exec, io, getOctokit);
const { main } = require('${{ runner.temp }}/gh-aw/actions/check_team_member.cjs');
const { main } = require(path.join(actionsDir, 'check_team_member.cjs'));
await main();
- name: Update pull request branches
@@ -249,9 +263,11 @@ jobs:
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
const path = require('path');
const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
setupGlobals(core, github, context, exec, io, getOctokit);
const { main } = require('${{ runner.temp }}/gh-aw/actions/update_pull_request_branches.cjs');
const { main } = require(path.join(actionsDir, 'update_pull_request_branches.cjs'));
await main();
apply_safe_outputs:
@@ -275,7 +291,7 @@ jobs:
persist-credentials: false
- name: Setup Scripts
uses: github/gh-aw-actions/setup@c863074b673419603d146aab585e2986ef08deec # v0.84.3
uses: github/gh-aw-actions/setup@5e508589e03a7757a7e05b26e834292f5445bfb6 # v0.88.8
with:
destination: ${{ runner.temp }}/gh-aw/actions
@@ -284,9 +300,11 @@ jobs:
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
const path = require('path');
const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
setupGlobals(core, github, context, exec, io, getOctokit);
const { main } = require('${{ runner.temp }}/gh-aw/actions/check_team_member.cjs');
const { main } = require(path.join(actionsDir, 'check_team_member.cjs'));
await main();
- name: Apply Safe Outputs
@@ -297,9 +315,11 @@ jobs:
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
const path = require('path');
const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
setupGlobals(core, github, context, exec, io, getOctokit);
const { main } = require('${{ runner.temp }}/gh-aw/actions/apply_safe_outputs_replay.cjs');
const { main } = require(path.join(actionsDir, 'apply_safe_outputs_replay.cjs'));
await main();
- name: Record outputs
@@ -321,7 +341,7 @@ jobs:
persist-credentials: false
- name: Setup Scripts
uses: github/gh-aw-actions/setup@c863074b673419603d146aab585e2986ef08deec # v0.84.3
uses: github/gh-aw-actions/setup@5e508589e03a7757a7e05b26e834292f5445bfb6 # v0.88.8
with:
destination: ${{ runner.temp }}/gh-aw/actions
@@ -330,15 +350,17 @@ jobs:
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
const path = require('path');
const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
setupGlobals(core, github, context, exec, io, getOctokit);
const { main } = require('${{ runner.temp }}/gh-aw/actions/check_team_member.cjs');
const { main } = require(path.join(actionsDir, 'check_team_member.cjs'));
await main();
- name: Install gh-aw
uses: github/gh-aw-actions/setup-cli@c863074b673419603d146aab585e2986ef08deec # v0.84.3
uses: github/gh-aw-actions/setup-cli@5e508589e03a7757a7e05b26e834292f5445bfb6 # v0.88.8
with:
version: v0.84.3
version: v0.88.8
- name: Create missing labels
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
@@ -347,9 +369,11 @@ jobs:
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
const path = require('path');
const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
setupGlobals(core, github, context, exec, io, getOctokit);
const { main } = require('${{ runner.temp }}/gh-aw/actions/create_labels.cjs');
const { main } = require(path.join(actionsDir, 'create_labels.cjs'));
await main();
activity_report:
@@ -367,7 +391,7 @@ jobs:
persist-credentials: false
- name: Setup Scripts
uses: github/gh-aw-actions/setup@c863074b673419603d146aab585e2986ef08deec # v0.84.3
uses: github/gh-aw-actions/setup@5e508589e03a7757a7e05b26e834292f5445bfb6 # v0.88.8
with:
destination: ${{ runner.temp }}/gh-aw/actions
@@ -376,15 +400,17 @@ jobs:
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
const path = require('path');
const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
setupGlobals(core, github, context, exec, io, getOctokit);
const { main } = require('${{ runner.temp }}/gh-aw/actions/check_team_member.cjs');
const { main } = require(path.join(actionsDir, 'check_team_member.cjs'));
await main();
- name: Install gh-aw
uses: github/gh-aw-actions/setup-cli@c863074b673419603d146aab585e2986ef08deec # v0.84.3
uses: github/gh-aw-actions/setup-cli@5e508589e03a7757a7e05b26e834292f5445bfb6 # v0.88.8
with:
version: v0.84.3
version: v0.88.8
- name: Restore activity report logs cache
id: activity_report_logs_cache
@@ -472,7 +498,7 @@ jobs:
persist-credentials: false
- name: Setup Scripts
uses: github/gh-aw-actions/setup@c863074b673419603d146aab585e2986ef08deec # v0.84.3
uses: github/gh-aw-actions/setup@5e508589e03a7757a7e05b26e834292f5445bfb6 # v0.88.8
with:
destination: ${{ runner.temp }}/gh-aw/actions
@@ -481,15 +507,17 @@ jobs:
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
const path = require('path');
const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
setupGlobals(core, github, context, exec, io, getOctokit);
const { main } = require('${{ runner.temp }}/gh-aw/actions/check_team_member.cjs');
const { main } = require(path.join(actionsDir, 'check_team_member.cjs'));
await main();
- name: Install gh-aw
uses: github/gh-aw-actions/setup-cli@c863074b673419603d146aab585e2986ef08deec # v0.84.3
uses: github/gh-aw-actions/setup-cli@5e508589e03a7757a7e05b26e834292f5445bfb6 # v0.88.8
with:
version: v0.84.3
version: v0.88.8
- name: Restore forecast report logs cache
id: forecast_report_logs_cache
@@ -552,9 +580,11 @@ jobs:
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
const path = require('path');
const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
setupGlobals(core, github, context, exec, io, getOctokit);
const { main } = require('${{ runner.temp }}/gh-aw/actions/create_forecast_issue.cjs');
const { main } = require(path.join(actionsDir, 'create_forecast_issue.cjs'));
await main();
close_agentic_workflows_issues:
@@ -564,7 +594,7 @@ jobs:
issues: write
steps:
- name: Setup Scripts
uses: github/gh-aw-actions/setup@c863074b673419603d146aab585e2986ef08deec # v0.84.3
uses: github/gh-aw-actions/setup@5e508589e03a7757a7e05b26e834292f5445bfb6 # v0.88.8
with:
destination: ${{ runner.temp }}/gh-aw/actions
@@ -573,9 +603,11 @@ jobs:
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
const path = require('path');
const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
setupGlobals(core, github, context, exec, io, getOctokit);
const { main } = require('${{ runner.temp }}/gh-aw/actions/check_team_member.cjs');
const { main } = require(path.join(actionsDir, 'check_team_member.cjs'));
await main();
- name: Close no-repro agentic-workflows issues
@@ -583,9 +615,11 @@ jobs:
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
const path = require('path');
const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
setupGlobals(core, github, context, exec, io, getOctokit);
const { main } = require('${{ runner.temp }}/gh-aw/actions/close_agentic_workflows_issues.cjs');
const { main } = require(path.join(actionsDir, 'close_agentic_workflows_issues.cjs'));
await main();
validate_workflows:
@@ -601,7 +635,7 @@ jobs:
persist-credentials: false
- name: Setup Scripts
uses: github/gh-aw-actions/setup@c863074b673419603d146aab585e2986ef08deec # v0.84.3
uses: github/gh-aw-actions/setup@5e508589e03a7757a7e05b26e834292f5445bfb6 # v0.88.8
with:
destination: ${{ runner.temp }}/gh-aw/actions
@@ -610,15 +644,17 @@ jobs:
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
const path = require('path');
const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
setupGlobals(core, github, context, exec, io, getOctokit);
const { main } = require('${{ runner.temp }}/gh-aw/actions/check_team_member.cjs');
const { main } = require(path.join(actionsDir, 'check_team_member.cjs'));
await main();
- name: Install gh-aw
uses: github/gh-aw-actions/setup-cli@c863074b673419603d146aab585e2986ef08deec # v0.84.3
uses: github/gh-aw-actions/setup-cli@5e508589e03a7757a7e05b26e834292f5445bfb6 # v0.88.8
with:
version: v0.84.3
version: v0.88.8
- name: Validate workflows and file issue on findings
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
@@ -627,7 +663,9 @@ jobs:
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
const path = require('path');
const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions');
const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs'));
setupGlobals(core, github, context, exec, io, getOctokit);
const { main } = require('${{ runner.temp }}/gh-aw/actions/run_validate_workflows.cjs');
const { main } = require(path.join(actionsDir, 'run_validate_workflows.cjs'));
await main();
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+6 -4
View File
@@ -19,8 +19,10 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Install gh-aw extension
uses: github/gh-aw-actions/setup-cli@c863074b673419603d146aab585e2986ef08deec # v0.84.3
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
version: v0.84.3
persist-credentials: false
- name: Install gh-aw extension
uses: github/gh-aw-actions/setup-cli@5e508589e03a7757a7e05b26e834292f5445bfb6 # v0.88.8
with:
version: v0.88.8
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+55 -3
View File
@@ -7,11 +7,15 @@ on:
permissions:
contents: read
copilot-requests: write
pull-requests: read
tools:
edit:
web-fetch:
github:
toolsets: [repos]
toolsets: [repos, pull_requests]
checkout:
fetch: ["*"]
fetch-depth: 0
safe-outputs:
allowed-domains:
- github.com
@@ -22,6 +26,19 @@ safe-outputs:
labels: [automated-update, copilot-updates]
title-prefix: "[bot] "
base-branch: main
allowed-files:
- "website/learning-hub/**/*.md"
push-to-pull-request-branch:
target: "*"
required-title-prefix: "[bot] "
required-labels: [automated-update, copilot-updates]
allowed-files:
- "website/learning-hub/**/*.md"
close-pull-request:
target: "*"
required-labels: [automated-update, copilot-updates]
required-title-prefix: "[bot] "
max: 5
---
# Check for Awesome GitHub Copilot Updates
@@ -92,9 +109,31 @@ To create a new page:
If the new information can be added to existing pages, edit those pages to include refinements, new sections, or updated information as needed, following the content model above. Make sure to update any relevant links in the "Further Reading" sections.
## Step 4 — Open a pull request
## Step 4 — Reuse or update the existing bot pull request
Create a pull request with your changes, using the `main` branch as the base branch. The PR title should summarize what was updated (e.g., "Add/plan command and model marketplace documentation"). The PR body should list:
Before opening a new pull request, use GitHub pull request tooling to find open
PRs with the `automated-update` and `copilot-updates` labels and a `[bot] `
title prefix. Identify whether any matching PR is already updating the same
Learning Hub area.
If a matching PR already exists:
1. Use the `push_to_pull_request_branch` safe-output tool to push the changes
onto that PR's branch instead of creating a new PR. This tool can only target
PRs that carry both labels and the `[bot] ` title prefix.
2. Keep the branch and title stable so the update remains a single, current
review thread.
3. If an older matching PR is stale or clearly superseded by the newer content,
use the `close_pull_request` safe-output tool to close it with a short
explanation such as "Superseded by newer automated update".
4. Prefer a single active PR that reflects the latest information.
Only use the `create_pull_request` safe-output tool to open a fresh PR when no
relevant open bot PR exists for the same content area.
When creating a new PR, use the `main` branch as the base branch. The PR title
should summarize what was updated (for example, "Add/plan command and model
marketplace documentation"). The PR body should list:
1. What new features or changes were found
2. What sections of the guide were updated
@@ -102,3 +141,16 @@ Create a pull request with your changes, using the `main` branch as the base bra
4. **Content cleanup** — what older inline version notes were consolidated, rewritten as current behavior, or moved into a Compatibility and Migration Notes section, or a brief note that none needed changes this run
The PR should target the `main` branch and include the labels `automated-update` and `copilot-updates`.
## Step 5 — Avoid duplicate bot churn
Do not create a new PR when the same content is already being tracked in a
current open bot PR — push to it instead (Step 4).
If the repo already has one or more older bot PRs for near-identical Learning Hub changes, prefer to:
- push the update to the newest relevant PR via `push_to_pull_request_branch`
- close stale duplicates via `close_pull_request` with a short explanation such as "Superseded by newer automated update"
- avoid leaving the maintainers to triage multiple almost-identical docs PRs
This keeps the automation loop tight and reduces review noise.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+120
View File
@@ -0,0 +1,120 @@
---
name: PR Quality Signal Review
description: 'Advisory review for PR quality signals: repo fit, AI disclosure, duplication risk, and marketing-heavy submissions'
on:
pull_request:
types: [opened, reopened, synchronize, edited]
permissions:
contents: read
pull-requests: read
tools:
github:
toolsets: [repos, pull_requests]
safe-outputs:
add-comment:
max: 1
hide-older-comments: true
noop:
report-as-issue: false
---
# PR Quality Signal Review
You are an AI reviewer helping maintain the signal quality of submissions to this repository.
Your job is to look for high-probability review signals that suggest a pull request may be low-value, shallow, duplicate, or overly marketing-focused rather than clearly useful to the repository.
## Scope
Review pull requests that touch the repository's core resource directories and content, with special attention to:
- `agents/`
- `instructions/`
- `skills/`
- `workflows/`
- `hooks/`
- `plugins/`
- `website/`
This workflow is advisory only. It should flag likely quality issues and suggest a tighter review focus, but it should not block or approve a merge on its own.
## Step 1 — Gather PR context
Read the PR metadata for the current pull request, including:
- title
- description/body
- author login
- labels
- changed files
If the PR title ends with `🤖🤖🤖`, treat that as an explicit AI-disclosure signal. This is not automatically a bad submission, but it is a signal that the author should make the value and repository fit obvious and concrete.
## Step 2 — Evaluate high-signal quality checks
Assess the PR against these signals, in order of confidence:
### 1. Repository fit and usefulness
Look for evidence that the contribution solves a specific, real problem in the repository's scope.
Flag for review when the PR:
- has vague or generic framing with little concrete value
- reads like self-promotion or product marketing rather than a useful contribution
- proposes overlap with existing resources without a clear differentiator
- adds a broad "AI can do everything" pattern with no domain-specific constraint or workflow
- changes website or docs content without a clear factual update tied to a feature, migration, or user need
### 2. AI disclosure and provenance
If `🤖🤖🤖` is present, check whether the PR body explains:
- what was generated or iterated with AI
- why the content is still useful and repo-relevant
- whether the author tested or validated the result
A PR that uses AI but does not explain the value beyond "I prompted an agent" is a weaker signal.
### 3. Duplicate or low-differentiation risk
Compare the changed files to existing resources in the repository. If the PR appears to be a near-duplicate, a reworded version of an existing pattern, or a marketing wrapper around a generic capability, note it as a reviewer signal.
### 4. Missing evidence
Flag when there is no clear validation or rationale, such as:
- no examples or usage guidance
- no tests, validation steps, or operational constraint
- no explanation of why the value is not already covered by a stronger existing resource
## Step 3 — Produce a single review comment
If one or more high-confidence signals are present, leave a single PR comment in this format:
```markdown
## ⚠️ PR Quality Signal Review
This PR shows one or more review signals that deserve a closer look before merge.
| Signal | Evidence | Recommendation |
|---|---|---|
| Repo fit | <short description> | <what to clarify or tighten> |
| AI disclosure | <AI marker or explanation status> | <ask for concrete value and validation> |
| Marketing-heavy framing | <why this looks promotional> | <refocus on concrete user need and repo fit> |
| Duplicate / low differentiation | <why this overlaps existing content> | <explain unique value or merge into existing coverage> |
| Missing evidence | <what is absent> | <add examples, tests, or rationale> |
This is an advisory signal review only. It does not replace human judgment.
```
If the PR looks healthy and does not show high-confidence quality concerns, call `noop` with the message:
`No high-confidence quality signals detected in this PR. Repo fit and value look reasonable.`
## Guidelines
- Be conservative: only call out issues when the signal is strong and actionable.
- Treat `🤖🤖🤖` as a signal of provenance, not a negative by itself.
- Prefer repo-fit, clarity, evidence, and differentiation over raw file count or "vibe".
- Keep the feedback brief and specific enough for a maintainer to act on quickly.
- If a PR is clearly a trusted-source submission (for example, a GitHub/Microsoft plugin submission), do not flag it merely because it is automated or externally sourced. Use the signal map for low-signal and low-value items, not trusted paths.
File diff suppressed because one or more lines are too long