diff --git a/.github/workflows/cli-for-beginners-sync.lock.yml b/.github/workflows/cli-for-beginners-sync.lock.yml index abd0ba370..ea688351d 100644 --- a/.github/workflows/cli-for-beginners-sync.lock.yml +++ b/.github/workflows/cli-for-beginners-sync.lock.yml @@ -1,13 +1,13 @@ # gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"b256feb874346cc27a15b2e35925c0a556b4ca2ccc9176856d46a02436d36290","compiler_version":"v0.72.1","strict":true,"agent_id":"copilot"} # gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_CI_TRIGGER_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN"],"actions":[{"repo":"actions/cache/restore","sha":"27d5ce7f107fe9357f9df03efb73ab90386fccae","version":"v5.0.5"},{"repo":"actions/cache/save","sha":"27d5ce7f107fe9357f9df03efb73ab90386fccae","version":"v5.0.5"},{"repo":"actions/checkout","sha":"de0fac2e4500dabe0009e67214ff5f5447ce83dd","version":"v6.0.2"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9"},{"repo":"actions/setup-node","sha":"48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e","version":"v6.4.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"bc56a0cad2f450c562810785ef38649c04db812a","version":"v0.72.1"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.25.41"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.25.41"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.25.41"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.3.6","digest":"sha256:2bb8eef86006a4c5963c55616a9c51c32f27bfdecb023b8aa6f91f6718d9171c","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.3.6@sha256:2bb8eef86006a4c5963c55616a9c51c32f27bfdecb023b8aa6f91f6718d9171c"},{"image":"ghcr.io/github/github-mcp-server:v1.0.3","digest":"sha256:2ac27ef03461ef2b877031b838a7d1fd7f12b12d4ace7796d8cad91446d55959","pinned_image":"ghcr.io/github/github-mcp-server:v1.0.3@sha256:2ac27ef03461ef2b877031b838a7d1fd7f12b12d4ace7796d8cad91446d55959"},{"image":"node:lts-alpine","digest":"sha256:d1b3b4da11eefd5941e7f0b9cf17783fc99d9c6fc34884a665f40a06dbdfc94f","pinned_image":"node:lts-alpine@sha256:d1b3b4da11eefd5941e7f0b9cf17783fc99d9c6fc34884a665f40a06dbdfc94f"}]} -# ___ _ _ -# / _ \ | | (_) -# | |_| | __ _ ___ _ __ | |_ _ ___ +# ___ _ _ +# / _ \ | | (_) +# | |_| | __ _ ___ _ __ | |_ _ ___ # | _ |/ _` |/ _ \ '_ \| __| |/ __| -# | | | | (_| | __/ | | | |_| | (__ +# | | | | (_| | __/ | | | |_| | (__ # \_| |_/\__, |\___|_| |_|\__|_|\___| # __/ | -# _ _ |___/ +# _ _ |___/ # | | | | / _| | # | | | | ___ _ __ _ __| |_| | _____ ____ # | |/\| |/ _ \ '__| |/ /| _| |/ _ \ \ /\ / / ___| @@ -73,6 +73,7 @@ run-name: "CLI for Beginners Content Sync" jobs: activation: runs-on: ubuntu-slim + if: github.repository == vars.UPSTREAM_REPOSITORY permissions: actions: read contents: read @@ -231,7 +232,7 @@ jobs: - **workflow-run-id**: __GH_AW_GITHUB_RUN_ID__ {{/if}} - + GH_AW_PROMPT_c78156520ab442fc_EOF cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md" cat << 'GH_AW_PROMPT_c78156520ab442fc_EOF' @@ -270,9 +271,9 @@ jobs: 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, @@ -321,6 +322,7 @@ jobs: agent: needs: activation runs-on: ubuntu-latest + if: github.repository == vars.UPSTREAM_REPOSITORY permissions: contents: read concurrency: @@ -599,17 +601,17 @@ jobs: # 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: @@ -629,9 +631,9 @@ jobs: 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: @@ -644,7 +646,7 @@ jobs: run: | set -eo pipefail mkdir -p "${RUNNER_TEMP}/gh-aw/mcp-config" - + # Export gateway environment variables for MCP config and gateway script export MCP_GATEWAY_PORT="8080" export MCP_GATEWAY_DOMAIN="host.docker.internal" @@ -656,13 +658,13 @@ jobs: mkdir -p "${MCP_GATEWAY_PAYLOAD_DIR}" export MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD="524288" export DEBUG="*" - + export GH_AW_ENGINE="copilot" MCP_GATEWAY_UID=$(id -u 2>/dev/null || echo '0') MCP_GATEWAY_GID=$(id -g 2>/dev/null || echo '0') DOCKER_SOCK_GID=$(stat -c '%g' /var/run/docker.sock 2>/dev/null || echo '0') export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host --add-host host.docker.internal:127.0.0.1 --user '"${MCP_GATEWAY_UID}"':'"${MCP_GATEWAY_GID}"' --group-add '"${DOCKER_SOCK_GID}"' -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.3.6' - + mkdir -p /home/runner/.copilot GH_AW_NODE=$(which node 2>/dev/null || command -v node 2>/dev/null || echo node) cat << GH_AW_MCP_CONFIG_ac6978ed737cde57_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs" diff --git a/.github/workflows/duplicate-resource-detector.lock.yml b/.github/workflows/duplicate-resource-detector.lock.yml index d9442fe6e..ae3ca9373 100644 --- a/.github/workflows/duplicate-resource-detector.lock.yml +++ b/.github/workflows/duplicate-resource-detector.lock.yml @@ -1,13 +1,13 @@ # gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"ff58c3ff9cf9181e74e682ba6117a448bb9a2a9e52c012dc53d86d7697f3b565","compiler_version":"v0.72.1","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"],"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":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9"},{"repo":"actions/setup-node","sha":"48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e","version":"v6.4.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"bc56a0cad2f450c562810785ef38649c04db812a","version":"v0.72.1"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.25.41"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.25.41"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.25.41"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.3.6","digest":"sha256:2bb8eef86006a4c5963c55616a9c51c32f27bfdecb023b8aa6f91f6718d9171c","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.3.6@sha256:2bb8eef86006a4c5963c55616a9c51c32f27bfdecb023b8aa6f91f6718d9171c"},{"image":"ghcr.io/github/github-mcp-server:v1.0.3","digest":"sha256:2ac27ef03461ef2b877031b838a7d1fd7f12b12d4ace7796d8cad91446d55959","pinned_image":"ghcr.io/github/github-mcp-server:v1.0.3@sha256:2ac27ef03461ef2b877031b838a7d1fd7f12b12d4ace7796d8cad91446d55959"},{"image":"node:lts-alpine","digest":"sha256:d1b3b4da11eefd5941e7f0b9cf17783fc99d9c6fc34884a665f40a06dbdfc94f","pinned_image":"node:lts-alpine@sha256:d1b3b4da11eefd5941e7f0b9cf17783fc99d9c6fc34884a665f40a06dbdfc94f"}]} -# ___ _ _ -# / _ \ | | (_) -# | |_| | __ _ ___ _ __ | |_ _ ___ +# ___ _ _ +# / _ \ | | (_) +# | |_| | __ _ ___ _ __ | |_ _ ___ # | _ |/ _` |/ _ \ '_ \| __| |/ __| -# | | | | (_| | __/ | | | |_| | (__ +# | | | | (_| | __/ | | | |_| | (__ # \_| |_/\__, |\___|_| |_|\__|_|\___| # __/ | -# _ _ |___/ +# _ _ |___/ # | | | | / _| | # | | | | ___ _ __ _ __| |_| | _____ ____ # | |/\| |/ _ \ '__| |/ /| _| |/ _ \ \ /\ / / ___| @@ -70,6 +70,7 @@ run-name: "Duplicate Resource Detector" jobs: activation: runs-on: ubuntu-slim + if: github.repository == vars.UPSTREAM_REPOSITORY permissions: actions: read contents: read @@ -224,7 +225,7 @@ jobs: - **workflow-run-id**: __GH_AW_GITHUB_RUN_ID__ {{/if}} - + GH_AW_PROMPT_792cefb25e1f2461_EOF cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md" cat << 'GH_AW_PROMPT_792cefb25e1f2461_EOF' @@ -260,9 +261,9 @@ jobs: 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, @@ -308,6 +309,7 @@ jobs: agent: needs: activation runs-on: ubuntu-latest + if: github.repository == vars.UPSTREAM_REPOSITORY permissions: contents: read issues: read @@ -564,17 +566,17 @@ jobs: # 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: @@ -594,9 +596,9 @@ jobs: 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: @@ -609,7 +611,7 @@ jobs: run: | set -eo pipefail mkdir -p "${RUNNER_TEMP}/gh-aw/mcp-config" - + # Export gateway environment variables for MCP config and gateway script export MCP_GATEWAY_PORT="8080" export MCP_GATEWAY_DOMAIN="host.docker.internal" @@ -621,13 +623,13 @@ jobs: mkdir -p "${MCP_GATEWAY_PAYLOAD_DIR}" export MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD="524288" export DEBUG="*" - + export GH_AW_ENGINE="copilot" MCP_GATEWAY_UID=$(id -u 2>/dev/null || echo '0') MCP_GATEWAY_GID=$(id -g 2>/dev/null || echo '0') DOCKER_SOCK_GID=$(stat -c '%g' /var/run/docker.sock 2>/dev/null || echo '0') export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host --add-host host.docker.internal:127.0.0.1 --user '"${MCP_GATEWAY_UID}"':'"${MCP_GATEWAY_GID}"' --group-add '"${DOCKER_SOCK_GID}"' -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.3.6' - + mkdir -p /home/runner/.copilot GH_AW_NODE=$(which node 2>/dev/null || command -v node 2>/dev/null || echo node) cat << GH_AW_MCP_CONFIG_cbfc25997d27e2fa_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs" diff --git a/.github/workflows/duplicate-resource-detector.md b/.github/workflows/duplicate-resource-detector.md index 0bfba0eb0..326e9b8f8 100644 --- a/.github/workflows/duplicate-resource-detector.md +++ b/.github/workflows/duplicate-resource-detector.md @@ -1,5 +1,5 @@ --- -description: Weekly scan of agents, instructions, and skills to identify potential duplicate resources and report them for review +description: Weekly scan of agents, instructions, skills, hooks, and workflows to identify potential duplicate resources and report them for review on: schedule: weekly permissions: @@ -28,6 +28,9 @@ Scan all resources in the following directories and identify groups of resources - `agents/` (`.agent.md` files) - `instructions/` (`.instructions.md` files) - `skills/` (folders — check `SKILL.md` inside each) +- `hooks/` (folders — check `README.md` inside each) +- `workflows/` (`.md` files) +- `plugins/` (folders — check `.github/plugin/plugin.json` inside each) ### Step 1: Gather Resource Metadata @@ -38,7 +41,7 @@ For each resource, extract: 3. **Front matter `name`** field (if present) 4. **First ~20 lines of body content** (the markdown after the front matter) -Use bash to read files efficiently. For skills, read `skills//SKILL.md`. +Use bash to read files efficiently. For skills, read `skills//SKILL.md`. For hooks, read `hooks//README.md`. For workflows, read the `.md` files directly in the `workflows/` directory. For plugins, read `.github/plugin/plugin.json` inside each plugin folder. ### Step 2: Identify Potential Duplicates @@ -50,6 +53,7 @@ Compare resources and flag groups that look like potential duplicates. Consider - **Cross-type overlap** — an agent and an instruction (or instruction and skill) that cover the same topic so thoroughly that one may make the other redundant Be pragmatic. Resources that cover related but distinct topics are NOT duplicates. For example: + - `react.instructions.md` (general React coding standards) and `react-testing.agent.md` (React testing agent) are **not** duplicates — they serve different purposes. - `python-fastapi.instructions.md` and `python-flask.instructions.md` are **not** duplicates — they target different frameworks. - `code-review.agent.md` and `code-review.instructions.md` that both do the same style of code review **are** potential duplicates worth flagging. @@ -63,6 +67,7 @@ Search for issues with label "duplicate-review" that are closed ``` Read the comments and body of those past issues to find any pairs or groups that reviewers have explicitly marked as **"accepted"** or **"not duplicates"**. Look for phrases like: + - "accepted as-is" - "not duplicates" - "intentionally separate" @@ -123,4 +128,6 @@ Use `
` blocks to collapse groups if there are more than 10. - Include cross-type duplicates (e.g., an agent and an instruction doing the same thing). - Limit the report to the top 20 most likely duplicate groups to keep it actionable. - For skills, use the folder name and description from `SKILL.md`. +- For hooks, use the folder name and description from `README.md`. +- For plugins, use the folder name and description from `.github/plugin/plugin.json`. - Process resources in batches to stay within time limits — prioritize name and description comparison, then spot-check content for top candidates. diff --git a/.github/workflows/external-plugin-intake.yml b/.github/workflows/external-plugin-intake.yml index 4c98f0e02..ea8b9eb97 100644 --- a/.github/workflows/external-plugin-intake.yml +++ b/.github/workflows/external-plugin-intake.yml @@ -2,7 +2,7 @@ name: External Plugin Intake on: issues: - types: [opened, edited, reopened] + types: [opened, edited, reopened, labeled] concurrency: group: external-plugin-intake-${{ github.event.issue.number }} @@ -17,7 +17,9 @@ jobs: runs-on: ubuntu-latest if: >- contains(github.event.issue.labels.*.name, 'external-plugin') || - contains(github.event.issue.body, '') + contains(github.event.issue.body, '') || + startsWith(github.event.issue.title, '[External Plugin]:') || + startsWith(github.event.issue.title, '[External Plugin Submission]') outputs: evaluation: ${{ steps.evaluation.outputs.result }} should-sync: ${{ steps.guard.outputs.should-sync }} diff --git a/.github/workflows/external-plugin-rerun-intake-command.yml b/.github/workflows/external-plugin-rerun-intake-command.yml index 84d4b0dad..1f367ee2e 100644 --- a/.github/workflows/external-plugin-rerun-intake-command.yml +++ b/.github/workflows/external-plugin-rerun-intake-command.yml @@ -63,9 +63,14 @@ jobs: }); const labelNames = new Set((currentIssue.labels || []).map((label) => label.name)); + const issueTitle = String(currentIssue.title || '').trim(); + const hasExternalPluginTitle = + issueTitle.startsWith('[External Plugin]:') || + issueTitle.startsWith('[External Plugin Submission]'); const isExternalPluginIssue = labelNames.has('external-plugin') || - String(currentIssue.body || '').includes(intake.ISSUE_FORM_MARKER); + String(currentIssue.body || '').includes(intake.ISSUE_FORM_MARKER) || + hasExternalPluginTitle; if (!isExternalPluginIssue) { core.info('Ignoring /rerun-intake because the issue is not an external plugin submission.'); return; diff --git a/.github/workflows/learning-hub-updater.lock.yml b/.github/workflows/learning-hub-updater.lock.yml index ec26cb091..35be1b19b 100644 --- a/.github/workflows/learning-hub-updater.lock.yml +++ b/.github/workflows/learning-hub-updater.lock.yml @@ -1,13 +1,13 @@ # gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"a0b5bd27f5ca87418c0cdb64df4d55250d115eb99049640f8c1789d3aee78411","compiler_version":"v0.72.1","strict":true,"agent_id":"copilot"} # gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_CI_TRIGGER_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_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":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9"},{"repo":"actions/setup-node","sha":"48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e","version":"v6.4.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"bc56a0cad2f450c562810785ef38649c04db812a","version":"v0.72.1"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.25.41"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.25.41"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.25.41"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.3.6","digest":"sha256:2bb8eef86006a4c5963c55616a9c51c32f27bfdecb023b8aa6f91f6718d9171c","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.3.6@sha256:2bb8eef86006a4c5963c55616a9c51c32f27bfdecb023b8aa6f91f6718d9171c"},{"image":"ghcr.io/github/github-mcp-server:v1.0.3","digest":"sha256:2ac27ef03461ef2b877031b838a7d1fd7f12b12d4ace7796d8cad91446d55959","pinned_image":"ghcr.io/github/github-mcp-server:v1.0.3@sha256:2ac27ef03461ef2b877031b838a7d1fd7f12b12d4ace7796d8cad91446d55959"},{"image":"node:lts-alpine","digest":"sha256:d1b3b4da11eefd5941e7f0b9cf17783fc99d9c6fc34884a665f40a06dbdfc94f","pinned_image":"node:lts-alpine@sha256:d1b3b4da11eefd5941e7f0b9cf17783fc99d9c6fc34884a665f40a06dbdfc94f"}]} -# ___ _ _ -# / _ \ | | (_) -# | |_| | __ _ ___ _ __ | |_ _ ___ +# ___ _ _ +# / _ \ | | (_) +# | |_| | __ _ ___ _ __ | |_ _ ___ # | _ |/ _` |/ _ \ '_ \| __| |/ __| -# | | | | (_| | __/ | | | |_| | (__ +# | | | | (_| | __/ | | | |_| | (__ # \_| |_/\__, |\___|_| |_|\__|_|\___| # __/ | -# _ _ |___/ +# _ _ |___/ # | | | | / _| | # | | | | ___ _ __ _ __| |_| | _____ ____ # | |/\| |/ _ \ '__| |/ /| _| |/ _ \ \ /\ / / ___| @@ -71,6 +71,7 @@ run-name: "Learning Hub Updater" jobs: activation: runs-on: ubuntu-slim + if: github.repository == vars.UPSTREAM_REPOSITORY permissions: actions: read contents: read @@ -228,7 +229,7 @@ jobs: - **workflow-run-id**: __GH_AW_GITHUB_RUN_ID__ {{/if}} - + GH_AW_PROMPT_cc5fcdecf89ba0ab_EOF cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md" cat << 'GH_AW_PROMPT_cc5fcdecf89ba0ab_EOF' @@ -264,9 +265,9 @@ jobs: 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, @@ -312,6 +313,7 @@ jobs: agent: needs: activation runs-on: ubuntu-latest + if: github.repository == vars.UPSTREAM_REPOSITORY permissions: contents: read concurrency: @@ -575,17 +577,17 @@ jobs: # 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: @@ -605,9 +607,9 @@ jobs: 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: @@ -620,7 +622,7 @@ jobs: run: | set -eo pipefail mkdir -p "${RUNNER_TEMP}/gh-aw/mcp-config" - + # Export gateway environment variables for MCP config and gateway script export MCP_GATEWAY_PORT="8080" export MCP_GATEWAY_DOMAIN="host.docker.internal" @@ -632,13 +634,13 @@ jobs: mkdir -p "${MCP_GATEWAY_PAYLOAD_DIR}" export MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD="524288" export DEBUG="*" - + export GH_AW_ENGINE="copilot" MCP_GATEWAY_UID=$(id -u 2>/dev/null || echo '0') MCP_GATEWAY_GID=$(id -g 2>/dev/null || echo '0') DOCKER_SOCK_GID=$(stat -c '%g' /var/run/docker.sock 2>/dev/null || echo '0') export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host --add-host host.docker.internal:127.0.0.1 --user '"${MCP_GATEWAY_UID}"':'"${MCP_GATEWAY_GID}"' --group-add '"${DOCKER_SOCK_GID}"' -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.3.6' - + mkdir -p /home/runner/.copilot GH_AW_NODE=$(which node 2>/dev/null || command -v node 2>/dev/null || echo node) cat << GH_AW_MCP_CONFIG_1568b8f530c15a53_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs" diff --git a/.github/workflows/learning-hub-updater.md b/.github/workflows/learning-hub-updater.md index 1a41b031f..bfe5a87c3 100644 --- a/.github/workflows/learning-hub-updater.md +++ b/.github/workflows/learning-hub-updater.md @@ -23,17 +23,17 @@ safe-outputs: # Check for Awesome GitHub Copilot Updates -You are a documentation maintainer for the Awesome GitHub Copilot Learning Hub. Your job is to check for recent updates to GitHub Copilot and determine if the Learning Hub pages in `website/learning-hub` need updating. +You are a documentation maintainer for the Awesome GitHub Copilot Learning Hub. Your job is to check for recent updates to GitHub Copilot and determine if the Learning Hub pages in `website/src/content/docs/learning-hub` need updating. ## Step 1 — Gather recent Copilot updates Use `web-fetch` to read the following pages and extract the latest entries from the past 7 days: -- https://github.blog/changelog/label/copilot/ — official changelog -- https://github.com/github/copilot-cli/blob/main/changelog.md — CLI changelog -- https://github.blog/ai-and-ml/github-copilot/ — blog posts -- https://code.visualstudio.com/updates - VS Code release notes (filter for Copilot-related updates) -- https://nishanil.github.io/copilot-guide/ - community-maintained guide (check for recent commits or updates) +- — official changelog +- — CLI changelog +- — blog posts +- - VS Code release notes (filter for Copilot-related updates) +- - community-maintained guide (check for recent commits or updates) Also use `gh` CLI to check the latest releases and commits in the `github/copilot-cli` repo. @@ -61,17 +61,17 @@ If there is nothing new or everything is already up to date, stop here and repor If updates are needed, make a decision on whether a new page needs to be added (e.g., for a major new feature) or if existing pages can be updated with new sections. -### For new pages: +### For new pages A new page should be created for major features or capabilities that warrant their own documentation (e.g., a new feature of Copilot, a new pattern for working with Copilot, etc.). To create a new page: -1. Create a new markdown file in the appropriate section of `website/learning-hub` (e.g., `website/learning-hub/agents/new-agent.md`). +1. Create a new markdown file in the appropriate section of `website/src/content/docs/learning-hub` (e.g., `website/src/content/docs/learning-hub/new-topic.md`). 2. Write a summary of the new feature, how it works, and its use cases. 3. Add a "Further Reading" section with links to official documentation, blog posts, and relevant community resources. -### For updates to existing pages: +### For updates to existing pages If the new information can be added to existing pages, edit those pages to include refinements, new sections, or updated information as needed. Make sure to update any relevant links in the "Further Reading" sections. diff --git a/.github/workflows/pr-duplicate-check.md b/.github/workflows/pr-duplicate-check.md index 07561fa54..1b09dee4b 100644 --- a/.github/workflows/pr-duplicate-check.md +++ b/.github/workflows/pr-duplicate-check.md @@ -1,5 +1,5 @@ --- -description: 'Checks PRs for potential duplicate agents, instructions, skills, and workflows already in the repository' +description: 'Checks PRs for potential duplicate agents, instructions, skills, hooks, workflows, and plugins already in the repository' on: pull_request: types: [opened, synchronize, reopened] @@ -34,10 +34,12 @@ Filter for files in these resource directories: - `agents/` (`.agent.md` files) - `instructions/` (`.instructions.md` files) - `skills/` (folders — the SKILL.md inside each folder is the resource) +- `hooks/` (folders — the README.md inside each folder is the resource) - `workflows/` (`.md` files) +- `plugins/` (folders — the `.github/plugin/plugin.json` inside each folder is the resource) If **no files** from these directories were modified, call `noop` with the message: -"No agent, instruction, skill, or workflow files were changed in this PR — no duplicate check needed." +"No agent, instruction, skill, hook, workflow, or plugin files were changed in this PR — no duplicate check needed." ## Step 2: Read Metadata for the PR's New Resources @@ -57,7 +59,9 @@ Read all existing resources in the repository (excluding files that are part of - `agents/` (`.agent.md` files) - `instructions/` (`.instructions.md` files) - `skills/` (folders — read `SKILL.md` inside each) +- `hooks/` (folders — read `README.md` inside each) - `workflows/` (`.md` files) +- `plugins/` (folders — read `.github/plugin/plugin.json` inside each) For each, extract the same metadata: file path, description, name field, and first ~20 lines. @@ -71,6 +75,7 @@ Compare the PR's new resources against the existing repository resources. Flag p - **Cross-type overlap** — an agent and an instruction (or skill) that cover the same topic so thoroughly that one may make the other redundant Be pragmatic. Resources that cover related but distinct topics are **not** duplicates: + - `react.instructions.md` (general React coding standards) and `react-testing.agent.md` (React testing agent) → **not** duplicates - `python-fastapi.instructions.md` and `python-flask.instructions.md` → **not** duplicates (different frameworks) - `code-review.agent.md` and `code-review.instructions.md` that both enforce the same style rules → **potential** duplicate @@ -92,8 +97,8 @@ This PR adds resources that may be similar to existing ones in the repository. P | Resource | Type | Description | |----------|------|-------------| -| `` | | | -| `` | | | +| `` | | | +| `` | | | **Why flagged:** @@ -117,4 +122,6 @@ Call `noop` with the message: "No potential duplicate resources detected in this - Sort groups by confidence: strongest duplicate signal first. - Limit the report to the top **5** most likely duplicate groups to keep feedback actionable. - For skills, report by folder name (e.g., `skills/my-skill/`) using the description from `SKILL.md`. +- For hooks, report by folder name (e.g., `hooks/my-hook/`) using the description from `README.md`. +- For plugins, report by folder name (e.g., `plugins/my-plugin/`) using the description from `.github/plugin/plugin.json`. - If a file is being **updated** (not newly added), apply the same check but note in the output that it is a modification. diff --git a/.github/workflows/resource-staleness-report.lock.yml b/.github/workflows/resource-staleness-report.lock.yml index fcec6f261..43b82c25d 100644 --- a/.github/workflows/resource-staleness-report.lock.yml +++ b/.github/workflows/resource-staleness-report.lock.yml @@ -1,13 +1,13 @@ # gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"9ab9dc5c875492aa5da7b793735c1a9816a55c753165c01efd9d86087d7f33d3","compiler_version":"v0.72.1","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"],"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":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9"},{"repo":"actions/setup-node","sha":"48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e","version":"v6.4.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"bc56a0cad2f450c562810785ef38649c04db812a","version":"v0.72.1"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.25.41"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.25.41"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.25.41"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.3.6","digest":"sha256:2bb8eef86006a4c5963c55616a9c51c32f27bfdecb023b8aa6f91f6718d9171c","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.3.6@sha256:2bb8eef86006a4c5963c55616a9c51c32f27bfdecb023b8aa6f91f6718d9171c"},{"image":"ghcr.io/github/github-mcp-server:v1.0.3","digest":"sha256:2ac27ef03461ef2b877031b838a7d1fd7f12b12d4ace7796d8cad91446d55959","pinned_image":"ghcr.io/github/github-mcp-server:v1.0.3@sha256:2ac27ef03461ef2b877031b838a7d1fd7f12b12d4ace7796d8cad91446d55959"},{"image":"node:lts-alpine","digest":"sha256:d1b3b4da11eefd5941e7f0b9cf17783fc99d9c6fc34884a665f40a06dbdfc94f","pinned_image":"node:lts-alpine@sha256:d1b3b4da11eefd5941e7f0b9cf17783fc99d9c6fc34884a665f40a06dbdfc94f"}]} -# ___ _ _ -# / _ \ | | (_) -# | |_| | __ _ ___ _ __ | |_ _ ___ +# ___ _ _ +# / _ \ | | (_) +# | |_| | __ _ ___ _ __ | |_ _ ___ # | _ |/ _` |/ _ \ '_ \| __| |/ __| -# | | | | (_| | __/ | | | |_| | (__ +# | | | | (_| | __/ | | | |_| | (__ # \_| |_/\__, |\___|_| |_|\__|_|\___| # __/ | -# _ _ |___/ +# _ _ |___/ # | | | | / _| | # | | | | ___ _ __ _ __| |_| | _____ ____ # | |/\| |/ _ \ '__| |/ /| _| |/ _ \ \ /\ / / ___| @@ -70,6 +70,7 @@ run-name: "Resource Staleness Report" jobs: activation: runs-on: ubuntu-slim + if: github.repository == vars.UPSTREAM_REPOSITORY permissions: actions: read contents: read @@ -224,7 +225,7 @@ jobs: - **workflow-run-id**: __GH_AW_GITHUB_RUN_ID__ {{/if}} - + GH_AW_PROMPT_25b4b73e24c8b397_EOF cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md" cat << 'GH_AW_PROMPT_25b4b73e24c8b397_EOF' @@ -260,9 +261,9 @@ jobs: 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, @@ -308,6 +309,7 @@ jobs: agent: needs: activation runs-on: ubuntu-latest + if: github.repository == vars.UPSTREAM_REPOSITORY permissions: contents: read concurrency: @@ -563,17 +565,17 @@ jobs: # 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: @@ -593,9 +595,9 @@ jobs: 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: @@ -608,7 +610,7 @@ jobs: run: | set -eo pipefail mkdir -p "${RUNNER_TEMP}/gh-aw/mcp-config" - + # Export gateway environment variables for MCP config and gateway script export MCP_GATEWAY_PORT="8080" export MCP_GATEWAY_DOMAIN="host.docker.internal" @@ -620,13 +622,13 @@ jobs: mkdir -p "${MCP_GATEWAY_PAYLOAD_DIR}" export MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD="524288" export DEBUG="*" - + export GH_AW_ENGINE="copilot" MCP_GATEWAY_UID=$(id -u 2>/dev/null || echo '0') MCP_GATEWAY_GID=$(id -g 2>/dev/null || echo '0') DOCKER_SOCK_GID=$(stat -c '%g' /var/run/docker.sock 2>/dev/null || echo '0') export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host --add-host host.docker.internal:127.0.0.1 --user '"${MCP_GATEWAY_UID}"':'"${MCP_GATEWAY_GID}"' --group-add '"${DOCKER_SOCK_GID}"' -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.3.6' - + mkdir -p /home/runner/.copilot GH_AW_NODE=$(which node 2>/dev/null || command -v node 2>/dev/null || echo node) cat << GH_AW_MCP_CONFIG_37075b9bf56df645_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs" diff --git a/.github/workflows/resource-staleness-report.md b/.github/workflows/resource-staleness-report.md index ec5e747bf..310077818 100644 --- a/.github/workflows/resource-staleness-report.md +++ b/.github/workflows/resource-staleness-report.md @@ -1,5 +1,5 @@ --- -description: Weekly report identifying stale and aging resources across agents, prompts, instructions, hooks, and skills folders +description: Weekly report identifying stale and aging resources across agents, instructions, hooks, skills, workflows, and plugins folders on: schedule: weekly permissions: @@ -23,10 +23,11 @@ You are an AI agent that audits the resources in this repository to identify one Analyze all files in the following directories to determine when each file last had a **major** (substantive) change committed: - `agents/` (`.agent.md` files) -- `prompts/` (`.prompt.md` files) - `instructions/` (`.instructions.md` files) -- `hooks/` (folders — check the folder's files) - `skills/` (folders — check the folder's files) +- `hooks/` (folders — check the folder's files) +- `workflows/` (`.md` files) +- `plugins/` (folders — check `.github/plugin/plugin.json` inside each) ### What Counts as a Major Change @@ -53,7 +54,7 @@ This gives the most recent commit that **modified** (not just renamed) the file. git log -1 --format="%H %ai" --diff-filter=A -- ``` -For hook and skill folders, check all files within the folder and use the **most recent** major change date across any file in that folder. +For hook, skill, and plugin folders, check all files within the folder and use the **most recent** major change date across any file in that folder. ### Classification @@ -106,7 +107,7 @@ Organize the issue body as follows: | Resource | Type | Last Major Change | Days Ago | |----------|------|-------------------|----------| -| `prompts/example.prompt.md` | Prompt | 2025-02-01 | 20 | +| `workflows/example.md` | Workflow | 2025-02-01 | 20 | ### Deep Review: 10 Oldest Stale Resources @@ -128,8 +129,8 @@ Use `
` blocks to collapse sections with more than 15 entries. ## Guidelines -- Process all resource types: agents, prompts, instructions, hooks, and skills. -- For **hooks** and **skills**, treat the entire folder as one resource. Report it by folder name and use the most recent change date of any file within. +- Process all resource types: agents, instructions, skills, hooks, workflows, and plugins. +- For **hooks**, **skills**, and **plugins**, treat the entire folder as one resource. Report it by folder name and use the most recent change date of any file within. - Sort tables by "Days Ago" descending (oldest first). - After building the stale table, inspect the **10 oldest stale resources** in more depth and include the deeper review section. - In the deeper review, prefer **high-signal issues**: outdated version assumptions, deprecated APIs, misleading instructions, harmful heuristics, unsafe defaults, or instructions that are scoped too broadly. diff --git a/.github/workflows/skill-quality-report.yml b/.github/workflows/skill-quality-report.yml index 75db829da..52325673c 100644 --- a/.github/workflows/skill-quality-report.yml +++ b/.github/workflows/skill-quality-report.yml @@ -13,6 +13,7 @@ permissions: jobs: nightly-scan: runs-on: ubuntu-latest + if: github.repository == vars.UPSTREAM_REPOSITORY steps: - name: Checkout code uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 @@ -376,8 +377,22 @@ jobs: console.log(`Closed ${closedCount} report discussion(s) older than ${RETENTION_DAYS} days.`); # ── Create Discussion (preferred) or Issue (fallback) ──────── + - name: Detect report publishing capabilities + id: repo-capabilities + uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7.1.0 + with: + script: | + const { data: repo } = await github.rest.repos.get({ + owner: context.repo.owner, + repo: context.repo.repo, + }); + + core.setOutput('has_discussions', repo.has_discussions ? 'true' : 'false'); + core.setOutput('has_issues', repo.has_issues ? 'true' : 'false'); + - name: Create Discussion id: create-discussion + if: steps.repo-capabilities.outputs.has_discussions == 'true' continue-on-error: true uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7.1.0 with: @@ -451,7 +466,7 @@ jobs: } - name: Fallback — Create Issue - if: steps.create-discussion.outcome == 'failure' + if: steps.repo-capabilities.outputs.has_issues == 'true' && (steps.repo-capabilities.outputs.has_discussions != 'true' || steps.create-discussion.outcome == 'failure') env: GH_TOKEN: ${{ github.token }} run: | @@ -471,3 +486,8 @@ jobs: echo "Posted detail comment $((i+1))/${COMMENT_COUNT}" fi done + + - name: Skip report publication when discussions and issues are disabled + if: steps.repo-capabilities.outputs.has_discussions != 'true' && steps.repo-capabilities.outputs.has_issues != 'true' + run: | + echo "Discussions and issues are disabled for this repository; skipping report publication." diff --git a/.github/workflows/traffic-reporting.yml b/.github/workflows/traffic-reporting.yml index d14055c3d..036253004 100644 --- a/.github/workflows/traffic-reporting.yml +++ b/.github/workflows/traffic-reporting.yml @@ -8,6 +8,7 @@ on: jobs: report-traffic: runs-on: ubuntu-latest + if: github.repository == vars.UPSTREAM_REPOSITORY permissions: actions: none @@ -59,19 +60,19 @@ jobs: API_KEY: ${{ secrets.REPORTING_API_KEY }} run: | echo "📤 Sending traffic data to reporting endpoint..." - + # Validate that REPORTING_URL is set if [ -z "${REPORTING_URL}" ]; then echo "❌ Error: REPORTING_URL environment variable is not set. Please configure vars.REPORTING_POST_URL." exit 1 fi - + # Validate that REPORTING_URL uses HTTPS if [[ ! "${REPORTING_URL}" =~ ^https:// ]]; then echo "❌ Error: REPORTING_URL must start with https:// to ensure secure transmission of sensitive traffic data." exit 1 fi - + # Send POST request with API key header, reading file directly HTTP_STATUS=$(curl -f --max-time 30 --retry 3 -s -o /dev/null -w "%{http_code}" \ -X POST \ @@ -79,9 +80,9 @@ jobs: -H "X-API-KEY: ${API_KEY}" \ --data-binary "@${RUNNER_TEMP}/traffic_data.json" \ "${REPORTING_URL}") - + echo "HTTP Status Code: ${HTTP_STATUS}" - + if [ "${HTTP_STATUS}" -ge 200 ] && [ "${HTTP_STATUS}" -lt 300 ]; then echo "✅ Traffic data sent successfully!" else