diff --git a/.github/workflows/smoke-call-workflow.lock.yml b/.github/workflows/smoke-call-workflow.lock.yml
index 8784a9f2fd2..2d5c50e3a08 100644
--- a/.github/workflows/smoke-call-workflow.lock.yml
+++ b/.github/workflows/smoke-call-workflow.lock.yml
@@ -152,10 +152,7 @@ jobs:
cat "/opt/gh-aw/prompts/safe_outputs_prompt.md"
cat << 'GH_AW_PROMPT_EOF'
- Tools: create_issue, missing_tool, missing_data, noop
- GH_AW_PROMPT_EOF
- cat "/opt/gh-aw/prompts/safe_outputs_auto_create_issue.md"
- cat << 'GH_AW_PROMPT_EOF'
+ Tools: call_workflow, missing_tool, missing_data, noop
The following GitHub context information is available for this workflow:
@@ -351,61 +348,12 @@ jobs:
mkdir -p /tmp/gh-aw/safeoutputs
mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs
cat > /opt/gh-aw/safeoutputs/config.json << 'GH_AW_SAFE_OUTPUTS_CONFIG_EOF'
- {"call_workflow":{"max":1,"workflow_files":{"smoke-workflow-call":"./.github/workflows/smoke-workflow-call.lock.yml"},"workflows":["smoke-workflow-call"]},"create_issue":{"max":1},"missing_data":{},"missing_tool":{},"noop":{"max":1}}
+ {"call_workflow":{"max":1,"workflow_files":{"smoke-workflow-call":"./.github/workflows/smoke-workflow-call.lock.yml"},"workflows":["smoke-workflow-call"]},"missing_data":{},"missing_tool":{},"noop":{"max":1}}
GH_AW_SAFE_OUTPUTS_CONFIG_EOF
- name: Write Safe Outputs Tools
run: |
cat > /opt/gh-aw/safeoutputs/tools.json << 'GH_AW_SAFE_OUTPUTS_TOOLS_EOF'
[
- {
- "description": "Create a new GitHub issue for tracking bugs, feature requests, or tasks. Use this for actionable work items that need assignment, labeling, and status tracking. For reports, announcements, or status updates that don't require task tracking, use create_discussion instead. CONSTRAINTS: Maximum 1 issue(s) can be created. Title will be prefixed with \"[smoke-call-workflow]\". Labels [\"smoke-call-workflow\"] will be automatically added.",
- "inputSchema": {
- "additionalProperties": false,
- "properties": {
- "body": {
- "description": "Detailed issue description in Markdown. Do NOT repeat the title as a heading since it already appears as the issue's h1. Include context, reproduction steps, or acceptance criteria as appropriate.",
- "type": "string"
- },
- "integrity": {
- "description": "Trustworthiness level of the message source (e.g., \"low\", \"medium\", \"high\").",
- "type": "string"
- },
- "labels": {
- "description": "Labels to categorize the issue (e.g., 'bug', 'enhancement'). Labels must exist in the repository.",
- "items": {
- "type": "string"
- },
- "type": "array"
- },
- "parent": {
- "description": "Parent issue number for creating sub-issues. This is the numeric ID from the GitHub URL (e.g., 42 in github.com/owner/repo/issues/42). Can also be a temporary_id (e.g., 'aw_abc123', 'aw_Test123') from a previously created issue in the same workflow run.",
- "type": [
- "number",
- "string"
- ]
- },
- "secrecy": {
- "description": "Confidentiality level of the message content (e.g., \"public\", \"internal\", \"private\").",
- "type": "string"
- },
- "temporary_id": {
- "description": "Unique temporary identifier for referencing this issue before it's created. Format: 'aw_' followed by 3 to 12 alphanumeric characters (e.g., 'aw_abc1', 'aw_Test123'). Use '#aw_ID' in body text to reference other issues by their temporary_id; these are replaced with actual issue numbers after creation.",
- "pattern": "^aw_[A-Za-z0-9]{3,12}$",
- "type": "string"
- },
- "title": {
- "description": "Concise issue title summarizing the bug, feature, or task. The title appears as the main heading, so keep it brief and descriptive.",
- "type": "string"
- }
- },
- "required": [
- "title",
- "body"
- ],
- "type": "object"
- },
- "name": "create_issue"
- },
{
"description": "Report that a tool or capability needed to complete the task is not available, or share any information you deem important about missing functionality or limitations. Use this when you cannot accomplish what was requested because the required functionality is missing or access is restricted.",
"inputSchema": {
@@ -523,39 +471,6 @@ jobs:
GH_AW_SAFE_OUTPUTS_TOOLS_EOF
cat > /opt/gh-aw/safeoutputs/validation.json << 'GH_AW_SAFE_OUTPUTS_VALIDATION_EOF'
{
- "create_issue": {
- "defaultMax": 1,
- "fields": {
- "body": {
- "required": true,
- "type": "string",
- "sanitize": true,
- "maxLength": 65000
- },
- "labels": {
- "type": "array",
- "itemType": "string",
- "itemSanitize": true,
- "itemMaxLength": 128
- },
- "parent": {
- "issueOrPRNumber": true
- },
- "repo": {
- "type": "string",
- "maxLength": 256
- },
- "temporary_id": {
- "type": "string"
- },
- "title": {
- "required": true,
- "type": "string",
- "sanitize": true,
- "maxLength": 128
- }
- }
- },
"missing_data": {
"defaultMax": 20,
"fields": {
@@ -1010,9 +925,6 @@ jobs:
- safe_outputs
if: (always()) && (needs.agent.result != 'skipped')
runs-on: ubuntu-slim
- permissions:
- contents: read
- issues: write
concurrency:
group: "gh-aw-conclusion-smoke-call-workflow"
cancel-in-progress: false
@@ -1150,9 +1062,6 @@ jobs:
needs: agent
if: ((!cancelled()) && (needs.agent.result != 'skipped')) && (needs.agent.outputs.detection_success == 'true')
runs-on: ubuntu-slim
- permissions:
- contents: read
- issues: write
timeout-minutes: 15
env:
GH_AW_CALLER_WORKFLOW_ID: "${{ github.repository }}/smoke-call-workflow"
@@ -1167,8 +1076,6 @@ jobs:
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 }}
- created_issue_number: ${{ steps.process_safe_outputs.outputs.created_issue_number }}
- created_issue_url: ${{ steps.process_safe_outputs.outputs.created_issue_url }}
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 }}
steps:
@@ -1204,7 +1111,7 @@ jobs:
GH_AW_ALLOWED_DOMAINS: "*.githubusercontent.com,127.0.0.1,172.30.0.1,::1,api.openai.com,api.snapcraft.io,app.renovatebot.com,appveyor.com,archive.ubuntu.com,azure.archive.ubuntu.com,badgen.net,circleci.com,codacy.com,codeclimate.com,codecov.io,codeload.github.com,coveralls.io,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,deepsource.io,docs.github.com,drone.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,host.docker.internal,img.shields.io,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,lfs.github.com,localhost,objects.githubusercontent.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,openai.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,ppa.launchpad.net,raw.githubusercontent.com,readthedocs.io,readthedocs.org,renovatebot.com,s.symcb.com,s.symcd.com,security.ubuntu.com,semaphoreci.com,shields.io,snyk.io,sonarcloud.io,sonarqube.com,travis-ci.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com"
GITHUB_SERVER_URL: ${{ github.server_url }}
GITHUB_API_URL: ${{ github.api_url }}
- GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"call_workflow\":{\"max\":1,\"workflow_files\":{\"smoke-workflow-call\":\"./.github/workflows/smoke-workflow-call.lock.yml\"},\"workflows\":[\"smoke-workflow-call\"]},\"create_issue\":{\"labels\":[\"smoke-call-workflow\"],\"max\":1,\"title_prefix\":\"[smoke-call-workflow]\"},\"missing_data\":{},\"missing_tool\":{}}"
+ GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"call_workflow\":{\"max\":1,\"workflow_files\":{\"smoke-workflow-call\":\"./.github/workflows/smoke-workflow-call.lock.yml\"},\"workflows\":[\"smoke-workflow-call\"]},\"missing_data\":{},\"missing_tool\":{}}"
with:
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
script: |
diff --git a/actions/setup/js/check_command_position.cjs b/actions/setup/js/check_command_position.cjs
index 9feabed4dbf..5c8b6ef04a1 100644
--- a/actions/setup/js/check_command_position.cjs
+++ b/actions/setup/js/check_command_position.cjs
@@ -41,6 +41,18 @@ async function main() {
const eventName = context.eventName;
try {
+ // For labeled events (label-command triggers), skip the command position check.
+ // The label name itself is the trigger, not a slash command in the body.
+ // Label name matching is enforced by the workflow-level `if:` condition
+ // (e.g. github.event.label.name == 'cloclo'), so no additional filtering
+ // is needed here regardless of which labels are configured.
+ if (context.payload?.action === "labeled") {
+ core.info(`Event ${eventName} with action 'labeled' does not require command position check`);
+ core.setOutput("command_position_ok", "true");
+ core.setOutput("matched_command", "");
+ return;
+ }
+
if (eventName === "issues") {
text = context.payload.issue?.body || "";
} else if (eventName === "pull_request") {
diff --git a/actions/setup/js/check_command_position.test.cjs b/actions/setup/js/check_command_position.test.cjs
index 636c1c12da6..c447337fade 100644
--- a/actions/setup/js/check_command_position.test.cjs
+++ b/actions/setup/js/check_command_position.test.cjs
@@ -114,5 +114,29 @@ const mockCore = {
(mockContext.payload = { comment: { body: "/discuss-bot analyze this" } }),
await eval(`(async () => { ${checkCommandPositionScript}; await main(); })()`),
expect(mockCore.setOutput).toHaveBeenCalledWith("command_position_ok", "true"));
+ }),
+ it("should pass for labeled issues event (label-command trigger)", async () => {
+ process.env.GH_AW_COMMANDS = JSON.stringify(["cloclo"]);
+ mockContext.eventName = "issues";
+ mockContext.payload = { action: "labeled", label: { name: "cloclo" }, issue: { body: "This is a regular issue body" } };
+ await eval(`(async () => { ${checkCommandPositionScript}; await main(); })()`);
+ expect(mockCore.setOutput).toHaveBeenCalledWith("command_position_ok", "true");
+ expect(mockCore.info).toHaveBeenCalledWith(expect.stringContaining("does not require command position check"));
+ }),
+ it("should pass for labeled pull_request event (label-command trigger)", async () => {
+ process.env.GH_AW_COMMANDS = JSON.stringify(["cloclo"]);
+ mockContext.eventName = "pull_request";
+ mockContext.payload = { action: "labeled", label: { name: "cloclo" }, pull_request: { body: "PR body without command" } };
+ await eval(`(async () => { ${checkCommandPositionScript}; await main(); })()`);
+ expect(mockCore.setOutput).toHaveBeenCalledWith("command_position_ok", "true");
+ expect(mockCore.info).toHaveBeenCalledWith(expect.stringContaining("does not require command position check"));
+ }),
+ it("should pass for labeled discussion event (label-command trigger)", async () => {
+ process.env.GH_AW_COMMANDS = JSON.stringify(["cloclo"]);
+ mockContext.eventName = "discussion";
+ mockContext.payload = { action: "labeled", label: { name: "cloclo" }, discussion: { body: "Discussion body without command" } };
+ await eval(`(async () => { ${checkCommandPositionScript}; await main(); })()`);
+ expect(mockCore.setOutput).toHaveBeenCalledWith("command_position_ok", "true");
+ expect(mockCore.info).toHaveBeenCalledWith(expect.stringContaining("does not require command position check"));
}));
}));