diff --git a/.github/ISSUE_TEMPLATE/custom.md b/.github/ISSUE_TEMPLATE/custom.md
new file mode 100644
index 0000000..48d5f81
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/custom.md
@@ -0,0 +1,10 @@
+---
+name: Custom issue template
+about: Describe this issue template's purpose here.
+title: ''
+labels: ''
+assignees: ''
+
+---
+
+
diff --git a/.github/workflows/Alma_build.yml b/.github/workflows/Alma_build.yml
index 67d8f22..0e4494f 100644
--- a/.github/workflows/Alma_build.yml
+++ b/.github/workflows/Alma_build.yml
@@ -44,16 +44,16 @@ jobs:
steps:
- name: Checkout main repository code
- uses: actions/checkout@v4
+ uses: actions/checkout@v6
- name: Checkout dependency repository (xengine)
- uses: actions/checkout@v4
+ uses: actions/checkout@v6
with:
repository: libxengine/libxengine
path: libxengine
- name: sub module checkout (opensource)
- uses: actions/checkout@v4
+ uses: actions/checkout@v6
with:
repository: libxengine/XEngine_OPenSource
path: XEngine_Source/XEngine_DependLibrary
@@ -89,7 +89,7 @@ jobs:
./XEngine_MQServiceApp -t
- name: Upload folder as artifact
- uses: actions/upload-artifact@v4
+ uses: actions/upload-artifact@v7
with:
name: XEngine_MQServiceApp-AlmaLinux_${{ matrix.version }}_${{ matrix.artifact }}
path: XEngine_Release/
\ No newline at end of file
diff --git a/.github/workflows/Centos_build.yml b/.github/workflows/Centos_build.yml
index d68d0ff..2aa6954 100644
--- a/.github/workflows/Centos_build.yml
+++ b/.github/workflows/Centos_build.yml
@@ -3,7 +3,7 @@ name: centos build workflows
on:
push:
branches:
- - 'develop'
+ - 'develop1'
paths:
- 'XEngine_Source/**'
- 'XEngine_Release/**'
@@ -48,16 +48,16 @@ jobs:
steps:
- name: Checkout main repository code
- uses: actions/checkout@v4
+ uses: actions/checkout@v6
- name: Checkout dependency repository (xengine)
- uses: actions/checkout@v4
+ uses: actions/checkout@v6
with:
repository: libxengine/libxengine
path: libxengine
- name: sub module checkout (opensource)
- uses: actions/checkout@v4
+ uses: actions/checkout@v6
with:
repository: libxengine/XEngine_OPenSource
path: XEngine_Source/XEngine_DependLibrary
@@ -95,7 +95,7 @@ jobs:
./XEngine_MQServiceApp -t
- name: Upload folder as artifact with CentOS
- uses: actions/upload-artifact@v4
+ uses: actions/upload-artifact@v7
with:
name: XEngine_MQServiceApp-CentOS_${{ matrix.version }}_${{ matrix.artifact }}
path: XEngine_Release/
diff --git a/.github/workflows/Mintbuild.yml b/.github/workflows/Mintbuild.yml
new file mode 100644
index 0000000..80b24f6
--- /dev/null
+++ b/.github/workflows/Mintbuild.yml
@@ -0,0 +1,73 @@
+name: MintLinux build workflows
+
+on:
+ push:
+ branches:
+ - 'develop'
+ paths:
+ - 'XEngine_Source/**'
+ - 'XEngine_Release/**'
+ - '.github/**'
+
+permissions:
+ contents: read
+
+jobs:
+ build:
+ runs-on: ${{ matrix.runner }}
+ container:
+ image: ${{ matrix.name }}
+ options: --platform ${{ matrix.platform }}
+ strategy:
+ matrix:
+ include:
+ - arch: amd64
+ runner: ubuntu-24.04
+ platform: linux/amd64
+ artifact: x86-64
+ name: linuxmintd/mint22-amd64
+ version: 22
+
+ steps:
+ - name: Checkout main repository code
+ uses: actions/checkout@v6
+
+ - name: Checkout dependency repository (xengine)
+ uses: actions/checkout@v6
+ with:
+ repository: libxengine/libxengine
+ path: libxengine
+
+ - name: sub module checkout (opensource)
+ uses: actions/checkout@v6
+ with:
+ repository: libxengine/XEngine_OPenSource
+ path: XEngine_Source/XEngine_DependLibrary
+
+ - name: Set TERM variable
+ run: echo "TERM=xterm" >> $GITHUB_ENV
+
+ - name: Set up Dependency ubuntu24.04 Environment
+ run: |
+ cd libxengine
+ chmod 777 *
+ sudo ./XEngine_LINEnv.sh -i 3
+
+ - name: make
+ run: |
+ cd XEngine_Source
+ make RELEASE=1
+ make FLAGS=InstallAll
+ make FLAGS=CleanAll
+ cd ..
+ - name: test
+ run: |
+ cd XEngine_Release
+ ./XEngine_MQServiceApp -t
+
+ - name: Upload folder as artifact
+ uses: actions/upload-artifact@v7
+ with:
+ name: XEngine_MQServiceApp-MintLinux_${{ matrix.version }}_x86-64
+ path: XEngine_Release/
+ retention-days: 1
\ No newline at end of file
diff --git a/.github/workflows/Rocky_build.yml b/.github/workflows/Rocky_build.yml
index 50aa58f..601c610 100644
--- a/.github/workflows/Rocky_build.yml
+++ b/.github/workflows/Rocky_build.yml
@@ -44,18 +44,18 @@ jobs:
steps:
- name: Checkout main repository code
- uses: actions/checkout@v4
+ uses: actions/checkout@v6
with:
ref: 'develop'
- name: Checkout dependency repository (xengine)
- uses: actions/checkout@v4
+ uses: actions/checkout@v6
with:
repository: libxengine/libxengine
path: libxengine
- name: sub module checkout (opensource)
- uses: actions/checkout@v4
+ uses: actions/checkout@v6
with:
repository: libxengine/XEngine_OPenSource
path: XEngine_Source/XEngine_DependLibrary
@@ -95,7 +95,7 @@ jobs:
./XEngine_MQServiceApp -t
- name: Upload folder as artifact with CentOS
- uses: actions/upload-artifact@v4
+ uses: actions/upload-artifact@v7
with:
name: XEngine_MQServiceApp-RockyLinux_${{ matrix.version }}_${{ matrix.artifact }}
path: XEngine_Release/
diff --git a/.github/workflows/Ubuntu_build.yml b/.github/workflows/Ubuntu_build.yml
index 6138309..1f03e85 100644
--- a/.github/workflows/Ubuntu_build.yml
+++ b/.github/workflows/Ubuntu_build.yml
@@ -23,12 +23,12 @@ jobs:
steps:
- name: Checkout main repository code
- uses: actions/checkout@v4
+ uses: actions/checkout@v6
with:
ref: 'develop'
- name: Checkout dependency repository (xengine)
- uses: actions/checkout@v4
+ uses: actions/checkout@v6
with:
repository: libxengine/libxengine
path: libxengine
@@ -96,28 +96,28 @@ jobs:
- name: Upload folder as artifact with ubuntu22.04 x86-64
if: matrix.os == 'ubuntu-22.04'
- uses: actions/upload-artifact@v4
+ uses: actions/upload-artifact@v7
with:
name: XEngine_MQServiceApp-Ubuntu_22.04_x86_64
path: XEngine_Release/
retention-days: 1
- name: Upload folder as artifact with ubuntu24.04 x86-64
if: matrix.os == 'ubuntu-24.04'
- uses: actions/upload-artifact@v4
+ uses: actions/upload-artifact@v7
with:
name: XEngine_MQServiceApp-Ubuntu_24.04_x86_64
path: XEngine_Release/
retention-days: 1
- name: Upload folder as artifact with ubuntu22.04 Arm64
if: matrix.os == 'ubuntu-22.04-arm'
- uses: actions/upload-artifact@v4
+ uses: actions/upload-artifact@v7
with:
name: XEngine_MQServiceApp-Ubuntu_22.04_Arm64
path: XEngine_Release/
retention-days: 1
- name: Upload folder as artifact with ubuntu24.04 Arm64
if: matrix.os == 'ubuntu-24.04-arm'
- uses: actions/upload-artifact@v4
+ uses: actions/upload-artifact@v7
with:
name: XEngine_MQServiceApp-Ubuntu_24.04_Arm64
path: XEngine_Release/
diff --git a/.github/workflows/agentics-maintenance.yml b/.github/workflows/agentics-maintenance.yml
new file mode 100644
index 0000000..6bd015f
--- /dev/null
+++ b/.github/workflows/agentics-maintenance.yml
@@ -0,0 +1,607 @@
+# ___ _ _
+# / _ \ | | (_)
+# | |_| | __ _ ___ _ __ | |_ _ ___
+# | _ |/ _` |/ _ \ '_ \| __| |/ __|
+# | | | | (_| | __/ | | | |_| | (__
+# \_| |_/\__, |\___|_| |_|\__|_|\___|
+# __/ |
+# _ _ |___/
+# | | | | / _| |
+# | | | | ___ _ __ _ __| |_| | _____ ____
+# | |/\| |/ _ \ '__| |/ /| _| |/ _ \ \ /\ / / ___|
+# \ /\ / (_) | | | | ( | | | | (_) \ V V /\__ \
+# \/ \/ \___/|_| |_|\_\|_| |_|\___/ \_/\_/ |___/
+#
+# This file was automatically generated by pkg/workflow/maintenance_workflow.go (v0.79.6). DO NOT EDIT.
+#
+# To regenerate this workflow, run:
+# gh aw compile
+# Not all edits will cause changes to this file.
+#
+# For more information: https://github.github.com/gh-aw/introduction/overview/
+#
+# Alternative regeneration methods:
+# make recompile
+#
+# Or use the gh-aw CLI directly:
+# ./gh-aw compile --validate --verbose
+#
+# The workflow is generated when any workflow uses the 'expires' field
+# in create-discussions, create-issues, or create-pull-request safe-outputs configuration.
+# Schedule frequency is automatically determined by the shortest expiration time.
+#
+name: Agentic Maintenance
+
+on:
+ schedule:
+ - cron: "37 0 * * *" # Daily (based on minimum expires: 30 days)
+ workflow_dispatch:
+ inputs:
+ operation:
+ description: 'Optional maintenance operation to run'
+ required: false
+ type: choice
+ default: ''
+ options:
+ - ''
+ - 'disable'
+ - 'enable'
+ - 'update'
+ - 'upgrade'
+ - 'safe_outputs'
+ - 'create_labels'
+ - 'activity_report'
+ - 'close_agentic_workflows_issues'
+ - 'clean_cache_memories'
+ - 'update_pull_request_branches'
+ - 'validate'
+ - 'forecast'
+ run_url:
+ description: 'Run URL or run ID to replay safe outputs from (e.g. https://github.com/owner/repo/actions/runs/12345 or 12345). Required when operation is safe_outputs.'
+ required: false
+ type: string
+ default: ''
+ workflow_call:
+ inputs:
+ operation:
+ description: 'Optional maintenance operation to run (disable, enable, update, upgrade, safe_outputs, create_labels, activity_report, close_agentic_workflows_issues, clean_cache_memories, update_pull_request_branches, validate, forecast)'
+ required: false
+ type: string
+ default: ''
+ run_url:
+ description: 'Run URL or run ID to replay safe outputs from (e.g. https://github.com/owner/repo/actions/runs/12345 or 12345). Required when operation is safe_outputs.'
+ required: false
+ type: string
+ default: ''
+ outputs:
+ operation_completed:
+ description: 'The maintenance operation that was completed (empty when none ran or a scheduled job ran)'
+ value: ${{ jobs.run_operation.outputs.operation || inputs.operation }}
+ applied_run_url:
+ description: 'The run URL that safe outputs were applied from'
+ value: ${{ jobs.apply_safe_outputs.outputs.run_url }}
+
+permissions: {}
+
+jobs:
+ close-expired-entities:
+ if: ${{ (!(github.event.repository.fork)) && github.event_name != 'push' && (github.event_name != 'workflow_dispatch' && github.event_name != 'workflow_call' || inputs.operation == '') }}
+ runs-on: ubuntu-slim
+ permissions:
+ discussions: write
+ issues: write
+ pull-requests: write
+ steps:
+ - name: Setup Scripts
+ uses: github/gh-aw-actions/setup@5c2fe865bb4dc46e1450f6ee0d0541d759aea73a # v0.79.6
+ with:
+ destination: ${{ runner.temp }}/gh-aw/actions
+
+ - name: Close expired discussions
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ 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/close_expired_discussions.cjs');
+ await main();
+
+ - name: Close expired issues
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ 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/close_expired_issues.cjs');
+ await main();
+
+ - name: Close expired pull requests
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ 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/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') }}
+ runs-on: ubuntu-slim
+ permissions:
+ actions: write
+ steps:
+ - name: Setup Scripts
+ uses: github/gh-aw-actions/setup@5c2fe865bb4dc46e1450f6ee0d0541d759aea73a # v0.79.6
+ with:
+ destination: ${{ runner.temp }}/gh-aw/actions
+
+ - name: Cleanup outdated cache-memory entries
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ 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/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)) }}
+ runs-on: ubuntu-slim
+ permissions:
+ actions: write
+ contents: write
+ pull-requests: write
+ outputs:
+ operation: ${{ steps.record.outputs.operation }}
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+ with:
+ persist-credentials: false
+
+ - name: Setup Scripts
+ uses: github/gh-aw-actions/setup@5c2fe865bb4dc46e1450f6ee0d0541d759aea73a # v0.79.6
+ with:
+ destination: ${{ runner.temp }}/gh-aw/actions
+
+ - name: Check admin/maintainer permissions
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ 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_team_member.cjs');
+ await main();
+
+ - name: Install gh-aw
+ uses: github/gh-aw-actions/setup-cli@5c2fe865bb4dc46e1450f6ee0d0541d759aea73a # v0.79.6
+ with:
+ version: v0.79.6
+
+ - name: Run operation
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ GH_AW_OPERATION: ${{ inputs.operation }}
+ GH_AW_CMD_PREFIX: gh aw
+ 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/run_operation_update_upgrade.cjs');
+ await main();
+
+ - name: Record outputs
+ id: record
+ run: echo "operation=${{ inputs.operation }}" >> "$GITHUB_OUTPUT"
+
+ update_pull_request_branches:
+ if: ${{ (github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call') && inputs.operation == 'update_pull_request_branches' && (!(github.event.repository.fork)) }}
+ runs-on: ubuntu-slim
+ permissions:
+ contents: write
+ pull-requests: write
+ steps:
+ - name: Setup Scripts
+ uses: github/gh-aw-actions/setup@5c2fe865bb4dc46e1450f6ee0d0541d759aea73a # v0.79.6
+ with:
+ destination: ${{ runner.temp }}/gh-aw/actions
+
+ - name: Check admin/maintainer permissions
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ 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_team_member.cjs');
+ await main();
+
+ - name: Update pull request branches
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ 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/update_pull_request_branches.cjs');
+ await main();
+
+ apply_safe_outputs:
+ if: ${{ (github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call') && inputs.operation == 'safe_outputs' && (!(github.event.repository.fork)) }}
+ runs-on: ubuntu-slim
+ permissions:
+ actions: read
+ contents: write
+ discussions: write
+ issues: write
+ pull-requests: write
+ outputs:
+ run_url: ${{ steps.record.outputs.run_url }}
+ steps:
+ - name: Checkout actions folder
+ uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+ with:
+ sparse-checkout: |
+ actions
+ persist-credentials: false
+
+ - name: Setup Scripts
+ uses: github/gh-aw-actions/setup@5c2fe865bb4dc46e1450f6ee0d0541d759aea73a # v0.79.6
+ with:
+ destination: ${{ runner.temp }}/gh-aw/actions
+
+ - name: Check admin/maintainer permissions
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ 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_team_member.cjs');
+ await main();
+
+ - name: Apply Safe Outputs
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ GH_AW_RUN_URL: ${{ inputs.run_url }}
+ 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/apply_safe_outputs_replay.cjs');
+ await main();
+
+ - name: Record outputs
+ id: record
+ run: echo "run_url=${{ inputs.run_url }}" >> "$GITHUB_OUTPUT"
+
+ create_labels:
+ if: ${{ (github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call') && inputs.operation == 'create_labels' && (!(github.event.repository.fork)) }}
+ runs-on: ubuntu-slim
+ permissions:
+ contents: read
+ issues: write
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+ with:
+ persist-credentials: false
+
+ - name: Setup Scripts
+ uses: github/gh-aw-actions/setup@5c2fe865bb4dc46e1450f6ee0d0541d759aea73a # v0.79.6
+ with:
+ destination: ${{ runner.temp }}/gh-aw/actions
+
+ - name: Check admin/maintainer permissions
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ 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_team_member.cjs');
+ await main();
+
+ - name: Install gh-aw
+ uses: github/gh-aw-actions/setup-cli@5c2fe865bb4dc46e1450f6ee0d0541d759aea73a # v0.79.6
+ with:
+ version: v0.79.6
+
+ - name: Create missing labels
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_CMD_PREFIX: gh aw
+ 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/create_labels.cjs');
+ await main();
+
+ activity_report:
+ if: ${{ (github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call') && inputs.operation == 'activity_report' && (!(github.event.repository.fork)) }}
+ runs-on: ubuntu-slim
+ timeout-minutes: 120
+ permissions:
+ actions: read
+ contents: read
+ issues: write
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+ with:
+ persist-credentials: false
+
+ - name: Setup Scripts
+ uses: github/gh-aw-actions/setup@5c2fe865bb4dc46e1450f6ee0d0541d759aea73a # v0.79.6
+ with:
+ destination: ${{ runner.temp }}/gh-aw/actions
+
+ - name: Check admin/maintainer permissions
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ 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_team_member.cjs');
+ await main();
+
+ - name: Install gh-aw
+ uses: github/gh-aw-actions/setup-cli@5c2fe865bb4dc46e1450f6ee0d0541d759aea73a # v0.79.6
+ with:
+ version: v0.79.6
+
+ - name: Restore activity report logs cache
+ id: activity_report_logs_cache
+ uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
+ with:
+ path: ./.cache/gh-aw/activity-report-logs
+ key: ${{ runner.os }}-activity-report-logs-${{ github.repository }}-${{ github.ref_name }}-${{ github.run_id }}
+ restore-keys: |
+ ${{ runner.os }}-activity-report-logs-${{ github.repository }}-
+ ${{ runner.os }}-activity-report-logs-
+ - name: Download activity report logs
+ timeout-minutes: 20
+ shell: bash
+ env:
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ GH_AW_CMD_PREFIX: gh aw
+ run: |
+ ${GH_AW_CMD_PREFIX} logs \
+ --repo "${{ github.repository }}" \
+ --start-date -1w \
+ --count 100 \
+ --output ./.cache/gh-aw/activity-report-logs \
+ --format markdown \
+ > ./.cache/gh-aw/activity-report-logs/report.md
+
+ - name: Save activity report logs cache
+ if: ${{ always() }}
+ uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
+ with:
+ path: ./.cache/gh-aw/activity-report-logs
+ key: ${{ steps.activity_report_logs_cache.outputs.cache-primary-key }}
+
+ - name: Generate activity report issue
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ with:
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ script: |
+ const fs = require('node:fs');
+ const reportPath = './.cache/gh-aw/activity-report-logs/report.md';
+ if (!fs.existsSync(reportPath)) {
+ core.warning('Activity report markdown not found at ' + reportPath + '; skipping issue creation.');
+ return;
+ }
+ let reportBody = '';
+ try {
+ reportBody = fs.readFileSync(reportPath, 'utf8').trim();
+ } catch (error) {
+ core.warning('Failed to read activity report markdown at ' + reportPath + ': ' + error.message);
+ return;
+ }
+ if (!reportBody) {
+ core.warning('Activity report markdown is empty at ' + reportPath + '; skipping issue creation.');
+ return;
+ }
+ const repoSlug = context.repo.owner + '/' + context.repo.repo;
+ const body = [
+ '### Agentic workflow activity report',
+ '',
+ 'Repository: ' + repoSlug,
+ 'Generated at: ' + new Date().toISOString(),
+ '',
+ reportBody,
+ ].join('\n');
+ const createdIssue = await github.rest.issues.create({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ title: '[aw] agentic status report',
+ body,
+ labels: ['agentic-workflows'],
+ });
+ core.info('Created issue #' + createdIssue.data.number + ': ' + createdIssue.data.html_url);
+
+ forecast_report:
+ if: ${{ (github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call') && inputs.operation == 'forecast' && (!(github.event.repository.fork)) }}
+ runs-on: ubuntu-slim
+ timeout-minutes: 60
+ permissions:
+ actions: read
+ contents: read
+ issues: write
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+ with:
+ persist-credentials: false
+
+ - name: Setup Scripts
+ uses: github/gh-aw-actions/setup@5c2fe865bb4dc46e1450f6ee0d0541d759aea73a # v0.79.6
+ with:
+ destination: ${{ runner.temp }}/gh-aw/actions
+
+ - name: Check admin/maintainer permissions
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ 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_team_member.cjs');
+ await main();
+
+ - name: Install gh-aw
+ uses: github/gh-aw-actions/setup-cli@5c2fe865bb4dc46e1450f6ee0d0541d759aea73a # v0.79.6
+ with:
+ version: v0.79.6
+
+ - name: Restore forecast report logs cache
+ id: forecast_report_logs_cache
+ uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
+ with:
+ path: ./.github/aw/logs
+ key: ${{ runner.os }}-forecast-report-logs-${{ github.repository }}-${{ github.ref_name }}-${{ github.run_id }}
+ restore-keys: |
+ ${{ runner.os }}-forecast-report-logs-${{ github.repository }}-
+ ${{ runner.os }}-forecast-report-logs-
+
+ - name: Generate forecast report
+ id: generate_forecast_report
+ timeout-minutes: 30
+ shell: bash
+ env:
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ DEBUG: "*"
+ GH_AW_CMD_PREFIX: gh aw
+ run: |
+ mkdir -p ./.cache/gh-aw/forecast
+ set +e
+ ${GH_AW_CMD_PREFIX} forecast --repo "${{ github.repository }}" --timeout 30 --verbose --json > ./.cache/gh-aw/forecast/report.json
+ forecast_exit_code=$?
+ set -e
+ if [ "${forecast_exit_code}" -eq 124 ]; then
+ echo '{"outcome":"timeout","message":"Forecast computation timed out after 30 minutes."}' > ./.cache/gh-aw/forecast/error.json
+ echo "::error::Forecast computation timed out after 30 minutes."
+ exit 1
+ fi
+ if [ "${forecast_exit_code}" -ne 0 ]; then
+ echo '{"outcome":"error","message":"Forecast computation failed before producing a report."}' > ./.cache/gh-aw/forecast/error.json
+ echo "::error::Forecast computation failed with exit code ${forecast_exit_code}."
+ exit 1
+ fi
+
+ - name: Debug forecast logs folder
+ if: ${{ always() }}
+ shell: bash
+ run: |
+ if [ ! -d ./.github/aw/logs ]; then
+ echo "Logs directory not found: ./.github/aw/logs"
+ exit 0
+ fi
+ echo "Files under ./.github/aw/logs:"
+ find ./.github/aw/logs -type f | sort
+
+ - name: Save forecast report logs cache
+ if: ${{ always() }}
+ uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
+ with:
+ path: ./.github/aw/logs
+ key: ${{ runner.os }}-forecast-report-logs-${{ github.repository }}-${{ github.ref_name }}-${{ github.run_id }}
+
+ - name: Generate forecast issue
+ if: ${{ always() }}
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ FORECAST_STEP_OUTCOME: ${{ steps.generate_forecast_report.outcome }}
+ 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/create_forecast_issue.cjs');
+ await main();
+
+ close_agentic_workflows_issues:
+ if: ${{ (github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call') && inputs.operation == 'close_agentic_workflows_issues' && (!(github.event.repository.fork)) }}
+ runs-on: ubuntu-slim
+ permissions:
+ issues: write
+ steps:
+ - name: Setup Scripts
+ uses: github/gh-aw-actions/setup@5c2fe865bb4dc46e1450f6ee0d0541d759aea73a # v0.79.6
+ with:
+ destination: ${{ runner.temp }}/gh-aw/actions
+
+ - name: Check admin/maintainer permissions
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ 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_team_member.cjs');
+ await main();
+
+ - name: Close no-repro agentic-workflows issues
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ 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/close_agentic_workflows_issues.cjs');
+ await main();
+
+ validate_workflows:
+ if: ${{ (github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call') && inputs.operation == 'validate' && (!(github.event.repository.fork)) }}
+ runs-on: ubuntu-latest
+ permissions:
+ contents: read
+ issues: write
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+ with:
+ persist-credentials: false
+
+ - name: Setup Scripts
+ uses: github/gh-aw-actions/setup@5c2fe865bb4dc46e1450f6ee0d0541d759aea73a # v0.79.6
+ with:
+ destination: ${{ runner.temp }}/gh-aw/actions
+
+ - name: Check admin/maintainer permissions
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ 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_team_member.cjs');
+ await main();
+
+ - name: Install gh-aw
+ uses: github/gh-aw-actions/setup-cli@5c2fe865bb4dc46e1450f6ee0d0541d759aea73a # v0.79.6
+ with:
+ version: v0.79.6
+
+ - name: Validate workflows and file issue on findings
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_CMD_PREFIX: gh aw
+ 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/run_validate_workflows.cjs');
+ await main();
diff --git a/.github/workflows/auto-code.lock.yml b/.github/workflows/auto-code.lock.yml
new file mode 100644
index 0000000..2a10a78
--- /dev/null
+++ b/.github/workflows/auto-code.lock.yml
@@ -0,0 +1,1327 @@
+# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"2db2d71c8e339e852eac5725e4d115b95a5f802b476179caca5c78d07e99d221","body_hash":"f4631eca0387739bc44c8ad08d5c0670c98c72198743c2ea9240d97915dca04e","compiler_version":"v0.79.6","agent_id":"copilot","engine_versions":{"copilot":"1.0.60"}}
+# gh-aw-manifest: {"version":1,"secrets":["GH_AW_CI_TRIGGER_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN","OPENAI_API_KEY"],"actions":[{"repo":"actions/checkout","sha":"df4cb1c069e1874edd31b4311f1884172cec0e10","version":"v6.0.3"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"5c2fe865bb4dc46e1450f6ee0d0541d759aea73a","version":"v0.79.6"}],"containers":[{"image":"ghcr.io/github/github-mcp-server:v1.1.2","digest":"sha256:30197479d8036c7811892bc07e06f9a05c9ef3cdd79bc59f256d50647f95788c","pinned_image":"ghcr.io/github/github-mcp-server:v1.1.2@sha256:30197479d8036c7811892bc07e06f9a05c9ef3cdd79bc59f256d50647f95788c"}]}
+# ___ _ _
+# / _ \ | | (_)
+# | |_| | __ _ ___ _ __ | |_ _ ___
+# | _ |/ _` |/ _ \ '_ \| __| |/ __|
+# | | | | (_| | __/ | | | |_| | (__
+# \_| |_/\__, |\___|_| |_|\__|_|\___|
+# __/ |
+# _ _ |___/
+# | | | | / _| |
+# | | | | ___ _ __ _ __| |_| | _____ ____
+# | |/\| |/ _ \ '__| |/ /| _| |/ _ \ \ /\ / / ___|
+# \ /\ / (_) | | | | ( | | | | (_) \ V V /\__ \
+# \/ \/ \___/|_| |_|\_\|_| |_|\___/ \_/\_/ |___/
+#
+# This file was automatically generated by gh-aw (v0.79.6). 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/
+#
+#
+# Secrets used:
+# - GH_AW_CI_TRIGGER_TOKEN
+# - GH_AW_GITHUB_MCP_SERVER_TOKEN
+# - GH_AW_GITHUB_TOKEN
+# - GITHUB_TOKEN
+# - OPENAI_API_KEY
+#
+# Custom actions used:
+# - actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+# - actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
+# - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+# - actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
+# - github/gh-aw-actions/setup@5c2fe865bb4dc46e1450f6ee0d0541d759aea73a # v0.79.6
+#
+# Container images used:
+# - ghcr.io/github/github-mcp-server:v1.1.2@sha256:30197479d8036c7811892bc07e06f9a05c9ef3cdd79bc59f256d50647f95788c
+
+name: "自动处理 Issue"
+on:
+ issues:
+ types:
+ - labeled
+
+permissions: {}
+
+concurrency:
+ group: "gh-aw-${{ github.workflow }}-${{ github.event.issue.number || github.run_id }}"
+
+run-name: "自动处理 Issue"
+
+jobs:
+ activation:
+ needs: pre_activation
+ if: needs.pre_activation.outputs.activated == 'true'
+ runs-on: ubuntu-slim
+ permissions:
+ actions: read
+ contents: read
+ env:
+ GH_AW_MAX_DAILY_AI_CREDITS: ${{ vars.GH_AW_DEFAULT_MAX_DAILY_AI_CREDITS || '5000' }}
+ outputs:
+ body: ${{ steps.sanitized.outputs.body }}
+ comment_id: ""
+ comment_repo: ""
+ daily_effective_workflow_exceeded: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_effective_workflow_exceeded == 'true' }}
+ daily_effective_workflow_threshold: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_effective_workflow_threshold || '' }}
+ daily_effective_workflow_total_effective_tokens: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_effective_workflow_total_effective_tokens || '' }}
+ engine_id: ${{ steps.generate_aw_info.outputs.engine_id }}
+ lockdown_check_failed: ${{ steps.generate_aw_info.outputs.lockdown_check_failed == 'true' }}
+ model: ${{ steps.generate_aw_info.outputs.model }}
+ setup-parent-span-id: ${{ steps.setup.outputs.parent-span-id || steps.setup.outputs.span-id }}
+ setup-span-id: ${{ steps.setup.outputs.span-id }}
+ setup-trace-id: ${{ steps.setup.outputs.trace-id }}
+ stale_lock_file_failed: ${{ steps.check-lock-file.outputs.stale_lock_file_failed == 'true' }}
+ text: ${{ steps.sanitized.outputs.text }}
+ title: ${{ steps.sanitized.outputs.title }}
+ steps:
+ - name: Setup Scripts
+ id: setup
+ uses: github/gh-aw-actions/setup@5c2fe865bb4dc46e1450f6ee0d0541d759aea73a # v0.79.6
+ with:
+ destination: ${{ runner.temp }}/gh-aw/actions
+ job-name: ${{ github.job }}
+ trace-id: ${{ needs.pre_activation.outputs.setup-trace-id }}
+ parent-span-id: ${{ needs.pre_activation.outputs.setup-parent-span-id || needs.pre_activation.outputs.setup-span-id }}
+ safe-output-artifact-client: ${{ env.GH_AW_MAX_DAILY_AI_CREDITS != '' }}
+ env:
+ GH_AW_SETUP_WORKFLOW_NAME: "自动处理 Issue"
+ GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/auto-code.lock.yml@${{ github.ref }}
+ GH_AW_INFO_VERSION: "1.0.60"
+ GH_AW_INFO_ENGINE_ID: "copilot"
+ - 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 || vars.GH_AW_DEFAULT_MODEL_COPILOT || 'claude-sonnet-4.6' }}
+ GH_AW_INFO_VERSION: "1.0.60"
+ GH_AW_INFO_AGENT_VERSION: "1.0.60"
+ GH_AW_INFO_CLI_VERSION: "v0.79.6"
+ GH_AW_INFO_WORKFLOW_NAME: "自动处理 Issue"
+ GH_AW_INFO_EXPERIMENTAL: "false"
+ GH_AW_INFO_SUPPORTS_TOOLS_ALLOWLIST: "true"
+ GH_AW_INFO_STAGED: "false"
+ GH_AW_INFO_ALLOWED_DOMAINS: '["defaults","ark.cn-beijing.volces.com"]'
+ GH_AW_INFO_FIREWALL_ENABLED: "false"
+ GH_AW_INFO_AWF_VERSION: ""
+ GH_AW_INFO_AWMG_VERSION: ""
+ GH_AW_INFO_FIREWALL_TYPE: ""
+ GH_AW_COMPILED_STRICT: "false"
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ 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: Check daily workflow token guardrail
+ id: daily-effective-workflow-guardrail
+ if: ${{ env.GH_AW_MAX_DAILY_AI_CREDITS != '' }}
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_WORKFLOW_NAME: "自动处理 Issue"
+ GH_AW_WORKFLOW_ID: "auto-code"
+ GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
+ GH_AW_WORKFLOW_DISPATCH_AW_CONTEXT: ${{ github.event.inputs.aw_context || '' }}
+ GH_AW_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ GH_AW_MAX_DAILY_AI_CREDITS: ${{ vars.GH_AW_DEFAULT_MAX_DAILY_AI_CREDITS || '5000' }}
+ 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_daily_aic_workflow_guardrail.cjs');
+ await main();
+ - name: Checkout .github and .agents folders
+ uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+ with:
+ persist-credentials: false
+ sparse-checkout: |
+ .github
+ .agents
+ .antigravity
+ .claude
+ .codex
+ .crush
+ .gemini
+ .opencode
+ .pi
+ sparse-checkout-cone-mode: true
+ fetch-depth: 1
+ - name: Save agent config folders for base branch restoration
+ env:
+ GH_AW_AGENT_FOLDERS: ".agents .antigravity .claude .codex .crush .gemini .github .opencode .pi"
+ GH_AW_AGENT_FILES: ".crush.json AGENTS.md ANTIGRAVITY.md CLAUDE.md GEMINI.md PI.md opencode.jsonc"
+ # poutine:ignore untrusted_checkout_exec
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/save_base_github_folders.sh"
+ - name: Check workflow lock file
+ id: check-lock-file
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_WORKFLOW_FILE: "auto-code.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@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_COMPILED_VERSION: "v0.79.6"
+ 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: Compute current body text
+ id: sanitized
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ 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,ark.cn-beijing.volces.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"
+ 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/compute_text.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_EXPR_1A3A194A: ${{ github.event.discussion.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'discussion' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }}
+ GH_AW_EXPR_463A214A: ${{ github.event.pull_request.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'pull_request' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }}
+ GH_AW_EXPR_802A9F6A: ${{ github.event.issue.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'issue' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }}
+ GH_AW_EXPR_FF1D34CE: ${{ github.event.comment.id || fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').comment_id }}
+ GH_AW_GITHUB_ACTOR: ${{ github.actor }}
+ GH_AW_GITHUB_EVENT_ISSUE_NUMBER: ${{ github.event.issue.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_791c723be483e095_EOF'
+
+ GH_AW_PROMPT_791c723be483e095_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_791c723be483e095_EOF'
+
+ Tools: add_comment, create_pull_request, missing_tool, missing_data, noop
+ GH_AW_PROMPT_791c723be483e095_EOF
+ cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_create_pull_request.md"
+ cat << 'GH_AW_PROMPT_791c723be483e095_EOF'
+
+ GH_AW_PROMPT_791c723be483e095_EOF
+ cat "${RUNNER_TEMP}/gh-aw/prompts/mcp_cli_tools_prompt.md"
+ cat << 'GH_AW_PROMPT_791c723be483e095_EOF'
+
+ The following GitHub context information is available for this workflow:
+ {{#if github.actor}}
+ - **actor**: __GH_AW_GITHUB_ACTOR__
+ {{/if}}
+ {{#if github.repository}}
+ - **repository**: __GH_AW_GITHUB_REPOSITORY__
+ {{/if}}
+ {{#if github.workspace}}
+ - **workspace**: __GH_AW_GITHUB_WORKSPACE__
+ {{/if}}
+ {{#if github.event.issue.number || (github.aw.context.item_type == 'issue' && github.aw.context.item_number)}}
+ - **issue-number**: #__GH_AW_EXPR_802A9F6A__
+ {{/if}}
+ {{#if github.event.discussion.number || (github.aw.context.item_type == 'discussion' && github.aw.context.item_number)}}
+ - **discussion-number**: #__GH_AW_EXPR_1A3A194A__
+ {{/if}}
+ {{#if github.event.pull_request.number || (github.aw.context.item_type == 'pull_request' && github.aw.context.item_number)}}
+ - **pull-request-number**: #__GH_AW_EXPR_463A214A__
+ {{/if}}
+ {{#if github.event.comment.id || github.aw.context.comment_id}}
+ - **comment-id**: __GH_AW_EXPR_FF1D34CE__
+ {{/if}}
+ {{#if github.run_id}}
+ - **workflow-run-id**: __GH_AW_GITHUB_RUN_ID__
+ {{/if}}
+
+
+ GH_AW_PROMPT_791c723be483e095_EOF
+ cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md"
+ cat << 'GH_AW_PROMPT_791c723be483e095_EOF'
+
+ {{#runtime-import .github/workflows/auto-code.md}}
+ GH_AW_PROMPT_791c723be483e095_EOF
+ } > "$GH_AW_PROMPT"
+ - name: Interpolate variables and render templates
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
+ GH_AW_ENGINE_ID: "copilot"
+ GH_AW_GITHUB_EVENT_ISSUE_NUMBER: ${{ github.event.issue.number }}
+ 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@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
+ GH_AW_EXPR_1A3A194A: ${{ github.event.discussion.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'discussion' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }}
+ GH_AW_EXPR_463A214A: ${{ github.event.pull_request.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'pull_request' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }}
+ GH_AW_EXPR_802A9F6A: ${{ github.event.issue.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'issue' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }}
+ GH_AW_EXPR_FF1D34CE: ${{ github.event.comment.id || fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').comment_id }}
+ GH_AW_GITHUB_ACTOR: ${{ github.actor }}
+ GH_AW_GITHUB_EVENT_ISSUE_NUMBER: ${{ github.event.issue.number }}
+ GH_AW_GITHUB_REPOSITORY: ${{ github.repository }}
+ GH_AW_GITHUB_RUN_ID: ${{ github.run_id }}
+ GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }}
+ GH_AW_MCP_CLI_SERVERS_LIST: '- `safeoutputs` — run `safeoutputs --help` to see available tools'
+ 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_EXPR_1A3A194A: process.env.GH_AW_EXPR_1A3A194A,
+ GH_AW_EXPR_463A214A: process.env.GH_AW_EXPR_463A214A,
+ GH_AW_EXPR_802A9F6A: process.env.GH_AW_EXPR_802A9F6A,
+ GH_AW_EXPR_FF1D34CE: process.env.GH_AW_EXPR_FF1D34CE,
+ GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR,
+ GH_AW_GITHUB_EVENT_ISSUE_NUMBER: process.env.GH_AW_GITHUB_EVENT_ISSUE_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_MCP_CLI_SERVERS_LIST: process.env.GH_AW_MCP_CLI_SERVERS_LIST,
+ 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
+ include-hidden-files: true
+ path: |
+ /tmp/gh-aw/aw_info.json
+ /tmp/gh-aw/model_multipliers.json
+ /tmp/gh-aw/models.json
+ /tmp/gh-aw/aw-prompts/prompt.txt
+ /tmp/gh-aw/aw-prompts/prompt-template.txt
+ /tmp/gh-aw/aw-prompts/prompt-import-tree.json
+ /tmp/gh-aw/github_rate_limits.jsonl
+ /tmp/gh-aw/base
+ /tmp/gh-aw/.github/agents
+ /tmp/gh-aw/.github/skills
+ if-no-files-found: ignore
+ retention-days: 1
+
+ agent:
+ needs: activation
+ if: needs.activation.outputs.daily_effective_workflow_exceeded != 'true'
+ runs-on: ubuntu-latest
+ permissions:
+ contents: read
+ copilot-requests: write
+ issues: read
+ pull-requests: read
+ 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: autocode
+ outputs:
+ agentic_engine_timeout: ${{ steps.detect-agent-errors.outputs.agentic_engine_timeout || 'false' }}
+ ai_credits_rate_limit_error: ${{ steps.parse-mcp-gateway.outputs.ai_credits_rate_limit_error || 'false' }}
+ aic: ${{ steps.parse-mcp-gateway.outputs.aic }}
+ ambient_context: ${{ steps.parse-mcp-gateway.outputs.ambient_context }}
+ 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-agent-errors.outputs.inference_access_error || 'false' }}
+ mcp_policy_error: ${{ steps.detect-agent-errors.outputs.mcp_policy_error || 'false' }}
+ model: ${{ needs.activation.outputs.model }}
+ model_not_supported_error: ${{ steps.detect-agent-errors.outputs.model_not_supported_error || 'false' }}
+ output: ${{ steps.collect_output.outputs.output }}
+ output_types: ${{ steps.collect_output.outputs.output_types }}
+ setup-parent-span-id: ${{ steps.setup.outputs.parent-span-id || steps.setup.outputs.span-id }}
+ setup-span-id: ${{ steps.setup.outputs.span-id }}
+ setup-trace-id: ${{ steps.setup.outputs.trace-id }}
+ unknown_model_ai_credits: ${{ steps.parse-mcp-gateway.outputs.unknown_model_ai_credits || 'false' }}
+ steps:
+ - name: Setup Scripts
+ id: setup
+ uses: github/gh-aw-actions/setup@5c2fe865bb4dc46e1450f6ee0d0541d759aea73a # v0.79.6
+ with:
+ destination: ${{ runner.temp }}/gh-aw/actions
+ job-name: ${{ github.job }}
+ trace-id: ${{ needs.activation.outputs.setup-trace-id }}
+ parent-span-id: ${{ needs.activation.outputs.setup-parent-span-id || needs.activation.outputs.setup-span-id }}
+ env:
+ GH_AW_SETUP_WORKFLOW_NAME: "自动处理 Issue"
+ GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/auto-code.lock.yml@${{ github.ref }}
+ GH_AW_INFO_VERSION: "1.0.60"
+ GH_AW_INFO_ENGINE_ID: "copilot"
+ - 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@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+ with:
+ persist-credentials: false
+ - 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 || github.event_name == 'workflow_dispatch' && fromJSON(github.event.inputs.aw_context || '{}').item_type == 'pull_request'
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ 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.60
+ env:
+ GH_HOST: github.com
+ - name: Parse integrity filter lists
+ id: parse-guard-vars
+ env:
+ GH_AW_BLOCKED_USERS_VAR: ${{ vars.GH_AW_GITHUB_BLOCKED_USERS || '' }}
+ GH_AW_TRUSTED_USERS_VAR: ${{ vars.GH_AW_GITHUB_TRUSTED_USERS || '' }}
+ GH_AW_APPROVAL_LABELS_VAR: ${{ vars.GH_AW_GITHUB_APPROVAL_LABELS || '' }}
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/parse_guard_list.sh"
+ - name: Download activation artifact
+ uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
+ with:
+ name: activation
+ path: /tmp/gh-aw
+ - name: Restore agent config folders from base branch
+ if: steps.checkout-pr.outcome == 'success'
+ env:
+ GH_AW_AGENT_FOLDERS: ".agents .antigravity .claude .codex .crush .gemini .github .opencode .pi"
+ GH_AW_AGENT_FILES: ".crush.json AGENTS.md ANTIGRAVITY.md CLAUDE.md GEMINI.md PI.md opencode.jsonc"
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_base_github_folders.sh"
+ - name: Restore inline sub-agents from activation artifact
+ env:
+ GH_AW_SUB_AGENT_DIR: ".github/agents"
+ GH_AW_SUB_AGENT_EXT: ".agent.md"
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_inline_sub_agents.sh"
+ - name: Restore inline skills from activation artifact
+ env:
+ GH_AW_SKILL_DIR: ".github/skills"
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_inline_skills.sh"
+ - name: Download container images
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/github-mcp-server:v1.1.2@sha256:30197479d8036c7811892bc07e06f9a05c9ef3cdd79bc59f256d50647f95788c
+ - name: Generate Safe Outputs Config
+ 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_b5dafa3335f30723_EOF'
+ {"add_comment":{"max":1},"create_pull_request":{"base_branch":"develop","max":1,"max_patch_files":100,"max_patch_size":1024,"protect_top_level_dot_folders":true,"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","DESIGN.md","README.md","CONTRIBUTING.md","CHANGELOG.md","SECURITY.md","CODE_OF_CONDUCT.md","AGENTS.md","CLAUDE.md","GEMINI.md"],"protected_files_policy":"allowed"},"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"report_incomplete":{}}
+ GH_AW_SAFE_OUTPUTS_CONFIG_b5dafa3335f30723_EOF
+ - name: Generate Safe Outputs Tools
+ env:
+ GH_AW_TOOLS_META_JSON: |
+ {
+ "description_suffixes": {
+ "add_comment": " CONSTRAINTS: Maximum 1 comment(s) can be added. Supports reply_to_id for discussion threading.",
+ "create_pull_request": " CONSTRAINTS: Maximum 1 pull request(s) can be created."
+ },
+ "repo_params": {},
+ "dynamic_tools": []
+ }
+ GH_AW_VALIDATION_JSON: |
+ {
+ "add_comment": {
+ "defaultMax": 1,
+ "fields": {
+ "body": {
+ "required": true,
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 65000
+ },
+ "item_number": {
+ "issueOrPRNumber": true
+ },
+ "reply_to_id": {
+ "type": "string",
+ "maxLength": 256
+ },
+ "repo": {
+ "type": "string",
+ "maxLength": 256
+ }
+ }
+ },
+ "create_pull_request": {
+ "defaultMax": 1,
+ "fields": {
+ "base": {
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 128
+ },
+ "body": {
+ "required": true,
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 65000
+ },
+ "branch": {
+ "required": true,
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 256
+ },
+ "draft": {
+ "type": "boolean"
+ },
+ "labels": {
+ "type": "array",
+ "itemType": "string",
+ "itemSanitize": true,
+ "itemMaxLength": 128
+ },
+ "repo": {
+ "type": "string",
+ "maxLength": 256
+ },
+ "title": {
+ "required": true,
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 128
+ }
+ }
+ },
+ "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
+ }
+ }
+ },
+ "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@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ 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_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+ 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="localhost"
+ export MCP_GATEWAY_HOST_DOMAIN="localhost"
+ 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"
+ MCP_GATEWAY_UID=$(id -u 2>/dev/null || echo '0')
+ MCP_GATEWAY_GID=$(id -g 2>/dev/null || echo '0')
+ case "${DOCKER_HOST:-}" in
+ unix://* ) DOCKER_SOCK_PATH="${DOCKER_HOST#unix://}" ;;
+ /* ) DOCKER_SOCK_PATH="$DOCKER_HOST" ;;
+ * ) DOCKER_SOCK_PATH=/var/run/docker.sock ;;
+ esac
+ DOCKER_SOCK_GID=$(stat -c '%g' "$DOCKER_SOCK_PATH" 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 '"${DOCKER_SOCK_PATH}"':/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 DOCKER_HOST=unix:///var/run/docker.sock -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.25'
+
+ 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_f41962abaffbda74_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs"
+ {
+ "mcpServers": {
+ "github": {
+ "type": "stdio",
+ "container": "ghcr.io/github/github-mcp-server:v1.1.2",
+ "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": {
+ "approval-labels": ${{ steps.parse-guard-vars.outputs.approval_labels }},
+ "blocked-users": ${{ steps.parse-guard-vars.outputs.blocked_users }},
+ "min-integrity": "none",
+ "repos": "all",
+ "trusted-users": ${{ steps.parse-guard-vars.outputs.trusted_users }}
+ }
+ }
+ },
+ "safeoutputs": {
+ "type": "http",
+ "url": "http://localhost:$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_f41962abaffbda74_EOF
+ - name: Mount MCP servers as CLIs
+ id: mount-mcp-clis
+ continue-on-error: true
+ env:
+ MCP_GATEWAY_API_KEY: ${{ steps.start-mcp-gateway.outputs.gateway-api-key }}
+ MCP_GATEWAY_DOMAIN: ${{ steps.start-mcp-gateway.outputs.gateway-domain }}
+ MCP_GATEWAY_PORT: ${{ steps.start-mcp-gateway.outputs.gateway-port }}
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ with:
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/mount_mcp_as_cli.cjs');
+ await main();
+ - name: Clean credentials
+ continue-on-error: true
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/clean_git_credentials.sh"
+ - name: Audit pre-agent workspace
+ id: pre_agent_audit
+ continue-on-error: true
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/audit_pre_agent_workspace.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(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(ls)
+ # --allow-tool shell(printf)
+ # --allow-tool shell(pwd)
+ # --allow-tool shell(safeoutputs:*)
+ # --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
+ printf '%s' "$(date +%s%3N)" > /tmp/gh-aw/agent_cli_start_ms.txt
+ touch /tmp/gh-aw/agent-step-summary.md
+ (umask 177 && touch /tmp/gh-aw/agent-stdio.log)
+ trap 'rm -f /home/runner/.copilot/settings.json' EXIT
+ mkdir -p /home/runner/.copilot
+ printf '%s' '{"builtInAgents":{"rubberDuck":false}}' > /home/runner/.copilot/settings.json
+ mkdir -p /tmp/
+ mkdir -p /tmp/gh-aw/
+ mkdir -p /tmp/gh-aw/agent/
+ mkdir -p /tmp/gh-aw/sandbox/agent/logs/
+ GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs copilot --add-dir /tmp/ --add-dir /tmp/gh-aw/ --add-dir /tmp/gh-aw/agent/ --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(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(ls)' --allow-tool 'shell(printf)' --allow-tool 'shell(pwd)' --allow-tool 'shell(safeoutputs:*)' --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 --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt 2>&1 | tee /tmp/gh-aw/agent-stdio.log
+ env:
+ COPILOT_AGENT_RUNNER_TYPE: STANDALONE
+ COPILOT_MODEL: doubao-seed-evolving
+ COPILOT_PROVIDER_BASE_URL: https://ark.cn-beijing.volces.com/api/v3
+ COPILOT_PROVIDER_BEARER_TOKEN: ${{ secrets.OPENAI_API_KEY }}
+ COPILOT_PROVIDER_TYPE: openai
+ COPILOT_PROVIDER_WIRE_API: responses
+ GH_AW_MAX_TURNS: ${{ vars.GH_AW_DEFAULT_MAX_TURNS || '' }}
+ 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_TIMEOUT_MINUTES: 20
+ GH_AW_VERSION: v0.79.6
+ GITHUB_API_URL: ${{ github.api_url }}
+ GITHUB_AW: true
+ GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows
+ 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 }}
+ RUNNER_TEMP: ${{ runner.temp }}
+ S2STOKENS: true
+ XDG_CONFIG_HOME: /home/runner
+ - name: Detect agent errors
+ if: always()
+ id: detect-agent-errors
+ continue-on-error: true
+ run: node "${RUNNER_TEMP}/gh-aw/actions/detect_agent_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@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ 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: 'GH_AW_GITHUB_MCP_SERVER_TOKEN,GH_AW_GITHUB_TOKEN,GITHUB_TOKEN,OPENAI_API_KEY'
+ 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_OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
+ - 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@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ 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,ark.cn-beijing.volces.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@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ 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@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ 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: 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/proxy-logs/
+ !/tmp/gh-aw/proxy-logs/proxy-tls/
+ /tmp/gh-aw/agent-stdio.log
+ /tmp/gh-aw/pre-agent-audit.txt
+ /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
+ if-no-files-found: ignore
+
+ conclusion:
+ needs:
+ - activation
+ - agent
+ - safe_outputs
+ if: >
+ always() && (needs.agent.result != 'skipped' || needs.activation.outputs.lockdown_check_failed == 'true' ||
+ needs.activation.outputs.stale_lock_file_failed == 'true' || needs.activation.outputs.daily_effective_workflow_exceeded == 'true')
+ runs-on: ubuntu-slim
+ permissions:
+ contents: write
+ discussions: write
+ issues: write
+ pull-requests: write
+ concurrency:
+ group: "gh-aw-conclusion-auto-code"
+ cancel-in-progress: false
+ queue: max
+ 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@5c2fe865bb4dc46e1450f6ee0d0541d759aea73a # v0.79.6
+ with:
+ destination: ${{ runner.temp }}/gh-aw/actions
+ job-name: ${{ github.job }}
+ trace-id: ${{ needs.activation.outputs.setup-trace-id }}
+ parent-span-id: ${{ needs.activation.outputs.setup-parent-span-id || needs.activation.outputs.setup-span-id }}
+ env:
+ GH_AW_SETUP_WORKFLOW_NAME: "自动处理 Issue"
+ GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/auto-code.lock.yml@${{ github.ref }}
+ GH_AW_INFO_VERSION: "1.0.60"
+ GH_AW_INFO_ENGINE_ID: "copilot"
+ - 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: Collect usage artifact files
+ if: always()
+ continue-on-error: true
+ run: |
+ mkdir -p /tmp/gh-aw/usage/agent /tmp/gh-aw/usage/detection
+ echo "Usage artifact source file status:"
+ for file in /tmp/gh-aw/aw-info.jsonl /tmp/gh-aw/agent_usage.jsonl /tmp/gh-aw/detection_usage.jsonl /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl; do
+ [ -f "$file" ] && echo "FOUND: $file" || echo "MISSING: $file"
+ done
+ [ -f /tmp/gh-aw/aw-info.jsonl ] && cp /tmp/gh-aw/aw-info.jsonl /tmp/gh-aw/usage/aw-info.jsonl || true
+ [ -f /tmp/gh-aw/agent_usage.jsonl ] && cp /tmp/gh-aw/agent_usage.jsonl /tmp/gh-aw/usage/agent_usage.jsonl || true
+ [ -f /tmp/gh-aw/detection_usage.jsonl ] && cp /tmp/gh-aw/detection_usage.jsonl /tmp/gh-aw/usage/detection_usage.jsonl || true
+ [ -f /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true
+ [ -f /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true
+ [ -f /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true
+ [ -f /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl || true
+ [ -f /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl || true
+ [ -f /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl || true
+ [ -f /tmp/gh-aw/usage/agent/token_usage.jsonl ] || : > /tmp/gh-aw/usage/agent/token_usage.jsonl
+ [ -f /tmp/gh-aw/usage/detection/token_usage.jsonl ] || : > /tmp/gh-aw/usage/detection/token_usage.jsonl
+ find /tmp/gh-aw/usage -type f -print | sort
+ - name: Upload usage artifact
+ if: always()
+ continue-on-error: true
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
+ with:
+ name: usage
+ path: |
+ /tmp/gh-aw/usage/aw-info.jsonl
+ /tmp/gh-aw/usage/agent_usage.jsonl
+ /tmp/gh-aw/usage/detection_usage.jsonl
+ /tmp/gh-aw/usage/agent/token_usage.jsonl
+ /tmp/gh-aw/usage/detection/token_usage.jsonl
+ if-no-files-found: ignore
+ - name: Process no-op messages
+ id: noop
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
+ GH_AW_NOOP_MAX: "1"
+ GH_AW_WORKFLOW_NAME: "自动处理 Issue"
+ GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/auto-code.md"
+ 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"
+ GH_AW_AIC: ${{ needs.agent.outputs.aic }}
+ GH_AW_AMBIENT_CONTEXT: ${{ needs.agent.outputs.ambient_context }}
+ GH_AW_WORKFLOW_ID: "auto-code"
+ 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: Record missing tool
+ id: missing_tool
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ 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: "自动处理 Issue"
+ GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/auto-code.md"
+ 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@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ 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: "自动处理 Issue"
+ GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/auto-code.md"
+ 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@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
+ GH_AW_WORKFLOW_NAME: "自动处理 Issue"
+ GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/auto-code.md"
+ 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: "auto-code"
+ GH_AW_ACTION_FAILURE_ISSUE_EXPIRES_HOURS: "168"
+ GH_AW_ENGINE_ID: "copilot"
+ GH_AW_CHECKOUT_PR_SUCCESS: ${{ needs.agent.outputs.checkout_pr_success }}
+ GH_AW_EFFECTIVE_TOKENS: ${{ needs.agent.outputs.effective_tokens || '' }}
+ GH_AW_AI_CREDITS_RATE_LIMIT_ERROR: ${{ needs.agent.outputs.ai_credits_rate_limit_error || 'false' }}
+ GH_AW_UNKNOWN_MODEL_AI_CREDITS: ${{ needs.agent.outputs.unknown_model_ai_credits || 'false' }}
+ GH_AW_AIC: ${{ needs.agent.outputs.aic }}
+ GH_AW_MAX_AI_CREDITS: ${{ vars.GH_AW_DEFAULT_MAX_AI_CREDITS || '1000' }}
+ 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_ENGINE_API_HOSTS: "api.enterprise.githubcopilot.com,api.githubcopilot.com,api.business.githubcopilot.com,api.individual.githubcopilot.com"
+ 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_DAILY_EFFECTIVE_WORKFLOW_EXCEEDED: ${{ needs.activation.outputs.daily_effective_workflow_exceeded }}
+ GH_AW_DAILY_EFFECTIVE_WORKFLOW_TOTAL_EFFECTIVE_TOKENS: ${{ needs.activation.outputs.daily_effective_workflow_total_effective_tokens }}
+ GH_AW_DAILY_EFFECTIVE_WORKFLOW_THRESHOLD: ${{ needs.activation.outputs.daily_effective_workflow_threshold }}
+ GH_AW_GROUP_REPORTS: "false"
+ GH_AW_FAILURE_REPORT_AS_ISSUE: "true"
+ GH_AW_MISSING_TOOL_REPORT_AS_FAILURE: "true"
+ GH_AW_MISSING_DATA_REPORT_AS_FAILURE: "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();
+
+ pre_activation:
+ runs-on: ubuntu-slim
+ outputs:
+ activated: ${{ steps.check_membership.outputs.is_team_member == 'true' }}
+ matched_command: ''
+ setup-parent-span-id: ${{ steps.setup.outputs.parent-span-id || steps.setup.outputs.span-id }}
+ setup-span-id: ${{ steps.setup.outputs.span-id }}
+ setup-trace-id: ${{ steps.setup.outputs.trace-id }}
+ steps:
+ - name: Setup Scripts
+ id: setup
+ uses: github/gh-aw-actions/setup@5c2fe865bb4dc46e1450f6ee0d0541d759aea73a # v0.79.6
+ with:
+ destination: ${{ runner.temp }}/gh-aw/actions
+ job-name: ${{ github.job }}
+ env:
+ GH_AW_SETUP_WORKFLOW_NAME: "自动处理 Issue"
+ GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/auto-code.lock.yml@${{ github.ref }}
+ GH_AW_INFO_VERSION: "1.0.60"
+ GH_AW_INFO_ENGINE_ID: "copilot"
+ - name: Check team membership for workflow
+ id: check_membership
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ 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
+ if: (!cancelled()) && needs.agent.result != 'skipped'
+ runs-on: ubuntu-slim
+ permissions:
+ contents: write
+ discussions: write
+ issues: write
+ pull-requests: write
+ timeout-minutes: 45
+ env:
+ GH_AW_AGENT_AIC: ${{ needs.agent.outputs.aic }}
+ GH_AW_AIC: ${{ needs.agent.outputs.aic }}
+ GH_AW_AMBIENT_CONTEXT: ${{ needs.agent.outputs.ambient_context }}
+ GH_AW_CALLER_WORKFLOW_ID: "${{ github.repository }}/auto-code"
+ GH_AW_EFFECTIVE_TOKENS: ${{ needs.agent.outputs.effective_tokens }}
+ GH_AW_ENGINE_ID: "copilot"
+ GH_AW_ENGINE_MODEL: ${{ needs.agent.outputs.model }}
+ GH_AW_ENGINE_VERSION: "1.0.60"
+ GH_AW_WORKFLOW_ID: "auto-code"
+ GH_AW_WORKFLOW_NAME: "自动处理 Issue"
+ GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/auto-code.md"
+ 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 }}
+ comment_id: ${{ steps.process_safe_outputs.outputs.comment_id }}
+ comment_url: ${{ steps.process_safe_outputs.outputs.comment_url }}
+ 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_pr_number: ${{ steps.process_safe_outputs.outputs.created_pr_number }}
+ created_pr_url: ${{ steps.process_safe_outputs.outputs.created_pr_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:
+ - name: Setup Scripts
+ id: setup
+ uses: github/gh-aw-actions/setup@5c2fe865bb4dc46e1450f6ee0d0541d759aea73a # v0.79.6
+ with:
+ destination: ${{ runner.temp }}/gh-aw/actions
+ job-name: ${{ github.job }}
+ trace-id: ${{ needs.activation.outputs.setup-trace-id }}
+ parent-span-id: ${{ needs.activation.outputs.setup-parent-span-id || needs.activation.outputs.setup-span-id }}
+ env:
+ GH_AW_SETUP_WORKFLOW_NAME: "自动处理 Issue"
+ GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/auto-code.lock.yml@${{ github.ref }}
+ GH_AW_INFO_VERSION: "1.0.60"
+ GH_AW_INFO_ENGINE_ID: "copilot"
+ - 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: Extract base branch from agent output
+ id: extract-base-branch
+ if: steps.download-agent-output.outcome == 'success'
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ 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/extract_base_branch_from_agent_output.cjs');
+ await main();
+ - name: Checkout repository (trusted default branch for comment events)
+ if: (!cancelled()) && needs.agent.result != 'skipped' && contains(needs.agent.outputs.output_types, 'create_pull_request') && (github.event_name == 'issue_comment' || github.event_name == 'pull_request_review_comment')
+ uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+ with:
+ ref: ${{ github.event.repository.default_branch }}
+ token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+ persist-credentials: false
+ fetch-depth: 1
+ - name: Checkout repository
+ if: (!cancelled()) && needs.agent.result != 'skipped' && contains(needs.agent.outputs.output_types, 'create_pull_request') && github.event_name != 'issue_comment' && github.event_name != 'pull_request_review_comment'
+ uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+ with:
+ ref: develop
+ token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+ persist-credentials: false
+ fetch-depth: 1
+ - name: Configure Git credentials
+ if: (!cancelled()) && needs.agent.result != 'skipped' && contains(needs.agent.outputs.output_types, 'create_pull_request')
+ env:
+ REPO_NAME: ${{ github.repository }}
+ SERVER_URL: ${{ github.server_url }}
+ GIT_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.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:${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
+ # zizmor: ignore[github-env] - GITHUB_SERVER_URL is set by GitHub Actions, not user input.
+ 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@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
+ GH_AW_COMMENT_ID: ${{ needs.activation.outputs.comment_id }}
+ 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,ark.cn-beijing.volces.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: "{\"add_comment\":{\"max\":1},\"create_pull_request\":{\"base_branch\":\"develop\",\"max\":1,\"max_patch_files\":100,\"max_patch_size\":1024,\"protect_top_level_dot_folders\":true,\"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\",\"DESIGN.md\",\"README.md\",\"CONTRIBUTING.md\",\"CHANGELOG.md\",\"SECURITY.md\",\"CODE_OF_CONDUCT.md\",\"AGENTS.md\",\"CLAUDE.md\",\"GEMINI.md\"],\"protected_files_policy\":\"allowed\"},\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"true\"},\"report_incomplete\":{}}"
+ GH_AW_CI_TRIGGER_TOKEN: ${{ secrets.GH_AW_CI_TRIGGER_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/auto-code.md b/.github/workflows/auto-code.md
new file mode 100644
index 0000000..f73bb47
--- /dev/null
+++ b/.github/workflows/auto-code.md
@@ -0,0 +1,123 @@
+---
+on:
+ issues:
+ types: [labeled]
+
+engine:
+ id: copilot
+ env:
+ COPILOT_PROVIDER_BASE_URL: "https://ark.cn-beijing.volces.com/api/v3"
+ COPILOT_PROVIDER_BEARER_TOKEN: ${{ secrets.OPENAI_API_KEY }}
+ COPILOT_MODEL: doubao-seed-evolving
+ COPILOT_PROVIDER_TYPE: openai
+ COPILOT_PROVIDER_WIRE_API: responses
+
+features:
+ dangerously-disable-sandbox-agent: "controlled environment for issue triage automation"
+sandbox:
+ agent: false
+strict: false
+
+network:
+ allowed:
+ - defaults
+ - ark.cn-beijing.volces.com
+
+tools:
+ github:
+ min-integrity: none
+
+permissions:
+ contents: read
+ issues: read
+ pull-requests: read
+ copilot-requests: write
+
+safe-outputs:
+ threat-detection: false
+ create-pull-request:
+ base-branch: develop
+ protected-files: allowed
+ add-comment:
+ max: 1
+---
+
+# 自动处理 Issue
+
+当 Issue 被打上 `bug` 或 `enhancement` 或 `feature` 标签时触发。其他标签直接退出,不做任何操作。
+
+## 判断任务类型
+
+读取 Issue #${{ github.event.issue.number }} 当前的标签:
+- 如果包含 `bug` 标签 → 执行【Bug 修复流程】
+- 如果包含 `feature` 标签 → 执行【新功能开发流程】
+- 如果包含 `enhancement` 标签 → 执行【功能改进开发流程】
+- 其他情况 → 直接退出
+
+## 任务执行限制
+- 根据需求查找相对应的可能关联的代码文件
+- 尽量只读取相关代码文件和文档,不去操作无关代码和文件
+- 尽量减少操作时间和步骤,减少TOKEN和时间消耗
+
+---
+
+
+## Bug 修复流程
+
+1. 阅读 Issue 的完整标题和正文,理解问题现象
+2. 浏览仓库相关代码和文档,定位问题所在的文件和函数
+3. 分析根本原因
+4. 实现修复方案,注意:
+ - 保持与现有代码风格一致
+ - 只修改必要的部分,不做无关改动
+5. 创建 Pull Request,标题格式:`fix: `,描述中说明:
+ - 问题根因
+ - 修复方式
+ - 如何验证
+6. 在原 Issue 下使用用户提问的语言进行回复,说明已提交 PR 及修复思路
+
+如果问题过于复杂或信息不足,在 Issue 下用中文说明原因,不创建 PR。
+
+---
+
+## 新功能开发流程
+
+1. 阅读 Issue 的完整标题和正文,理解需求目标
+2. 浏览仓库相关代码结构和文档,找到最相关的模块和文件
+3. 制定实现方案:
+ - 需要新增哪些文件或函数
+ - 需要修改哪些现有文件
+4. 按方案实现代码,注意:
+ - 保持与现有代码风格一致
+ - 新增函数/类需要添加注释
+ - 如果涉及接口变更,同步更新相关调用方
+5. 创建 Pull Request,标题格式:`feat: `,描述中说明:
+ - 实现了哪些功能
+ - 涉及哪些文件改动
+ - 如何验证/测试
+6. 在原 Issue 下使用用户提问的语言进行回复,说明已提交 PR、实现思路和测试建议
+
+如果需求描述不清晰或实现风险过大,在 Issue 下用中文说明原因,不创建 PR。
+
+---
+
+## 功能改进开发流程
+
+1. 阅读 Issue 的完整标题和正文,明确功能改进与优化的具体目标(如性能提升、代码结构重构、用户体验优化等)。
+2. 浏览仓库相关代码,评估受影响的范围,定位需要进行优化或重构的核心文件及函数。
+3. 制定改进方案,需特别注意:
+ - **向下兼容性**:确保本次改进不会破坏现有的公开接口(API)和已有功能。
+ - **防御性编程**:优化逻辑的同时,不能降低代码的健壮性。
+4. 按照方案实施代码改动,注意:
+ - 保持与现有代码风格高度一致。
+ - 仅针对性能、可读性或结构进行局部优化,严禁引入未经需求的无关大范围改动。
+5. 创建 Pull Request,根据改进的核心侧重点选择标题格式:
+ - 侧重于代码重构/可读性优化:`refactor: `
+ - 侧重于运行运行效率/性能优化:`perf: `
+ 在 PR 描述中说明:
+ - 优化的动机与改进点
+ - 改进前后的对比或预期收益
+ - 验证优化是否生效的测试方法
+6. 在原 Issue 下使用用户提问的语言进行回复,说明已提交 PR、优化思路及预期的提升效果。
+
+如果功能改进可能带来重大的破坏性变更(Breaking Changes)或者现有代码结构不支持盲目优化,在 Issue 下用中文说明原因,保持维持原状,不创建 PR。
\ No newline at end of file
diff --git a/.github/workflows/codeql-to-commit.yml b/.github/workflows/codeql-to-commit.yml
new file mode 100644
index 0000000..98ab97f
--- /dev/null
+++ b/.github/workflows/codeql-to-commit.yml
@@ -0,0 +1,194 @@
+name: Auto Copilot Autofix (High & Medium Only)
+
+on:
+ workflow_dispatch:
+ workflow_run:
+ workflows: ["CodeQL Advanced"]
+ types: [completed]
+
+jobs:
+ auto-fix:
+ runs-on: ubuntu-latest
+ if: ${{ github.event_name == 'workflow_dispatch' || github.event.workflow_run.conclusion == 'success' }}
+ permissions:
+ security-events: read
+ contents: write
+ pull-requests: write
+
+ steps:
+ - name: Trigger Autofix for High & Medium alerts
+ env:
+ GH_TOKEN: ${{ secrets.AUTOFIX_TOKEN }}
+ OWNER: ${{ github.repository_owner }}
+ REPO: ${{ github.event.repository.name }}
+ run: |
+ set +e
+ DEFAULT_BRANCH=$(gh api /repos/$OWNER/$REPO --jq '.default_branch')
+ echo "Default branch: $DEFAULT_BRANCH"
+
+ ALERTS=$(gh api "/repos/$OWNER/$REPO/code-scanning/alerts?state=open&per_page=100" \
+ --jq '[.[] | select(.rule.security_severity_level == "critical" or .rule.security_severity_level == "high" or .rule.security_severity_level == "medium" or .rule.severity == "warning") | {number: .number, level: (.rule.security_severity_level // .rule.severity)}]')
+
+ COUNT=$(echo $ALERTS | jq 'length')
+ echo "Found $COUNT alerts with high / medium / warning"
+ echo "$ALERTS" | jq -r '.[] | " Alert #\(.number) [\(.level)]"'
+
+ if [ "$COUNT" -eq 0 ]; then
+ echo "No alerts to process, exiting."
+ exit 0
+ fi
+
+ for ROW in $(echo $ALERTS | jq -r '.[] | @base64'); do
+ _jq() { echo "$ROW" | base64 -d | jq -r "$1"; }
+
+ NUMBER=$(_jq '.number')
+ SEC_LEVEL=$(_jq '.level')
+ BRANCH="autofix/${SEC_LEVEL}/alert-${NUMBER}"
+
+ echo "--- Alert #$NUMBER [$SEC_LEVEL] ---"
+
+ # 检查是否已有 autofix
+ EXISTING=$(gh api \
+ /repos/$OWNER/$REPO/code-scanning/alerts/$NUMBER/autofix \
+ --jq '.status' 2>/dev/null || echo "none")
+
+ if [ "$EXISTING" = "success" ]; then
+ echo "✅ Fix already exists"
+ else
+ echo "⏳ Generating fix..."
+ gh api -X POST \
+ /repos/$OWNER/$REPO/code-scanning/alerts/$NUMBER/autofix || {
+ echo "⚠️ Failed to trigger autofix for #$NUMBER, skipping"
+ continue
+ }
+
+ for i in 1 2 3; do
+ sleep 30
+ EXISTING=$(gh api \
+ /repos/$OWNER/$REPO/code-scanning/alerts/$NUMBER/autofix \
+ --jq '.status' 2>/dev/null || echo "none")
+ echo " Attempt $i: status = $EXISTING"
+ [ "$EXISTING" = "success" ] && break
+ done
+ fi
+
+ if [ "$EXISTING" != "success" ]; then
+ echo "⚠️ Autofix not available for alert #$NUMBER (status: $EXISTING), skipping"
+ continue
+ fi
+
+ # 检查分支是否已存在
+ BRANCH_STATUS=$(gh api \
+ /repos/$OWNER/$REPO/git/refs/heads/$BRANCH \
+ --silent 2>/dev/null && echo "exists" || echo "not_found")
+ echo "DEBUG branch status: $BRANCH_STATUS"
+
+ if [ "$BRANCH_STATUS" = "not_found" ]; then
+ # 创建分支
+ SHA=$(gh api /repos/$OWNER/$REPO/git/refs/heads/$DEFAULT_BRANCH \
+ --jq '.object.sha')
+
+ gh api -X POST /repos/$OWNER/$REPO/git/refs \
+ -f ref="refs/heads/$BRANCH" \
+ -f sha="$SHA" 2>/dev/null || true
+ echo "🌿 Created branch: $BRANCH"
+
+ # 提交 fix
+ COMMIT_RESULT=$(gh api -X POST \
+ /repos/$OWNER/$REPO/code-scanning/alerts/$NUMBER/autofix/commits \
+ -f target_ref="$BRANCH" 2>&1)
+ echo "DEBUG commit result: $COMMIT_RESULT"
+
+ if echo "$COMMIT_RESULT" | grep -q "target_ref"; then
+ echo "✅ Committed fix to branch: $BRANCH"
+ else
+ echo "⚠️ No code changes generated, deleting branch and skipping"
+ gh api -X DELETE \
+ /repos/$OWNER/$REPO/git/refs/heads/$BRANCH 2>/dev/null || true
+ continue
+ fi
+ else
+ # 分支已存在,检查是否已有 open PR
+ EXISTING_PR=$(gh pr list \
+ --repo "$OWNER/$REPO" \
+ --head "$BRANCH" \
+ --state open \
+ --json number \
+ --jq '.[0].number // empty')
+
+ if [ -n "$EXISTING_PR" ]; then
+ echo "⏭️ PR #$EXISTING_PR already exists, skipping"
+ continue
+ fi
+
+ echo "🌿 Branch exists, creating PR with existing branch"
+ fi
+
+ # 获取 alert 详情
+ ALERT_INFO=$(gh api \
+ /repos/$OWNER/$REPO/code-scanning/alerts/$NUMBER)
+
+ ALERT_TITLE=$(echo $ALERT_INFO | jq -r '.rule.description')
+ ALERT_HELP=$(echo $ALERT_INFO | jq -r '.rule.help // "暂无详细说明"' | head -c 800)
+ ALERT_TAGS=$(echo $ALERT_INFO | jq -r '.rule.tags // [] | join(", ")')
+ ALERT_FILE=$(echo $ALERT_INFO | jq -r '.most_recent_instance.location.path // "未知文件"')
+ ALERT_LINE=$(echo $ALERT_INFO | jq -r '.most_recent_instance.location.start_line // "未知行"')
+ ALERT_URL=$(echo $ALERT_INFO | jq -r '.html_url')
+ CWE_TAGS=$(echo $ALERT_INFO | jq -r '[.rule.tags[] | select(startswith("external/cwe/"))] | join(", ")')
+
+ AUTOFIX_DESC=$(gh api \
+ /repos/$OWNER/$REPO/code-scanning/alerts/$NUMBER/autofix \
+ --jq '.description // "暂无 AI 修复说明"')
+
+ # 创建 Draft PR
+ gh pr create \
+ --repo "$OWNER/$REPO" \
+ --base "$DEFAULT_BRANCH" \
+ --head "$BRANCH" \
+ --draft \
+ --title "[Autofix][$SEC_LEVEL] Alert #$NUMBER: $ALERT_TITLE" \
+ --body "## 🤖 Copilot Autofix 自动修复报告
+
+ ---
+
+ ### 📋 基本信息
+
+ | 字段 | 内容 |
+ |------|------|
+ | **Alert ID** | [#$NUMBER]($ALERT_URL) |
+ | **安全级别** | $SEC_LEVEL |
+ | **规则名称** | $ALERT_TITLE |
+ | **问题文件** | \`$ALERT_FILE\` 第 $ALERT_LINE 行 |
+ | **CWE 分类** | $CWE_TAGS |
+ | **规则标签** | $ALERT_TAGS |
+
+ ---
+
+ ### 🔍 问题说明
+
+ $ALERT_HELP
+
+ ---
+
+ ### 🤖 AI 修复思路
+
+ $AUTOFIX_DESC
+
+ ---
+
+ ### ✅ Review 检查清单
+
+ - [ ] 理解了漏洞的成因和影响范围
+ - [ ] 确认 AI 修复逻辑正确,没有遗漏边界情况
+ - [ ] 确认修复没有改变原有业务逻辑
+ - [ ] 确认没有引入新的安全问题
+ - [ ] CI / 单元测试全部通过
+ - [ ] 如有必要,已补充对应的测试用例
+
+ ---
+
+ > 此 PR 由 GitHub Copilot Autofix 自动生成,请仔细审核后再 merge。" && \
+ echo "🎉 PR created for alert #$NUMBER" || \
+ echo "❌ Failed to create PR for alert #$NUMBER"
+
+ done
diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml
index 30a3ccf..98088d5 100644
--- a/.github/workflows/codeql.yml
+++ b/.github/workflows/codeql.yml
@@ -11,7 +11,7 @@ on:
jobs:
analyze:
- runs-on: ubuntu-24.04
+ runs-on: ubuntu-latest
permissions:
security-events: write
packages: read
@@ -23,14 +23,13 @@ jobs:
matrix:
include:
- language: c-cpp
+ build-mode: manual
steps:
- name: Checkout repository
- uses: actions/checkout@v4
- with:
- ref: 'develop'
+ uses: actions/checkout@v6
- name: Checkout dependency repository (xengine)
- uses: actions/checkout@v4
+ uses: actions/checkout@v6
with:
repository: libxengine/libxengine
path: libxengine
@@ -42,24 +41,31 @@ jobs:
- name: Set TERM variable
run: echo "TERM=xterm" >> $GITHUB_ENV
-
+
- name: Set up Dependency Environment
run: |
cd libxengine
chmod +x ./XEngine_LINEnv.sh
sudo ./XEngine_LINEnv.sh -i 3
+ - name: make pre
+ run: |
+ cd XEngine_Source
+ make BUILDTYPE=1
+
- name: Initialize CodeQL
- uses: github/codeql-action/init@v3
+ uses: github/codeql-action/init@v4
with:
languages: ${{ matrix.language }}
+ build-mode: manual
+ queries: security-and-quality
- - name: make
+ - name: make check
run: |
cd XEngine_Source
- make
+ make BUILDTYPE=2
- name: Perform CodeQL Analysis
- uses: github/codeql-action/analyze@v3
+ uses: github/codeql-action/analyze@v4
with:
category: "/language:${{ matrix.language }}"
diff --git a/.github/workflows/cppcheck.yml b/.github/workflows/cppcheck.yml
deleted file mode 100644
index 279b03f..0000000
--- a/.github/workflows/cppcheck.yml
+++ /dev/null
@@ -1,35 +0,0 @@
-name: cpp check workflows
-
-on:
- push:
- branches:
- - 'develop'
- paths:
- - 'XEngine_Source/**'
- - 'XEngine_Release/**'
- - '.github/**'
-
-jobs:
- build:
- runs-on: ubuntu-latest
-
- steps:
- - name: Checkout main repository code
- uses: actions/checkout@v4
- with:
- ref: 'develop'
-
- - name: Create static_analysis directory
- run: mkdir -p static_analysis
-
- - name: Run Cppcheck
- run: |
- sudo apt-get install -y cppcheck
- cppcheck --enable=all --language=c++ --std=c++20 ./XEngine_Source/ --output-file=static_analysis/log.xml --xml
- continue-on-error: true
-
- - name: Upload Cppcheck Results
- uses: actions/upload-artifact@v4
- with:
- name: cppcheck_results
- path: static_analysis/log.xml
\ No newline at end of file
diff --git a/.github/workflows/debian_build.yml b/.github/workflows/debian_build.yml
index 70a6da1..10bed10 100644
--- a/.github/workflows/debian_build.yml
+++ b/.github/workflows/debian_build.yml
@@ -36,16 +36,16 @@ jobs:
steps:
- name: Checkout main repository code
- uses: actions/checkout@v4
+ uses: actions/checkout@v6
- name: Checkout dependency repository (xengine)
- uses: actions/checkout@v4
+ uses: actions/checkout@v6
with:
repository: libxengine/libxengine
path: libxengine
- name: sub module checkout (opensource)
- uses: actions/checkout@v4
+ uses: actions/checkout@v6
with:
repository: libxengine/XEngine_OPenSource
path: XEngine_Source/XEngine_DependLibrary
@@ -81,7 +81,7 @@ jobs:
./XEngine_MQServiceApp -t
- name: Upload folder as artifact
- uses: actions/upload-artifact@v4
+ uses: actions/upload-artifact@v7
with:
name: XEngine_MQServiceApp-Debian_${{ matrix.version }}_x86-64
path: XEngine_Release/
diff --git a/.github/workflows/fedora_build.yml b/.github/workflows/fedora_build.yml
index 2c2f61c..9510f44 100644
--- a/.github/workflows/fedora_build.yml
+++ b/.github/workflows/fedora_build.yml
@@ -21,6 +21,11 @@ jobs:
strategy:
matrix:
include:
+ - arch: amd64
+ runner: ubuntu-24.04
+ platform: linux/amd64
+ fedora-version: 43
+ artifact: x86-64
- arch: amd64
runner: ubuntu-24.04
platform: linux/amd64
@@ -34,16 +39,16 @@ jobs:
steps:
- name: Checkout main repository code
- uses: actions/checkout@v4
+ uses: actions/checkout@v6
- name: Checkout dependency repository (xengine)
- uses: actions/checkout@v4
+ uses: actions/checkout@v6
with:
repository: libxengine/libxengine
path: libxengine
- name: sub module checkout (opensource)
- uses: actions/checkout@v4
+ uses: actions/checkout@v6
with:
repository: libxengine/XEngine_OPenSource
path: XEngine_Source/XEngine_DependLibrary
@@ -82,7 +87,7 @@ jobs:
./XEngine_MQServiceApp -t
- name: Upload folder as artifact
- uses: actions/upload-artifact@v4
+ uses: actions/upload-artifact@v7
with:
name: XEngine_MQServiceApp-Fedora_${{ matrix.fedora-version }}_${{ matrix.artifact }}
path: XEngine_Release/
diff --git a/.github/workflows/issue-translator.yml b/.github/workflows/issue-translator.yml
deleted file mode 100644
index d9fdac8..0000000
--- a/.github/workflows/issue-translator.yml
+++ /dev/null
@@ -1,15 +0,0 @@
-name: Issue Translator
-on:
- issue_comment:
- types: [created]
- issues:
- types: [opened]
-
-jobs:
- build:
- runs-on: ubuntu-latest
- steps:
- - uses: usthe/issues-translate-action@v2.7
- with:
- IS_MODIFY_TITLE: false
- CUSTOM_BOT_NOTE: Bot detected the issue body's language is not English, translate it automatically.
\ No newline at end of file
diff --git a/.github/workflows/issue-triage.lock.yml b/.github/workflows/issue-triage.lock.yml
new file mode 100644
index 0000000..c4c7adb
--- /dev/null
+++ b/.github/workflows/issue-triage.lock.yml
@@ -0,0 +1,1223 @@
+# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"01651461ea771a40a1d9a25bbf950f25e913d6b556796467343b77b45eabdd15","body_hash":"b17fdb8754e311cfac38664fbaa575804386c0027689ce0def213670917f77f0","compiler_version":"v0.79.6","agent_id":"copilot","engine_versions":{"copilot":"1.0.60"}}
+# gh-aw-manifest: {"version":1,"secrets":["GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN","OPENAI_API_KEY"],"actions":[{"repo":"actions/checkout","sha":"df4cb1c069e1874edd31b4311f1884172cec0e10","version":"v6.0.3"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"5c2fe865bb4dc46e1450f6ee0d0541d759aea73a","version":"v0.79.6"}],"containers":[{"image":"ghcr.io/github/github-mcp-server:v1.1.2","digest":"sha256:30197479d8036c7811892bc07e06f9a05c9ef3cdd79bc59f256d50647f95788c","pinned_image":"ghcr.io/github/github-mcp-server:v1.1.2@sha256:30197479d8036c7811892bc07e06f9a05c9ef3cdd79bc59f256d50647f95788c"}]}
+# ___ _ _
+# / _ \ | | (_)
+# | |_| | __ _ ___ _ __ | |_ _ ___
+# | _ |/ _` |/ _ \ '_ \| __| |/ __|
+# | | | | (_| | __/ | | | |_| | (__
+# \_| |_/\__, |\___|_| |_|\__|_|\___|
+# __/ |
+# _ _ |___/
+# | | | | / _| |
+# | | | | ___ _ __ _ __| |_| | _____ ____
+# | |/\| |/ _ \ '__| |/ /| _| |/ _ \ \ /\ / / ___|
+# \ /\ / (_) | | | | ( | | | | (_) \ V V /\__ \
+# \/ \/ \___/|_| |_|\_\|_| |_|\___/ \_/\_/ |___/
+#
+# This file was automatically generated by gh-aw (v0.79.6). 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/
+#
+#
+# Secrets used:
+# - GH_AW_GITHUB_MCP_SERVER_TOKEN
+# - GH_AW_GITHUB_TOKEN
+# - GITHUB_TOKEN
+# - OPENAI_API_KEY
+#
+# Custom actions used:
+# - actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+# - actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
+# - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+# - actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
+# - github/gh-aw-actions/setup@5c2fe865bb4dc46e1450f6ee0d0541d759aea73a # v0.79.6
+#
+# Container images used:
+# - ghcr.io/github/github-mcp-server:v1.1.2@sha256:30197479d8036c7811892bc07e06f9a05c9ef3cdd79bc59f256d50647f95788c
+
+name: "Issue 自动分类与回复"
+on:
+ issues:
+ types:
+ - opened
+ - reopened
+
+permissions: {}
+
+concurrency:
+ group: "gh-aw-${{ github.workflow }}-${{ github.event.issue.number || github.run_id }}"
+
+run-name: "Issue 自动分类与回复"
+
+jobs:
+ activation:
+ needs: pre_activation
+ if: needs.pre_activation.outputs.activated == 'true'
+ runs-on: ubuntu-slim
+ permissions:
+ actions: read
+ contents: read
+ env:
+ GH_AW_MAX_DAILY_AI_CREDITS: ${{ vars.GH_AW_DEFAULT_MAX_DAILY_AI_CREDITS || '5000' }}
+ outputs:
+ body: ${{ steps.sanitized.outputs.body }}
+ comment_id: ""
+ comment_repo: ""
+ daily_effective_workflow_exceeded: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_effective_workflow_exceeded == 'true' }}
+ daily_effective_workflow_threshold: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_effective_workflow_threshold || '' }}
+ daily_effective_workflow_total_effective_tokens: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_effective_workflow_total_effective_tokens || '' }}
+ engine_id: ${{ steps.generate_aw_info.outputs.engine_id }}
+ lockdown_check_failed: ${{ steps.generate_aw_info.outputs.lockdown_check_failed == 'true' }}
+ model: ${{ steps.generate_aw_info.outputs.model }}
+ setup-parent-span-id: ${{ steps.setup.outputs.parent-span-id || steps.setup.outputs.span-id }}
+ setup-span-id: ${{ steps.setup.outputs.span-id }}
+ setup-trace-id: ${{ steps.setup.outputs.trace-id }}
+ stale_lock_file_failed: ${{ steps.check-lock-file.outputs.stale_lock_file_failed == 'true' }}
+ text: ${{ steps.sanitized.outputs.text }}
+ title: ${{ steps.sanitized.outputs.title }}
+ steps:
+ - name: Setup Scripts
+ id: setup
+ uses: github/gh-aw-actions/setup@5c2fe865bb4dc46e1450f6ee0d0541d759aea73a # v0.79.6
+ with:
+ destination: ${{ runner.temp }}/gh-aw/actions
+ job-name: ${{ github.job }}
+ trace-id: ${{ needs.pre_activation.outputs.setup-trace-id }}
+ parent-span-id: ${{ needs.pre_activation.outputs.setup-parent-span-id || needs.pre_activation.outputs.setup-span-id }}
+ safe-output-artifact-client: ${{ env.GH_AW_MAX_DAILY_AI_CREDITS != '' }}
+ env:
+ GH_AW_SETUP_WORKFLOW_NAME: "Issue 自动分类与回复"
+ GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/issue-triage.lock.yml@${{ github.ref }}
+ GH_AW_INFO_VERSION: "1.0.60"
+ GH_AW_INFO_ENGINE_ID: "copilot"
+ - 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 || vars.GH_AW_DEFAULT_MODEL_COPILOT || 'claude-sonnet-4.6' }}
+ GH_AW_INFO_VERSION: "1.0.60"
+ GH_AW_INFO_AGENT_VERSION: "1.0.60"
+ GH_AW_INFO_CLI_VERSION: "v0.79.6"
+ GH_AW_INFO_WORKFLOW_NAME: "Issue 自动分类与回复"
+ GH_AW_INFO_EXPERIMENTAL: "false"
+ GH_AW_INFO_SUPPORTS_TOOLS_ALLOWLIST: "true"
+ GH_AW_INFO_STAGED: "false"
+ GH_AW_INFO_ALLOWED_DOMAINS: '["defaults","ark.cn-beijing.volces.com"]'
+ GH_AW_INFO_FIREWALL_ENABLED: "false"
+ GH_AW_INFO_AWF_VERSION: ""
+ GH_AW_INFO_AWMG_VERSION: ""
+ GH_AW_INFO_FIREWALL_TYPE: ""
+ GH_AW_COMPILED_STRICT: "false"
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ 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: Check daily workflow token guardrail
+ id: daily-effective-workflow-guardrail
+ if: ${{ env.GH_AW_MAX_DAILY_AI_CREDITS != '' }}
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_WORKFLOW_NAME: "Issue 自动分类与回复"
+ GH_AW_WORKFLOW_ID: "issue-triage"
+ GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
+ GH_AW_WORKFLOW_DISPATCH_AW_CONTEXT: ${{ github.event.inputs.aw_context || '' }}
+ GH_AW_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ GH_AW_MAX_DAILY_AI_CREDITS: ${{ vars.GH_AW_DEFAULT_MAX_DAILY_AI_CREDITS || '5000' }}
+ 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_daily_aic_workflow_guardrail.cjs');
+ await main();
+ - name: Checkout .github and .agents folders
+ uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+ with:
+ persist-credentials: false
+ sparse-checkout: |
+ .github
+ .agents
+ .antigravity
+ .claude
+ .codex
+ .crush
+ .gemini
+ .opencode
+ .pi
+ sparse-checkout-cone-mode: true
+ fetch-depth: 1
+ - name: Save agent config folders for base branch restoration
+ env:
+ GH_AW_AGENT_FOLDERS: ".agents .antigravity .claude .codex .crush .gemini .github .opencode .pi"
+ GH_AW_AGENT_FILES: ".crush.json AGENTS.md ANTIGRAVITY.md CLAUDE.md GEMINI.md PI.md opencode.jsonc"
+ # poutine:ignore untrusted_checkout_exec
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/save_base_github_folders.sh"
+ - name: Check workflow lock file
+ id: check-lock-file
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_WORKFLOW_FILE: "issue-triage.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@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_COMPILED_VERSION: "v0.79.6"
+ 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: Compute current body text
+ id: sanitized
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ 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,ark.cn-beijing.volces.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"
+ 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/compute_text.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_EXPR_1A3A194A: ${{ github.event.discussion.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'discussion' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }}
+ GH_AW_EXPR_463A214A: ${{ github.event.pull_request.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'pull_request' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }}
+ GH_AW_EXPR_802A9F6A: ${{ github.event.issue.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'issue' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }}
+ GH_AW_EXPR_FF1D34CE: ${{ github.event.comment.id || fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').comment_id }}
+ GH_AW_GITHUB_ACTOR: ${{ github.actor }}
+ 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_72243dd344875363_EOF'
+
+ GH_AW_PROMPT_72243dd344875363_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_72243dd344875363_EOF'
+
+ Tools: add_comment, add_labels, missing_tool, missing_data, noop
+
+ GH_AW_PROMPT_72243dd344875363_EOF
+ cat "${RUNNER_TEMP}/gh-aw/prompts/mcp_cli_tools_prompt.md"
+ cat << 'GH_AW_PROMPT_72243dd344875363_EOF'
+
+ The following GitHub context information is available for this workflow:
+ {{#if github.actor}}
+ - **actor**: __GH_AW_GITHUB_ACTOR__
+ {{/if}}
+ {{#if github.repository}}
+ - **repository**: __GH_AW_GITHUB_REPOSITORY__
+ {{/if}}
+ {{#if github.workspace}}
+ - **workspace**: __GH_AW_GITHUB_WORKSPACE__
+ {{/if}}
+ {{#if github.event.issue.number || (github.aw.context.item_type == 'issue' && github.aw.context.item_number)}}
+ - **issue-number**: #__GH_AW_EXPR_802A9F6A__
+ {{/if}}
+ {{#if github.event.discussion.number || (github.aw.context.item_type == 'discussion' && github.aw.context.item_number)}}
+ - **discussion-number**: #__GH_AW_EXPR_1A3A194A__
+ {{/if}}
+ {{#if github.event.pull_request.number || (github.aw.context.item_type == 'pull_request' && github.aw.context.item_number)}}
+ - **pull-request-number**: #__GH_AW_EXPR_463A214A__
+ {{/if}}
+ {{#if github.event.comment.id || github.aw.context.comment_id}}
+ - **comment-id**: __GH_AW_EXPR_FF1D34CE__
+ {{/if}}
+ {{#if github.run_id}}
+ - **workflow-run-id**: __GH_AW_GITHUB_RUN_ID__
+ {{/if}}
+
+
+ GH_AW_PROMPT_72243dd344875363_EOF
+ cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md"
+ cat << 'GH_AW_PROMPT_72243dd344875363_EOF'
+
+ {{#runtime-import .github/workflows/issue-triage.md}}
+ GH_AW_PROMPT_72243dd344875363_EOF
+ } > "$GH_AW_PROMPT"
+ - name: Interpolate variables and render templates
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
+ GH_AW_ENGINE_ID: "copilot"
+ GH_AW_GITHUB_REPOSITORY: ${{ github.repository }}
+ 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@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
+ GH_AW_EXPR_1A3A194A: ${{ github.event.discussion.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'discussion' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }}
+ GH_AW_EXPR_463A214A: ${{ github.event.pull_request.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'pull_request' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }}
+ GH_AW_EXPR_802A9F6A: ${{ github.event.issue.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'issue' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }}
+ GH_AW_EXPR_FF1D34CE: ${{ github.event.comment.id || fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').comment_id }}
+ GH_AW_GITHUB_ACTOR: ${{ github.actor }}
+ GH_AW_GITHUB_REPOSITORY: ${{ github.repository }}
+ GH_AW_GITHUB_RUN_ID: ${{ github.run_id }}
+ GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }}
+ GH_AW_MCP_CLI_SERVERS_LIST: '- `safeoutputs` — run `safeoutputs --help` to see available tools'
+ 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_EXPR_1A3A194A: process.env.GH_AW_EXPR_1A3A194A,
+ GH_AW_EXPR_463A214A: process.env.GH_AW_EXPR_463A214A,
+ GH_AW_EXPR_802A9F6A: process.env.GH_AW_EXPR_802A9F6A,
+ GH_AW_EXPR_FF1D34CE: process.env.GH_AW_EXPR_FF1D34CE,
+ GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR,
+ 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_MCP_CLI_SERVERS_LIST: process.env.GH_AW_MCP_CLI_SERVERS_LIST,
+ 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
+ include-hidden-files: true
+ path: |
+ /tmp/gh-aw/aw_info.json
+ /tmp/gh-aw/model_multipliers.json
+ /tmp/gh-aw/models.json
+ /tmp/gh-aw/aw-prompts/prompt.txt
+ /tmp/gh-aw/aw-prompts/prompt-template.txt
+ /tmp/gh-aw/aw-prompts/prompt-import-tree.json
+ /tmp/gh-aw/github_rate_limits.jsonl
+ /tmp/gh-aw/base
+ /tmp/gh-aw/.github/agents
+ /tmp/gh-aw/.github/skills
+ if-no-files-found: ignore
+ retention-days: 1
+
+ agent:
+ needs: activation
+ if: needs.activation.outputs.daily_effective_workflow_exceeded != 'true'
+ runs-on: ubuntu-latest
+ permissions:
+ contents: read
+ copilot-requests: write
+ issues: read
+ pull-requests: read
+ 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: issuetriage
+ outputs:
+ agentic_engine_timeout: ${{ steps.detect-agent-errors.outputs.agentic_engine_timeout || 'false' }}
+ ai_credits_rate_limit_error: ${{ steps.parse-mcp-gateway.outputs.ai_credits_rate_limit_error || 'false' }}
+ aic: ${{ steps.parse-mcp-gateway.outputs.aic }}
+ ambient_context: ${{ steps.parse-mcp-gateway.outputs.ambient_context }}
+ 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-agent-errors.outputs.inference_access_error || 'false' }}
+ mcp_policy_error: ${{ steps.detect-agent-errors.outputs.mcp_policy_error || 'false' }}
+ model: ${{ needs.activation.outputs.model }}
+ model_not_supported_error: ${{ steps.detect-agent-errors.outputs.model_not_supported_error || 'false' }}
+ output: ${{ steps.collect_output.outputs.output }}
+ output_types: ${{ steps.collect_output.outputs.output_types }}
+ setup-parent-span-id: ${{ steps.setup.outputs.parent-span-id || steps.setup.outputs.span-id }}
+ setup-span-id: ${{ steps.setup.outputs.span-id }}
+ setup-trace-id: ${{ steps.setup.outputs.trace-id }}
+ unknown_model_ai_credits: ${{ steps.parse-mcp-gateway.outputs.unknown_model_ai_credits || 'false' }}
+ steps:
+ - name: Setup Scripts
+ id: setup
+ uses: github/gh-aw-actions/setup@5c2fe865bb4dc46e1450f6ee0d0541d759aea73a # v0.79.6
+ with:
+ destination: ${{ runner.temp }}/gh-aw/actions
+ job-name: ${{ github.job }}
+ trace-id: ${{ needs.activation.outputs.setup-trace-id }}
+ parent-span-id: ${{ needs.activation.outputs.setup-parent-span-id || needs.activation.outputs.setup-span-id }}
+ env:
+ GH_AW_SETUP_WORKFLOW_NAME: "Issue 自动分类与回复"
+ GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/issue-triage.lock.yml@${{ github.ref }}
+ GH_AW_INFO_VERSION: "1.0.60"
+ GH_AW_INFO_ENGINE_ID: "copilot"
+ - 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@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+ with:
+ persist-credentials: false
+ - 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 || github.event_name == 'workflow_dispatch' && fromJSON(github.event.inputs.aw_context || '{}').item_type == 'pull_request'
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ 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.60
+ env:
+ GH_HOST: github.com
+ - name: Parse integrity filter lists
+ id: parse-guard-vars
+ env:
+ GH_AW_BLOCKED_USERS_VAR: ${{ vars.GH_AW_GITHUB_BLOCKED_USERS || '' }}
+ GH_AW_TRUSTED_USERS_VAR: ${{ vars.GH_AW_GITHUB_TRUSTED_USERS || '' }}
+ GH_AW_APPROVAL_LABELS_VAR: ${{ vars.GH_AW_GITHUB_APPROVAL_LABELS || '' }}
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/parse_guard_list.sh"
+ - name: Download activation artifact
+ uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
+ with:
+ name: activation
+ path: /tmp/gh-aw
+ - name: Restore agent config folders from base branch
+ if: steps.checkout-pr.outcome == 'success'
+ env:
+ GH_AW_AGENT_FOLDERS: ".agents .antigravity .claude .codex .crush .gemini .github .opencode .pi"
+ GH_AW_AGENT_FILES: ".crush.json AGENTS.md ANTIGRAVITY.md CLAUDE.md GEMINI.md PI.md opencode.jsonc"
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_base_github_folders.sh"
+ - name: Restore inline sub-agents from activation artifact
+ env:
+ GH_AW_SUB_AGENT_DIR: ".github/agents"
+ GH_AW_SUB_AGENT_EXT: ".agent.md"
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_inline_sub_agents.sh"
+ - name: Restore inline skills from activation artifact
+ env:
+ GH_AW_SKILL_DIR: ".github/skills"
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_inline_skills.sh"
+ - name: Download container images
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/github-mcp-server:v1.1.2@sha256:30197479d8036c7811892bc07e06f9a05c9ef3cdd79bc59f256d50647f95788c
+ - name: Generate Safe Outputs Config
+ 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_33a8e71ee9b45c67_EOF'
+ {"add_comment":{"max":1},"add_labels":{"allowed":["bug","feature","enhancement","documentation","question","duplicate","invalid"]},"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"report_incomplete":{}}
+ GH_AW_SAFE_OUTPUTS_CONFIG_33a8e71ee9b45c67_EOF
+ - name: Generate Safe Outputs Tools
+ env:
+ GH_AW_TOOLS_META_JSON: |
+ {
+ "description_suffixes": {
+ "add_comment": " CONSTRAINTS: Maximum 1 comment(s) can be added. Supports reply_to_id for discussion threading.",
+ "add_labels": " CONSTRAINTS: Only these labels are allowed: [\"bug\" \"feature\" \"enhancement\" \"documentation\" \"question\" \"duplicate\" \"invalid\"]."
+ },
+ "repo_params": {},
+ "dynamic_tools": []
+ }
+ GH_AW_VALIDATION_JSON: |
+ {
+ "add_comment": {
+ "defaultMax": 1,
+ "fields": {
+ "body": {
+ "required": true,
+ "type": "string",
+ "sanitize": true,
+ "maxLength": 65000
+ },
+ "item_number": {
+ "issueOrPRNumber": true
+ },
+ "reply_to_id": {
+ "type": "string",
+ "maxLength": 256
+ },
+ "repo": {
+ "type": "string",
+ "maxLength": 256
+ }
+ }
+ },
+ "add_labels": {
+ "defaultMax": 5,
+ "fields": {
+ "item_number": {
+ "issueNumberOrTemporaryId": true
+ },
+ "labels": {
+ "required": true,
+ "type": "array",
+ "itemType": "string",
+ "itemSanitize": true,
+ "itemMaxLength": 128
+ },
+ "repo": {
+ "type": "string",
+ "maxLength": 256
+ }
+ }
+ },
+ "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
+ }
+ }
+ },
+ "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@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ 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_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+ 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="localhost"
+ export MCP_GATEWAY_HOST_DOMAIN="localhost"
+ 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"
+ MCP_GATEWAY_UID=$(id -u 2>/dev/null || echo '0')
+ MCP_GATEWAY_GID=$(id -g 2>/dev/null || echo '0')
+ case "${DOCKER_HOST:-}" in
+ unix://* ) DOCKER_SOCK_PATH="${DOCKER_HOST#unix://}" ;;
+ /* ) DOCKER_SOCK_PATH="$DOCKER_HOST" ;;
+ * ) DOCKER_SOCK_PATH=/var/run/docker.sock ;;
+ esac
+ DOCKER_SOCK_GID=$(stat -c '%g' "$DOCKER_SOCK_PATH" 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 '"${DOCKER_SOCK_PATH}"':/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 DOCKER_HOST=unix:///var/run/docker.sock -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.25'
+
+ 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_f41962abaffbda74_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs"
+ {
+ "mcpServers": {
+ "github": {
+ "type": "stdio",
+ "container": "ghcr.io/github/github-mcp-server:v1.1.2",
+ "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": {
+ "approval-labels": ${{ steps.parse-guard-vars.outputs.approval_labels }},
+ "blocked-users": ${{ steps.parse-guard-vars.outputs.blocked_users }},
+ "min-integrity": "none",
+ "repos": "all",
+ "trusted-users": ${{ steps.parse-guard-vars.outputs.trusted_users }}
+ }
+ }
+ },
+ "safeoutputs": {
+ "type": "http",
+ "url": "http://localhost:$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_f41962abaffbda74_EOF
+ - name: Mount MCP servers as CLIs
+ id: mount-mcp-clis
+ continue-on-error: true
+ env:
+ MCP_GATEWAY_API_KEY: ${{ steps.start-mcp-gateway.outputs.gateway-api-key }}
+ MCP_GATEWAY_DOMAIN: ${{ steps.start-mcp-gateway.outputs.gateway-domain }}
+ MCP_GATEWAY_PORT: ${{ steps.start-mcp-gateway.outputs.gateway-port }}
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ with:
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/mount_mcp_as_cli.cjs');
+ await main();
+ - name: Clean credentials
+ continue-on-error: true
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/clean_git_credentials.sh"
+ - name: Audit pre-agent workspace
+ id: pre_agent_audit
+ continue-on-error: true
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/audit_pre_agent_workspace.sh"
+ - name: Execute GitHub Copilot CLI
+ id: agentic_execution
+ # Copilot CLI tool arguments (sorted):
+ # --allow-tool github
+ # --allow-tool safeoutputs
+ timeout-minutes: 20
+ run: |
+ set -o pipefail
+ printf '%s' "$(date +%s%3N)" > /tmp/gh-aw/agent_cli_start_ms.txt
+ touch /tmp/gh-aw/agent-step-summary.md
+ (umask 177 && touch /tmp/gh-aw/agent-stdio.log)
+ trap 'rm -f /home/runner/.copilot/settings.json' EXIT
+ mkdir -p /home/runner/.copilot
+ printf '%s' '{"builtInAgents":{"rubberDuck":false}}' > /home/runner/.copilot/settings.json
+ mkdir -p /tmp/
+ mkdir -p /tmp/gh-aw/
+ mkdir -p /tmp/gh-aw/agent/
+ mkdir -p /tmp/gh-aw/sandbox/agent/logs/
+ GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs copilot --add-dir /tmp/ --add-dir /tmp/gh-aw/ --add-dir /tmp/gh-aw/agent/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-tool github --allow-tool safeoutputs --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt 2>&1 | tee /tmp/gh-aw/agent-stdio.log
+ env:
+ COPILOT_AGENT_RUNNER_TYPE: STANDALONE
+ COPILOT_MODEL: doubao-seed-evolving
+ COPILOT_PROVIDER_BASE_URL: https://ark.cn-beijing.volces.com/api/v3
+ COPILOT_PROVIDER_BEARER_TOKEN: ${{ secrets.OPENAI_API_KEY }}
+ COPILOT_PROVIDER_TYPE: openai
+ COPILOT_PROVIDER_WIRE_API: responses
+ GH_AW_MAX_TURNS: ${{ vars.GH_AW_DEFAULT_MAX_TURNS || '' }}
+ 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_TIMEOUT_MINUTES: 20
+ GH_AW_VERSION: v0.79.6
+ GITHUB_API_URL: ${{ github.api_url }}
+ GITHUB_AW: true
+ GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows
+ 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 }}
+ RUNNER_TEMP: ${{ runner.temp }}
+ S2STOKENS: true
+ XDG_CONFIG_HOME: /home/runner
+ - name: Detect agent errors
+ if: always()
+ id: detect-agent-errors
+ continue-on-error: true
+ run: node "${RUNNER_TEMP}/gh-aw/actions/detect_agent_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@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ 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: 'GH_AW_GITHUB_MCP_SERVER_TOKEN,GH_AW_GITHUB_TOKEN,GITHUB_TOKEN,OPENAI_API_KEY'
+ 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_OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
+ - 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@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ 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,ark.cn-beijing.volces.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@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ 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@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ 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: 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/proxy-logs/
+ !/tmp/gh-aw/proxy-logs/proxy-tls/
+ /tmp/gh-aw/agent-stdio.log
+ /tmp/gh-aw/pre-agent-audit.txt
+ /tmp/gh-aw/agent/
+ /tmp/gh-aw/github_rate_limits.jsonl
+ /tmp/gh-aw/safeoutputs.jsonl
+ /tmp/gh-aw/agent_output.json
+ if-no-files-found: ignore
+
+ conclusion:
+ needs:
+ - activation
+ - agent
+ - safe_outputs
+ if: >
+ always() && (needs.agent.result != 'skipped' || needs.activation.outputs.lockdown_check_failed == 'true' ||
+ needs.activation.outputs.stale_lock_file_failed == 'true' || needs.activation.outputs.daily_effective_workflow_exceeded == 'true')
+ runs-on: ubuntu-slim
+ permissions:
+ contents: read
+ discussions: write
+ issues: write
+ pull-requests: write
+ concurrency:
+ group: "gh-aw-conclusion-issue-triage"
+ cancel-in-progress: false
+ queue: max
+ 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@5c2fe865bb4dc46e1450f6ee0d0541d759aea73a # v0.79.6
+ with:
+ destination: ${{ runner.temp }}/gh-aw/actions
+ job-name: ${{ github.job }}
+ trace-id: ${{ needs.activation.outputs.setup-trace-id }}
+ parent-span-id: ${{ needs.activation.outputs.setup-parent-span-id || needs.activation.outputs.setup-span-id }}
+ env:
+ GH_AW_SETUP_WORKFLOW_NAME: "Issue 自动分类与回复"
+ GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/issue-triage.lock.yml@${{ github.ref }}
+ GH_AW_INFO_VERSION: "1.0.60"
+ GH_AW_INFO_ENGINE_ID: "copilot"
+ - 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: Collect usage artifact files
+ if: always()
+ continue-on-error: true
+ run: |
+ mkdir -p /tmp/gh-aw/usage/agent /tmp/gh-aw/usage/detection
+ echo "Usage artifact source file status:"
+ for file in /tmp/gh-aw/aw-info.jsonl /tmp/gh-aw/agent_usage.jsonl /tmp/gh-aw/detection_usage.jsonl /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl; do
+ [ -f "$file" ] && echo "FOUND: $file" || echo "MISSING: $file"
+ done
+ [ -f /tmp/gh-aw/aw-info.jsonl ] && cp /tmp/gh-aw/aw-info.jsonl /tmp/gh-aw/usage/aw-info.jsonl || true
+ [ -f /tmp/gh-aw/agent_usage.jsonl ] && cp /tmp/gh-aw/agent_usage.jsonl /tmp/gh-aw/usage/agent_usage.jsonl || true
+ [ -f /tmp/gh-aw/detection_usage.jsonl ] && cp /tmp/gh-aw/detection_usage.jsonl /tmp/gh-aw/usage/detection_usage.jsonl || true
+ [ -f /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true
+ [ -f /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true
+ [ -f /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true
+ [ -f /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl || true
+ [ -f /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl || true
+ [ -f /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl || true
+ [ -f /tmp/gh-aw/usage/agent/token_usage.jsonl ] || : > /tmp/gh-aw/usage/agent/token_usage.jsonl
+ [ -f /tmp/gh-aw/usage/detection/token_usage.jsonl ] || : > /tmp/gh-aw/usage/detection/token_usage.jsonl
+ find /tmp/gh-aw/usage -type f -print | sort
+ - name: Upload usage artifact
+ if: always()
+ continue-on-error: true
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
+ with:
+ name: usage
+ path: |
+ /tmp/gh-aw/usage/aw-info.jsonl
+ /tmp/gh-aw/usage/agent_usage.jsonl
+ /tmp/gh-aw/usage/detection_usage.jsonl
+ /tmp/gh-aw/usage/agent/token_usage.jsonl
+ /tmp/gh-aw/usage/detection/token_usage.jsonl
+ if-no-files-found: ignore
+ - name: Process no-op messages
+ id: noop
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
+ GH_AW_NOOP_MAX: "1"
+ GH_AW_WORKFLOW_NAME: "Issue 自动分类与回复"
+ GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/issue-triage.md"
+ 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"
+ GH_AW_AIC: ${{ needs.agent.outputs.aic }}
+ GH_AW_AMBIENT_CONTEXT: ${{ needs.agent.outputs.ambient_context }}
+ GH_AW_WORKFLOW_ID: "issue-triage"
+ 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: Record missing tool
+ id: missing_tool
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ 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: "Issue 自动分类与回复"
+ GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/issue-triage.md"
+ 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@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ 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: "Issue 自动分类与回复"
+ GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/issue-triage.md"
+ 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@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
+ GH_AW_WORKFLOW_NAME: "Issue 自动分类与回复"
+ GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/issue-triage.md"
+ 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: "issue-triage"
+ GH_AW_ACTION_FAILURE_ISSUE_EXPIRES_HOURS: "168"
+ GH_AW_ENGINE_ID: "copilot"
+ GH_AW_CHECKOUT_PR_SUCCESS: ${{ needs.agent.outputs.checkout_pr_success }}
+ GH_AW_EFFECTIVE_TOKENS: ${{ needs.agent.outputs.effective_tokens || '' }}
+ GH_AW_AI_CREDITS_RATE_LIMIT_ERROR: ${{ needs.agent.outputs.ai_credits_rate_limit_error || 'false' }}
+ GH_AW_UNKNOWN_MODEL_AI_CREDITS: ${{ needs.agent.outputs.unknown_model_ai_credits || 'false' }}
+ GH_AW_AIC: ${{ needs.agent.outputs.aic }}
+ GH_AW_MAX_AI_CREDITS: ${{ vars.GH_AW_DEFAULT_MAX_AI_CREDITS || '1000' }}
+ 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_ENGINE_API_HOSTS: "api.enterprise.githubcopilot.com,api.githubcopilot.com,api.business.githubcopilot.com,api.individual.githubcopilot.com"
+ 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_DAILY_EFFECTIVE_WORKFLOW_EXCEEDED: ${{ needs.activation.outputs.daily_effective_workflow_exceeded }}
+ GH_AW_DAILY_EFFECTIVE_WORKFLOW_TOTAL_EFFECTIVE_TOKENS: ${{ needs.activation.outputs.daily_effective_workflow_total_effective_tokens }}
+ GH_AW_DAILY_EFFECTIVE_WORKFLOW_THRESHOLD: ${{ needs.activation.outputs.daily_effective_workflow_threshold }}
+ GH_AW_GROUP_REPORTS: "false"
+ GH_AW_FAILURE_REPORT_AS_ISSUE: "true"
+ GH_AW_MISSING_TOOL_REPORT_AS_FAILURE: "true"
+ GH_AW_MISSING_DATA_REPORT_AS_FAILURE: "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();
+
+ pre_activation:
+ runs-on: ubuntu-slim
+ outputs:
+ activated: ${{ steps.check_membership.outputs.is_team_member == 'true' }}
+ matched_command: ''
+ setup-parent-span-id: ${{ steps.setup.outputs.parent-span-id || steps.setup.outputs.span-id }}
+ setup-span-id: ${{ steps.setup.outputs.span-id }}
+ setup-trace-id: ${{ steps.setup.outputs.trace-id }}
+ steps:
+ - name: Setup Scripts
+ id: setup
+ uses: github/gh-aw-actions/setup@5c2fe865bb4dc46e1450f6ee0d0541d759aea73a # v0.79.6
+ with:
+ destination: ${{ runner.temp }}/gh-aw/actions
+ job-name: ${{ github.job }}
+ env:
+ GH_AW_SETUP_WORKFLOW_NAME: "Issue 自动分类与回复"
+ GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/issue-triage.lock.yml@${{ github.ref }}
+ GH_AW_INFO_VERSION: "1.0.60"
+ GH_AW_INFO_ENGINE_ID: "copilot"
+ - name: Check team membership for workflow
+ id: check_membership
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ 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
+ if: (!cancelled()) && needs.agent.result != 'skipped'
+ runs-on: ubuntu-slim
+ permissions:
+ contents: read
+ discussions: write
+ issues: write
+ pull-requests: write
+ timeout-minutes: 45
+ env:
+ GH_AW_AGENT_AIC: ${{ needs.agent.outputs.aic }}
+ GH_AW_AIC: ${{ needs.agent.outputs.aic }}
+ GH_AW_AMBIENT_CONTEXT: ${{ needs.agent.outputs.ambient_context }}
+ GH_AW_CALLER_WORKFLOW_ID: "${{ github.repository }}/issue-triage"
+ GH_AW_EFFECTIVE_TOKENS: ${{ needs.agent.outputs.effective_tokens }}
+ GH_AW_ENGINE_ID: "copilot"
+ GH_AW_ENGINE_MODEL: ${{ needs.agent.outputs.model }}
+ GH_AW_ENGINE_VERSION: "1.0.60"
+ GH_AW_WORKFLOW_ID: "issue-triage"
+ GH_AW_WORKFLOW_NAME: "Issue 自动分类与回复"
+ GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/issue-triage.md"
+ 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 }}
+ comment_id: ${{ steps.process_safe_outputs.outputs.comment_id }}
+ comment_url: ${{ steps.process_safe_outputs.outputs.comment_url }}
+ 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 }}
+ steps:
+ - name: Setup Scripts
+ id: setup
+ uses: github/gh-aw-actions/setup@5c2fe865bb4dc46e1450f6ee0d0541d759aea73a # v0.79.6
+ with:
+ destination: ${{ runner.temp }}/gh-aw/actions
+ job-name: ${{ github.job }}
+ trace-id: ${{ needs.activation.outputs.setup-trace-id }}
+ parent-span-id: ${{ needs.activation.outputs.setup-parent-span-id || needs.activation.outputs.setup-span-id }}
+ env:
+ GH_AW_SETUP_WORKFLOW_NAME: "Issue 自动分类与回复"
+ GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/issue-triage.lock.yml@${{ github.ref }}
+ GH_AW_INFO_VERSION: "1.0.60"
+ GH_AW_INFO_ENGINE_ID: "copilot"
+ - 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: Configure GH_HOST for enterprise compatibility
+ id: ghes-host-config
+ shell: bash
+ # zizmor: ignore[github-env] - GITHUB_SERVER_URL is set by GitHub Actions, not user input.
+ 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@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
+ GH_AW_COMMENT_ID: ${{ needs.activation.outputs.comment_id }}
+ 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,ark.cn-beijing.volces.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: "{\"add_comment\":{\"max\":1},\"add_labels\":{\"allowed\":[\"bug\",\"feature\",\"enhancement\",\"documentation\",\"question\",\"duplicate\",\"invalid\"]},\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"true\"},\"report_incomplete\":{}}"
+ 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/issue-triage.md b/.github/workflows/issue-triage.md
new file mode 100644
index 0000000..ae11740
--- /dev/null
+++ b/.github/workflows/issue-triage.md
@@ -0,0 +1,72 @@
+---
+on:
+ issues:
+ types: [opened, reopened]
+
+engine:
+ id: copilot
+ env:
+ COPILOT_PROVIDER_BASE_URL: "https://ark.cn-beijing.volces.com/api/v3"
+ COPILOT_PROVIDER_BEARER_TOKEN: ${{ secrets.OPENAI_API_KEY }}
+ COPILOT_MODEL: doubao-seed-evolving
+ COPILOT_PROVIDER_TYPE: openai
+ COPILOT_PROVIDER_WIRE_API: responses
+
+features:
+ dangerously-disable-sandbox-agent: "controlled environment for issue triage automation"
+sandbox:
+ agent: false
+strict: false
+
+network:
+ allowed:
+ - defaults
+ - ark.cn-beijing.volces.com
+
+tools:
+ github:
+ min-integrity: none
+
+permissions:
+ issues: read
+ contents: read
+ pull-requests: read
+ copilot-requests: write
+
+safe-outputs:
+ threat-detection: false
+ add-comment:
+ max: 1
+ add-labels:
+ allowed:
+ - bug
+ - feature
+ - enhancement
+ - documentation
+ - question
+ - duplicate
+ - invalid
+---
+
+# Issue 自动分类与回复
+
+分析仓库 ${{ github.repository }} 中新开的 Issue。
+
+## 任务
+
+1. 阅读 Issue 的标题和正文
+2. 判断类型,添加合适的标签:
+ - `bug`:程序出错、功能异常
+ - `feature`:新功能请求
+ - `enhancement`:改进现有功能
+ - `documentation`:文档问题
+ - `question`:使用疑问
+ - `duplicate`:与已有 Issue 重复
+ - `invalid`:信息不完整或无效
+
+3. 使用用户提问的语言回复一条友好的评论,包含:
+ - 感谢用户提交 Issue
+ - 说明你打的标签和原因
+ - 如果是 bug,请用户补充:复现步骤、环境信息、错误日志
+ - 如果是 question,尝试根据仓库代码和文档给出初步解答
+ - 预计处理时间(普通问题 3 个工作日内)
\ No newline at end of file
diff --git a/.github/workflows/macbuild.yml b/.github/workflows/macbuild.yml
index b975c7c..b999a94 100644
--- a/.github/workflows/macbuild.yml
+++ b/.github/workflows/macbuild.yml
@@ -20,12 +20,12 @@ jobs:
steps:
- name: Checkout main repository code
- uses: actions/checkout@v4
+ uses: actions/checkout@v6
with:
ref: 'develop'
- name: Checkout dependency repository (xengine)
- uses: actions/checkout@v4
+ uses: actions/checkout@v6
with:
repository: libxengine/libxengine
path: libxengine
@@ -77,14 +77,14 @@ jobs:
- name: Upload folder as artifact with mac x64
if: matrix.os == 'macos-15-intel'
- uses: actions/upload-artifact@v4
+ uses: actions/upload-artifact@v7
with:
name: XEngine_MQServiceApp-Mac_x86_64
path: XEngine_Release/
retention-days: 1
- name: Upload folder as artifact with mac arm
if: matrix.os == 'macos-15'
- uses: actions/upload-artifact@v4
+ uses: actions/upload-artifact@v7
with:
name: XEngine_MQServiceApp-Mac_Arm64
path: XEngine_Release/
diff --git a/.github/workflows/msbuild.yml b/.github/workflows/msbuild.yml
index bdf78ef..884d6fd 100644
--- a/.github/workflows/msbuild.yml
+++ b/.github/workflows/msbuild.yml
@@ -21,12 +21,12 @@ jobs:
steps:
- name: Checkout main repository code
- uses: actions/checkout@v4
+ uses: actions/checkout@v6
with:
ref: 'develop'
- name: Checkout dependency repository (xengine)
- uses: actions/checkout@v4
+ uses: actions/checkout@v6
with:
repository: libxengine/libxengine
path: libxengine
@@ -73,7 +73,7 @@ jobs:
shell: pwsh
- name: Setup MSBuild
- uses: microsoft/setup-msbuild@v2
+ uses: microsoft/setup-msbuild@v3
- name: Build Solution
run: msbuild XEngine_Source/XEngine_MQServiceApp.sln /p:Configuration=${{ matrix.configuration }} /p:Platform=${{ matrix.platform }}
@@ -109,21 +109,21 @@ jobs:
- name: Upload folder as artifact with x86
if: matrix.configuration == 'Release' && matrix.platform == 'x86'
- uses: actions/upload-artifact@v4
+ uses: actions/upload-artifact@v7
with:
name: XEngine_MQServiceApp-Windows_x86_32
path: XEngine_Release/
retention-days: 1
- name: Upload folder as artifact with x64
if: matrix.configuration == 'Release' && matrix.platform == 'x64'
- uses: actions/upload-artifact@v4
+ uses: actions/upload-artifact@v7
with:
name: XEngine_MQServiceApp-Windows_x86_64
path: XEngine_Release/
retention-days: 1
- name: Upload folder as artifact with Arm64
if: matrix.configuration == 'Release' && matrix.platform == 'Arm64'
- uses: actions/upload-artifact@v4
+ uses: actions/upload-artifact@v7
with:
name: XEngine_MQServiceApp-Windows_Arm64
path: XEngine_Release/
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index dfd1818..aa2e11d 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -12,12 +12,12 @@ jobs:
steps:
# 检出代码并包含标签
- name: Checkout code
- uses: actions/checkout@v4
+ uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Download ubuntu build
- uses: dawidd6/action-download-artifact@v6
+ uses: dawidd6/action-download-artifact@v21
with:
workflow: Ubuntu_build.yml
workflow_conclusion: success
@@ -25,8 +25,17 @@ jobs:
skip_unpack: true
if_no_artifact_found: fail
path: ./XRelease/
+ - name: Download Mint build
+ uses: dawidd6/action-download-artifact@v21
+ with:
+ workflow: Mintbuild.yml
+ workflow_conclusion: success
+ check_artifacts: false
+ skip_unpack: true
+ if_no_artifact_found: fail
+ path: ./XRelease/
- name: Download fedora build
- uses: dawidd6/action-download-artifact@v6
+ uses: dawidd6/action-download-artifact@v21
with:
workflow: fedora_build.yml
workflow_conclusion: success
@@ -35,7 +44,7 @@ jobs:
if_no_artifact_found: fail
path: ./XRelease/
- name: Download debian build
- uses: dawidd6/action-download-artifact@v6
+ uses: dawidd6/action-download-artifact@v21
with:
workflow: debian_build.yml
workflow_conclusion: success
@@ -44,7 +53,7 @@ jobs:
if_no_artifact_found: fail
path: ./XRelease/
- name: Download Rockylinux
- uses: dawidd6/action-download-artifact@v6
+ uses: dawidd6/action-download-artifact@v21
with:
workflow: Rocky_build.yml
workflow_conclusion: success
@@ -53,16 +62,16 @@ jobs:
if_no_artifact_found: fail
path: ./XRelease/
- name: Download CentOS
- uses: dawidd6/action-download-artifact@v6
+ uses: dawidd6/action-download-artifact@v21
with:
- workflow: Centos_build.yml
+ workflow: Centos_build1s.yml
workflow_conclusion: success
check_artifacts: false
skip_unpack: true
if_no_artifact_found: fail
path: ./XRelease/
- name: Download Alma
- uses: dawidd6/action-download-artifact@v6
+ uses: dawidd6/action-download-artifact@v21
with:
workflow: Alma_build.yml
workflow_conclusion: success
@@ -71,7 +80,7 @@ jobs:
if_no_artifact_found: fail
path: ./XRelease/
- name: Download macbuild
- uses: dawidd6/action-download-artifact@v6
+ uses: dawidd6/action-download-artifact@v21
with:
workflow: macbuild.yml
workflow_conclusion: success
@@ -80,7 +89,7 @@ jobs:
if_no_artifact_found: fail
path: ./XRelease/
- name: Download msbuild
- uses: dawidd6/action-download-artifact@v6
+ uses: dawidd6/action-download-artifact@v21
with:
workflow: msbuild.yml
workflow_conclusion: success
@@ -122,7 +131,7 @@ jobs:
echo "$release_notes" > release_notes.txt
- name: Release
- uses: softprops/action-gh-release@v2
+ uses: softprops/action-gh-release@v3
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
diff --git a/CHANGELOG b/CHANGELOG
index 019df1b..52d4ce1 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,27 @@
+XEngine_MQService V3.20.0.1001
+
+ci:更新了CI版本库
+ci:删除了多余的扫描
+更新:依赖库
+更新:windows 编译器VS到2026版本
+增加:AI代理解决问题
+增加:发送消息会返回序列号了
+增加:心跳支持
+修改:现在绑定消息的序列号从1开始
+修改:VS编译器的运行时库统一
+修正:codeql 扫描出的问题
+
+ci:update last version
+ci:delete unused
+update:depend library
+update:vs to 2026
+added:agentic workflows for issue triage and auto fix
+added:reply with serial number for post message
+added:heartbeat support
+modify:serial from 1 number to start
+modify:vs crt runtime unified
+fixed:codeql scan problem
+======================================================================================
XEngine_MQService V3.19.0.1001
增加:权限控制开关
diff --git a/XEngine_Apps/MQCore_HTTPApp/MQCore_HTTPApp.vcxproj b/XEngine_Apps/MQCore_HTTPApp/MQCore_HTTPApp.vcxproj
index 91905eb..e401992 100644
--- a/XEngine_Apps/MQCore_HTTPApp/MQCore_HTTPApp.vcxproj
+++ b/XEngine_Apps/MQCore_HTTPApp/MQCore_HTTPApp.vcxproj
@@ -29,26 +29,26 @@
Application
true
- v143
+ v145
MultiByte
Application
false
- v143
+ v145
true
Unicode
Application
true
- v143
+ v145
Unicode
Application
false
- v143
+ v145
true
Unicode
diff --git a/XEngine_Apps/MQCore_TCPApp/MQCore_TCPApp.cpp b/XEngine_Apps/MQCore_TCPApp/MQCore_TCPApp.cpp
index 099a40c..8d7c6de 100644
--- a/XEngine_Apps/MQCore_TCPApp/MQCore_TCPApp.cpp
+++ b/XEngine_Apps/MQCore_TCPApp/MQCore_TCPApp.cpp
@@ -289,7 +289,7 @@ void MQ_Get(int nType = 0)
else
{
_xtprintf("获取消息队列数据失败,错误码:%d\n", st_ProtocolHdr.wReserve);
- }
+ }
break;
}
std::this_thread::sleep_for(std::chrono::milliseconds(1));
diff --git a/XEngine_Apps/MQCore_TCPApp/MQCore_TCPApp.vcxproj b/XEngine_Apps/MQCore_TCPApp/MQCore_TCPApp.vcxproj
index f3877e1..4bc95ab 100644
--- a/XEngine_Apps/MQCore_TCPApp/MQCore_TCPApp.vcxproj
+++ b/XEngine_Apps/MQCore_TCPApp/MQCore_TCPApp.vcxproj
@@ -29,26 +29,26 @@
Application
true
- v143
+ v145
MultiByte
Application
false
- v143
+ v145
true
Unicode
Application
true
- v143
+ v145
Unicode
Application
false
- v143
+ v145
true
Unicode
diff --git a/XEngine_Apps/MQCore_WSApp/MQCore_WSApp.vcxproj b/XEngine_Apps/MQCore_WSApp/MQCore_WSApp.vcxproj
index af1f394..7322106 100644
--- a/XEngine_Apps/MQCore_WSApp/MQCore_WSApp.vcxproj
+++ b/XEngine_Apps/MQCore_WSApp/MQCore_WSApp.vcxproj
@@ -29,26 +29,26 @@
Application
true
- v143
+ v145
MultiByte
Application
false
- v143
+ v145
true
Unicode
Application
true
- v143
+ v145
Unicode
Application
false
- v143
+ v145
true
Unicode
diff --git a/XEngine_Docment/Docment_en.docx b/XEngine_Docment/Docment_en.docx
index b3eb094..89bfdf0 100644
Binary files a/XEngine_Docment/Docment_en.docx and b/XEngine_Docment/Docment_en.docx differ
diff --git a/XEngine_Docment/Docment_zh.docx b/XEngine_Docment/Docment_zh.docx
index 18d2e25..c33b434 100644
Binary files a/XEngine_Docment/Docment_zh.docx and b/XEngine_Docment/Docment_zh.docx differ
diff --git a/XEngine_Release/XEngine_Config/XEngine_Config.json b/XEngine_Release/XEngine_Config/XEngine_Config.json
index 8e4a4f5..ba46c4c 100644
--- a/XEngine_Release/XEngine_Config/XEngine_Config.json
+++ b/XEngine_Release/XEngine_Config/XEngine_Config.json
@@ -14,6 +14,13 @@
"nHttpThread": 2,
"nWSThread": 2,
"nMQTTThread": 2
+ },
+ "XTime": {
+ "nHeartCheck": 3,
+ "nTCPTime": 5,
+ "nWSTime": 5,
+ "nHTTPTime": 5,
+ "nMQTTTime": 5
},
"XLog": {
"tszLOGFile": "./XEngine_Log/XEngine_MQServiceApp.Log",
@@ -26,7 +33,7 @@
"SQLAddr": "118.25.14.242",
"SQLPort": 3306,
"SQLUser": "root",
- "SQLPass": "123123Qyt!"
+ "SQLPass": "123"
},
"XPass": {
"nTimeout": 2,
@@ -53,7 +60,7 @@
"tszEMailSubject": "XEngine MessageQueue Notify",
"tszServiceAddr": "smtp://smtp.163.com",
"tszUser": "ggqytgodlove@163.com",
- "tszPass": "STZsBi3uuJvWsWL3"
+ "tszPass": "1"
},
"SMSNotify": {
"bEnable": false
diff --git a/XEngine_Release/XEngine_Config/XEngine_VerConfig.json b/XEngine_Release/XEngine_Config/XEngine_VerConfig.json
index e663a9f..45aa441 100644
--- a/XEngine_Release/XEngine_Config/XEngine_VerConfig.json
+++ b/XEngine_Release/XEngine_Config/XEngine_VerConfig.json
@@ -1,5 +1,6 @@
{
"XVer":[
+ "3.20.0.1001 Build20260729",
"3.19.0.1001 Build20260228",
"3.18.0.1001 Build20251016",
"3.17.0.1001 Build20250907",
diff --git a/XEngine_Source/MQCore_ConfigModule/Config_Define.h b/XEngine_Source/MQCore_ConfigModule/Config_Define.h
index 3e9c59a..749ddb6 100644
--- a/XEngine_Source/MQCore_ConfigModule/Config_Define.h
+++ b/XEngine_Source/MQCore_ConfigModule/Config_Define.h
@@ -33,6 +33,14 @@ typedef struct
int nMQTTThread;
}st_XMax;
struct
+ {
+ int nHeartCheck; //检测次数
+ int nTCPTime; //TCP检测时间
+ int nWSTime; //WEBSOCKET检测时间
+ int nMQTime; //MQTT检测时间
+ int nHTTPTime; //HTTP检测时间
+ }st_XTime;
+ struct
{
XCHAR tszLOGFile[XPATH_MAX];
int nMaxSize;
diff --git a/XEngine_Source/MQCore_ConfigModule/Config_Json/Config_Json.cpp b/XEngine_Source/MQCore_ConfigModule/Config_Json/Config_Json.cpp
index b5111bc..6d511ae 100644
--- a/XEngine_Source/MQCore_ConfigModule/Config_Json/Config_Json.cpp
+++ b/XEngine_Source/MQCore_ConfigModule/Config_Json/Config_Json.cpp
@@ -22,10 +22,28 @@ CConfig_Json::~CConfig_Json()
//////////////////////////////////////////////////////////////////////////
// 公用函数
//////////////////////////////////////////////////////////////////////////
+// 函数名称: Config_Json_File
+// 功能说明:
+// 读取指定 JSON 配置文件,并将结果填充到 XENGINE_SERVERCONFIG 结构体中。
+// 函数按“参数校验 -> 文件读取 -> JSON 解析 -> 字段映射”流程执行。
+//
+// 参数:
+// lpszConfigFile [in] 配置文件路径
+// pSt_ServerConfig [out] 配置输出结构体,不能为空
+//
+// 返回值:
+// true : 读取并解析成功
+// false : 失败(同时设置 Config_IsErrorOccur / Config_dwErrorCode)
+//
+// 错误处理:
+// - 参数或文件打开失败: ERROR_MQ_MODULE_CONFIG_JSON_PARAMENT
+// - JSON 解析失败 : ERROR_MQ_MODULE_CONFIG_JSON_PARSE
bool CConfig_Json::Config_Json_File(LPCXSTR lpszConfigFile,XENGINE_SERVERCONFIG *pSt_ServerConfig)
{
+ // 初始化错误状态,默认本次调用无错误
Config_IsErrorOccur = false;
+ // 1) 参数有效性校验
if ((NULL == lpszConfigFile) || (NULL == pSt_ServerConfig))
{
Config_IsErrorOccur = true;
@@ -36,6 +54,7 @@ bool CConfig_Json::Config_Json_File(LPCXSTR lpszConfigFile,XENGINE_SERVERCONFIG
Json::Value st_JsonRoot;
Json::CharReaderBuilder st_JsonBuilder;
+ // 2) 打开并读取配置文件内容
FILE* pSt_File = _xtfopen(lpszConfigFile, _X("rb"));
if (NULL == pSt_File)
{
@@ -47,6 +66,7 @@ bool CConfig_Json::Config_Json_File(LPCXSTR lpszConfigFile,XENGINE_SERVERCONFIG
size_t nSize = fread(tszMsgBuffer, 1, sizeof(tszMsgBuffer), pSt_File);
fclose(pSt_File);
+ // 3) 解析 JSON 文本
std::unique_ptr const pSt_JsonReader(st_JsonBuilder.newCharReader());
if (!pSt_JsonReader->parse(tszMsgBuffer, tszMsgBuffer + nSize, &st_JsonRoot, &st_JsonError))
{
@@ -54,6 +74,7 @@ bool CConfig_Json::Config_Json_File(LPCXSTR lpszConfigFile,XENGINE_SERVERCONFIG
Config_dwErrorCode = ERROR_MQ_MODULE_CONFIG_JSON_PARSE;
return false;
}
+ // 4) 将 JSON 字段映射到配置结构体
_tcsxcpy(pSt_ServerConfig->tszIPAddr,st_JsonRoot["tszIPAddr"].asCString());
_tcsxcpy(pSt_ServerConfig->tszTopic, st_JsonRoot["tszTopic"].asCString());
pSt_ServerConfig->bDeamon = st_JsonRoot["bDeamon"].asInt();
@@ -76,6 +97,19 @@ bool CConfig_Json::Config_Json_File(LPCXSTR lpszConfigFile,XENGINE_SERVERCONFIG
pSt_ServerConfig->st_XMax.nHttpThread = st_JsonXMax["nHttpThread"].asInt();
pSt_ServerConfig->st_XMax.nWSThread = st_JsonXMax["nWSThread"].asInt();
pSt_ServerConfig->st_XMax.nMQTTThread = st_JsonXMax["nMQTTThread"].asInt();
+ //时间配置
+ if (st_JsonRoot["XTime"].empty() || (5 != st_JsonRoot["XTime"].size()))
+ {
+ Config_IsErrorOccur = true;
+ Config_dwErrorCode = ERROR_MQ_MODULE_CONFIG_JSON_XTIME;
+ return false;
+ }
+ Json::Value st_JsonXTime = st_JsonRoot["XTime"];
+ pSt_ServerConfig->st_XTime.nHeartCheck = st_JsonXTime["nHeartCheck"].asInt();
+ pSt_ServerConfig->st_XTime.nTCPTime = st_JsonXTime["nTCPTime"].asInt();
+ pSt_ServerConfig->st_XTime.nWSTime = st_JsonXTime["nWSTime"].asInt();
+ pSt_ServerConfig->st_XTime.nHTTPTime = st_JsonXTime["nHTTPTime"].asInt();
+ pSt_ServerConfig->st_XTime.nMQTime = st_JsonXTime["nMQTTTime"].asInt();
if (st_JsonRoot["XLog"].empty() || (5 != st_JsonRoot["XLog"].size()))
{
diff --git a/XEngine_Source/MQCore_ConfigModule/MQCore_ConfigModule.vcxproj b/XEngine_Source/MQCore_ConfigModule/MQCore_ConfigModule.vcxproj
index 6bc93e2..7e571ff 100644
--- a/XEngine_Source/MQCore_ConfigModule/MQCore_ConfigModule.vcxproj
+++ b/XEngine_Source/MQCore_ConfigModule/MQCore_ConfigModule.vcxproj
@@ -37,39 +37,39 @@
DynamicLibrary
true
- v143
+ v145
Unicode
DynamicLibrary
false
- v143
+ v145
true
Unicode
DynamicLibrary
true
- v143
+ v145
Unicode
DynamicLibrary
true
- v143
+ v145
Unicode
DynamicLibrary
false
- v143
+ v145
true
Unicode
DynamicLibrary
false
- v143
+ v145
true
Unicode
@@ -152,7 +152,7 @@
true
Use
pch.h
- MultiThreaded
+ MultiThreadedDLL
4819
stdcpp20
stdc17
@@ -213,7 +213,7 @@
true
Use
pch.h
- MultiThreaded
+ MultiThreadedDLL
4819
stdcpp20
stdc17
diff --git a/XEngine_Source/MQCore_DBModule/DBModule_MQData/DBModule_MQData.cpp b/XEngine_Source/MQCore_DBModule/DBModule_MQData/DBModule_MQData.cpp
index f44c265..2ab7b05 100644
--- a/XEngine_Source/MQCore_DBModule/DBModule_MQData/DBModule_MQData.cpp
+++ b/XEngine_Source/MQCore_DBModule/DBModule_MQData/DBModule_MQData.cpp
@@ -196,11 +196,18 @@ bool CDBModule_MQData::DBModule_MQData_Delete(XENGINE_DBMESSAGEQUEUE* pSt_DBInfo
类型:逻辑型
意思:是否成功
备注:
+ 查询流程说明:
+ 1) 参数校验:输入结构必须有效,否则设置统一错误码并返回失败;
+ 2) 缓存优先:当启用查询缓存时先查内存,命中则直接返回成功;
+ 3) 数据库查询:缓存未命中后拼接并执行 SQL,从结果集中填充输出结构;
+ 4) 缓存回填:数据库查询成功后,将结果写回缓存以加速后续查询;
+ 5) 错误语义:任一阶段失败均通过 DBModule_IsErrorOccur/DBModule_dwErrorCode 上报。
*********************************************************************/
bool CDBModule_MQData::DBModule_MQData_Query(XENGINE_DBMESSAGEQUEUE* pSt_DBInfo)
{
DBModule_IsErrorOccur = false;
+ // [阶段1] 输入参数校验:查询条件与输出承载结构均依赖 pSt_DBInfo。
if (NULL == pSt_DBInfo)
{
DBModule_IsErrorOccur = true;
@@ -208,6 +215,7 @@ bool CDBModule_MQData::DBModule_MQData_Query(XENGINE_DBMESSAGEQUEUE* pSt_DBInfo)
return false;
}
+ // [阶段2] 查询缓存优先:命中则直接返回,避免访问数据库。
if (m_bMemoryQuery)
{
if (MemoryCache_DBData_DataQuery(pSt_DBInfo))
@@ -215,6 +223,7 @@ bool CDBModule_MQData::DBModule_MQData_Query(XENGINE_DBMESSAGEQUEUE* pSt_DBInfo)
return true;
}
}
+ // [阶段3] 缓存未命中,执行数据库查询。
//查询
XNETHANDLE xhTable = 0;
__int64u nllLine = 0;
diff --git a/XEngine_Source/MQCore_DBModule/MQCore_DBModule.vcxproj b/XEngine_Source/MQCore_DBModule/MQCore_DBModule.vcxproj
index 48bf97f..7d8d2f8 100644
--- a/XEngine_Source/MQCore_DBModule/MQCore_DBModule.vcxproj
+++ b/XEngine_Source/MQCore_DBModule/MQCore_DBModule.vcxproj
@@ -37,39 +37,39 @@
DynamicLibrary
true
- v143
+ v145
Unicode
DynamicLibrary
false
- v143
+ v145
true
Unicode
DynamicLibrary
true
- v143
+ v145
Unicode
DynamicLibrary
true
- v143
+ v145
Unicode
DynamicLibrary
false
- v143
+ v145
true
Unicode
DynamicLibrary
false
- v143
+ v145
true
Unicode
diff --git a/XEngine_Source/MQCore_HelpModule/MQCore_HelpModule.vcxproj b/XEngine_Source/MQCore_HelpModule/MQCore_HelpModule.vcxproj
index b3a8417..7dd2a88 100644
--- a/XEngine_Source/MQCore_HelpModule/MQCore_HelpModule.vcxproj
+++ b/XEngine_Source/MQCore_HelpModule/MQCore_HelpModule.vcxproj
@@ -37,39 +37,39 @@
DynamicLibrary
true
- v143
+ v145
Unicode
DynamicLibrary
false
- v143
+ v145
true
Unicode
DynamicLibrary
true
- v143
+ v145
Unicode
DynamicLibrary
true
- v143
+ v145
Unicode
DynamicLibrary
false
- v143
+ v145
true
Unicode
DynamicLibrary
false
- v143
+ v145
true
Unicode
diff --git a/XEngine_Source/MQCore_MemoryCache/MQCore_MemoryCache.vcxproj b/XEngine_Source/MQCore_MemoryCache/MQCore_MemoryCache.vcxproj
index cb25f8b..00db5b0 100644
--- a/XEngine_Source/MQCore_MemoryCache/MQCore_MemoryCache.vcxproj
+++ b/XEngine_Source/MQCore_MemoryCache/MQCore_MemoryCache.vcxproj
@@ -37,39 +37,39 @@
DynamicLibrary
true
- v143
+ v145
Unicode
DynamicLibrary
false
- v143
+ v145
true
Unicode
DynamicLibrary
true
- v143
+ v145
Unicode
DynamicLibrary
true
- v143
+ v145
Unicode
DynamicLibrary
false
- v143
+ v145
true
Unicode
DynamicLibrary
false
- v143
+ v145
true
Unicode
diff --git a/XEngine_Source/MQCore_ProtocolModule/MQCore_ProtocolModule.vcxproj b/XEngine_Source/MQCore_ProtocolModule/MQCore_ProtocolModule.vcxproj
index 39d5e37..a118431 100644
--- a/XEngine_Source/MQCore_ProtocolModule/MQCore_ProtocolModule.vcxproj
+++ b/XEngine_Source/MQCore_ProtocolModule/MQCore_ProtocolModule.vcxproj
@@ -37,39 +37,39 @@
DynamicLibrary
true
- v143
+ v145
Unicode
DynamicLibrary
false
- v143
+ v145
true
Unicode
DynamicLibrary
true
- v143
+ v145
Unicode
DynamicLibrary
true
- v143
+ v145
Unicode
DynamicLibrary
false
- v143
+ v145
true
Unicode
DynamicLibrary
false
- v143
+ v145
true
Unicode
@@ -156,7 +156,7 @@
true
Use
pch.h
- MultiThreaded
+ MultiThreadedDLL
4819
stdcpp20
stdc17
@@ -217,7 +217,7 @@
true
Use
pch.h
- MultiThreaded
+ MultiThreadedDLL
4819
stdcpp20
stdc17
diff --git a/XEngine_Source/MQCore_ProtocolModule/ProtocolModule_Parse/ProtocolModule_Parse.cpp b/XEngine_Source/MQCore_ProtocolModule/ProtocolModule_Parse/ProtocolModule_Parse.cpp
index 48993cb..49ef3c1 100644
--- a/XEngine_Source/MQCore_ProtocolModule/ProtocolModule_Parse/ProtocolModule_Parse.cpp
+++ b/XEngine_Source/MQCore_ProtocolModule/ProtocolModule_Parse/ProtocolModule_Parse.cpp
@@ -55,14 +55,18 @@ CProtocolModule_Parse::~CProtocolModule_Parse()
*********************************************************************/
bool CProtocolModule_Parse::ProtocolModule_Parse_Websocket(LPCXSTR lpszMsgBuffer, int nMsgLen, XENGINE_PROTOCOLHDR* pSt_ProtocolHdr, XCHAR* ptszMsgBuffer, int* pInt_MsgLen)
{
+ // 初始化错误状态;本函数任何失败路径都会设置统一错误码后返回 false。
Protocol_IsErrorOccur = false;
+ // 基础参数校验:输入缓冲区必须有效。
if (NULL == lpszMsgBuffer)
{
Protocol_IsErrorOccur = true;
Protocol_dwErrorCode = ERROR_MQ_MODULE_PROTOCOL_PARAMENT;
return false;
}
+
+ // 第一步:将 WebSocket 文本消息解析为 JSON 根对象。
Json::Value st_JsonRoot;
JSONCPP_STRING st_JsonError;
Json::CharReaderBuilder st_ReaderBuilder;
@@ -75,6 +79,8 @@ bool CProtocolModule_Parse::ProtocolModule_Parse_Websocket(LPCXSTR lpszMsgBuffer
return false;
}
+ // 第二步:提取公共协议头字段(按字段是否存在进行兼容性读取)。
+ // pSt_ProtocolHdr 允许为空;为空时只执行消息体解析流程。
if (NULL != pSt_ProtocolHdr)
{
if (!st_JsonRoot["unOperatorType"].isNull())
@@ -103,6 +109,7 @@ bool CProtocolModule_Parse::ProtocolModule_Parse_Websocket(LPCXSTR lpszMsgBuffer
}
}
+ // 第三步:初始化消息体解析上下文,后续根据操作类型解析具体业务字段。
int nPos = 0;
*pInt_MsgLen = 0;
XENGINE_PROTOCOL_XMQ st_MQProtocol;
diff --git a/XEngine_Source/MQCore_SessionModule/MQCore_SessionModule.vcxproj b/XEngine_Source/MQCore_SessionModule/MQCore_SessionModule.vcxproj
index 7bd7aa5..1c60385 100644
--- a/XEngine_Source/MQCore_SessionModule/MQCore_SessionModule.vcxproj
+++ b/XEngine_Source/MQCore_SessionModule/MQCore_SessionModule.vcxproj
@@ -37,39 +37,39 @@
DynamicLibrary
true
- v143
+ v145
Unicode
DynamicLibrary
false
- v143
+ v145
true
Unicode
DynamicLibrary
true
- v143
+ v145
Unicode
DynamicLibrary
true
- v143
+ v145
Unicode
DynamicLibrary
false
- v143
+ v145
true
Unicode
DynamicLibrary
false
- v143
+ v145
true
Unicode
@@ -156,7 +156,7 @@
true
Use
pch.h
- MultiThreaded
+ MultiThreadedDLL
4819
stdcpp20
stdc17
@@ -217,7 +217,7 @@
true
Use
pch.h
- MultiThreaded
+ MultiThreadedDLL
4819
stdcpp20
stdc17
diff --git a/XEngine_Source/Makefile b/XEngine_Source/Makefile
index 1d9a4bd..697a235 100644
--- a/XEngine_Source/Makefile
+++ b/XEngine_Source/Makefile
@@ -1,6 +1,7 @@
RELEASE = 0
UNICODE = 0
PLATFORM=linux
+BUILDTYPE=0
FLAGS=
#要编译的模块
BASE_THIRDPART_JSONCPP = ./XEngine_DependLibrary/XEngine_Module/jsoncpp
@@ -24,10 +25,21 @@ else ifeq ($(PLATFORM),mac)
FILEEXT = dylib
endif
-XENGINE_MODULES = libjsoncpp.so libXEngine_InfoReport.so libXEngine_Token.so libXEngine_Verification.so libXEngine_MSGNotify.so \
- libMQCore_ConfigModule.so libMQCore_ProtocolModule.so libMQCore_SessionModule.so libMQCore_MemoryCache.so libMQCore_DBModule.so libMQCore_HelpModule.so \
+# 第三方库模块
+MODULES_THIRD = libjsoncpp.so libXEngine_InfoReport.so libXEngine_Token.so libXEngine_Verification.so libXEngine_MSGNotify.so
+# 业务模块 + 应用
+MODULES_APP = libMQCore_ConfigModule.so libMQCore_ProtocolModule.so libMQCore_SessionModule.so libMQCore_MemoryCache.so libMQCore_DBModule.so libMQCore_HelpModule.so \
XEngine_MQServiceApp.exe
+# 根据 BUILDTYPE 决定编译目标
+ifeq ($(BUILDTYPE),0)
+ XENGINE_MODULES = $(MODULES_THIRD) $(MODULES_APP)
+else ifeq ($(BUILDTYPE),1)
+ XENGINE_MODULES = $(MODULES_THIRD)
+else ifeq ($(BUILDTYPE),2)
+ XENGINE_MODULES = $(MODULES_APP)
+endif
+
.PHONY:MakeAll
MakeAll:$(XENGINE_MODULES)
diff --git a/XEngine_Source/XEngine_DependLibrary b/XEngine_Source/XEngine_DependLibrary
index adf48e2..237be58 160000
--- a/XEngine_Source/XEngine_DependLibrary
+++ b/XEngine_Source/XEngine_DependLibrary
@@ -1 +1 @@
-Subproject commit adf48e22d68f741ec52f299945f8f8f8fb3df9d2
+Subproject commit 237be589ec33bba0bf3405c095db470c1d3766b3
diff --git a/XEngine_Source/XEngine_MQServiceApp/MQService_HTTPTask/MQService_HTTPPost.cpp b/XEngine_Source/XEngine_MQServiceApp/MQService_HTTPTask/MQService_HTTPPost.cpp
index 53f1fca..2f1668c 100644
--- a/XEngine_Source/XEngine_MQServiceApp/MQService_HTTPTask/MQService_HTTPPost.cpp
+++ b/XEngine_Source/XEngine_MQServiceApp/MQService_HTTPTask/MQService_HTTPPost.cpp
@@ -99,6 +99,7 @@ bool MessageQueue_HttpTask_Post(LPCXSTR lpszClientAddr, LPCXSTR lpszFuncName, LP
XENGINE_DBUSERKEY st_Userkey;
memset(&st_Userkey, '\0', sizeof(XENGINE_DBUSERKEY));
+ st_Userkey.nKeySerial = 1;
_tcsxcpy(st_Userkey.tszUserName, st_UserInfo.tszUserName);
_tcsxcpy(st_Userkey.tszKeyName, st_ServiceCfg.tszTopic);
//创建
@@ -268,7 +269,7 @@ bool MessageQueue_HttpTask_Post(LPCXSTR lpszClientAddr, LPCXSTR lpszFuncName, LP
if (DBModule_MQUser_KeyQuery(&st_Userkey))
{
//有就更新
- st_Userkey.nKeySerial = st_MQProtocol.nSerial;
+ st_Userkey.nKeySerial = st_MQProtocol.nSerial == 0 ? 1 : st_MQProtocol.nSerial;
if (!DBModule_MQUser_KeyUPDate(&st_Userkey))
{
ProtocolModule_Packet_Http(tszSDBuffer, &nSDLen, ERROR_XENGINE_MESSAGE_HTTP_FAILURE, _X("update bind topic is failure"));
diff --git a/XEngine_Source/XEngine_MQServiceApp/MQService_Hdr.h b/XEngine_Source/XEngine_MQServiceApp/MQService_Hdr.h
index 7504b20..4e7f7b7 100644
--- a/XEngine_Source/XEngine_MQServiceApp/MQService_Hdr.h
+++ b/XEngine_Source/XEngine_MQServiceApp/MQService_Hdr.h
@@ -80,6 +80,11 @@ extern XHANDLE xhHTTPSocket;
extern XHANDLE xhWSSocket;
extern XHANDLE xhMQTTSocket;
+extern XHANDLE xhTCPHeart;
+extern XHANDLE xhHTTPHeart;
+extern XHANDLE xhWSHeart;
+extern XHANDLE xhMQTTHeart;
+
extern XHANDLE xhTCPPacket;
extern XHANDLE xhHTTPPacket;
extern XHANDLE xhWSPacket;
diff --git a/XEngine_Source/XEngine_MQServiceApp/MQService_Net.cpp b/XEngine_Source/XEngine_MQServiceApp/MQService_Net.cpp
index ce409db..f836c4d 100644
--- a/XEngine_Source/XEngine_MQServiceApp/MQService_Net.cpp
+++ b/XEngine_Source/XEngine_MQServiceApp/MQService_Net.cpp
@@ -19,10 +19,15 @@ void XCALLBACK MessageQueue_Callback_TCPLeave(LPCXSTR lpszClientAddr, XSOCKET hS
{
XEngine_MQXService_Close(lpszClientAddr, XENGINE_MQAPP_NETTYPE_TCP, false);
}
+void XCALLBACK MessageQueue_Client_TCPHeart(LPCXSTR lpszClientAddr, XSOCKET hSocket, int nStatus, XPVOID lParam)
+{
+ XEngine_MQXService_Close(lpszClientAddr, XENGINE_MQAPP_NETTYPE_TCP, true);
+}
//////////////////////////////////////////////////////////////////////////
bool XCALLBACK MessageQueue_Callback_MQTTLogin(LPCXSTR lpszClientAddr, XSOCKET hSocket, XPVOID lParam)
{
MQTTProtocol_Parse_Insert(lpszClientAddr);
+ XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _X("MQTT客户端:%s 链接到服务器"), lpszClientAddr);
return true;
}
void XCALLBACK MessageQueue_Callback_MQTTRecv(LPCXSTR lpszClientAddr, XSOCKET hSocket, LPCXSTR lpszRecvMsg, int nMsgLen, XPVOID lParam)
@@ -38,6 +43,10 @@ void XCALLBACK MessageQueue_Callback_MQTTLeave(LPCXSTR lpszClientAddr, XSOCKET h
{
XEngine_MQXService_Close(lpszClientAddr, XENGINE_MQAPP_NETTYPE_MQTT, false);
}
+void XCALLBACK MessageQueue_Client_MQTTHeart(LPCXSTR lpszClientAddr, XSOCKET hSocket, int nStatus, XPVOID lParam)
+{
+ XEngine_MQXService_Close(lpszClientAddr, XENGINE_MQAPP_NETTYPE_MQTT, true);
+}
//////////////////////////////////////////////////////////////////////////
bool XCALLBACK MessageQueue_Callback_HttpLogin(LPCXSTR lpszClientAddr, XSOCKET hSocket, XPVOID lParam)
{
@@ -57,6 +66,10 @@ void XCALLBACK MessageQueue_Callback_HttpLeave(LPCXSTR lpszClientAddr, XSOCKET h
{
XEngine_MQXService_Close(lpszClientAddr, XENGINE_MQAPP_NETTYPE_HTTP, false);
}
+void XCALLBACK MessageQueue_Client_HttpHeart(LPCXSTR lpszClientAddr, XSOCKET hSocket, int nStatus, XPVOID lParam)
+{
+ XEngine_MQXService_Close(lpszClientAddr, XENGINE_MQAPP_NETTYPE_HTTP, true);
+}
//////////////////////////////////////////////////////////////////////////
bool XCALLBACK MessageQueue_Callback_WSLogin(LPCXSTR lpszClientAddr, XSOCKET hSocket, XPVOID lParam)
{
@@ -92,6 +105,10 @@ void XCALLBACK MessageQueue_Callback_WSLeave(LPCXSTR lpszClientAddr, XSOCKET hSo
{
XEngine_MQXService_Close(lpszClientAddr, XENGINE_MQAPP_NETTYPE_WEBSOCKET, false);
}
+void XCALLBACK MessageQueue_Client_WSHeart(LPCXSTR lpszClientAddr, XSOCKET hSocket, int nStatus, XPVOID lParam)
+{
+ XEngine_MQXService_Close(lpszClientAddr, XENGINE_MQAPP_NETTYPE_WEBSOCKET, true);
+}
//////////////////////////////////////////////////////////////////////////
void XEngine_MQXService_Close(LPCXSTR lpszClientAddr, int nIPProto, bool bHeart)
{
@@ -102,7 +119,7 @@ void XEngine_MQXService_Close(LPCXSTR lpszClientAddr, int nIPProto, bool bHeart)
{
NetCore_TCPXCore_CloseForClientEx(xhTCPSocket, lpszClientAddr);
}
- XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _X("TCP客户端离开,TCP客户端地址:%s"), lpszClientAddr);
+ XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _X("TCP客户端离开,TCP客户端地址:%s,心跳标记:%d"), lpszClientAddr, bHeart);
}
else if (XENGINE_MQAPP_NETTYPE_WEBSOCKET == nIPProto)
{
@@ -111,7 +128,7 @@ void XEngine_MQXService_Close(LPCXSTR lpszClientAddr, int nIPProto, bool bHeart)
{
NetCore_TCPXCore_CloseForClientEx(xhWSSocket, lpszClientAddr);
}
- XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _X("Websocket客户端离开,Websocket客户端地址:%s"), lpszClientAddr);
+ XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _X("Websocket客户端离开,Websocket客户端地址:%s,心跳标记:%d"), lpszClientAddr, bHeart);
}
else if (XENGINE_MQAPP_NETTYPE_HTTP == nIPProto)
{
@@ -120,7 +137,7 @@ void XEngine_MQXService_Close(LPCXSTR lpszClientAddr, int nIPProto, bool bHeart)
{
NetCore_TCPXCore_CloseForClientEx(xhHTTPSocket, lpszClientAddr);
}
- XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _X("HTTP客户端离开,HTTP客户端地址:%s"), lpszClientAddr);
+ XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _X("HTTP客户端离开,HTTP客户端地址:%s,心跳标记:%d"), lpszClientAddr, bHeart);
}
else
{
@@ -129,7 +146,7 @@ void XEngine_MQXService_Close(LPCXSTR lpszClientAddr, int nIPProto, bool bHeart)
{
NetCore_TCPXCore_CloseForClientEx(xhMQTTSocket, lpszClientAddr);
}
- XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _X("MQTT客户端离开,MQTT客户端地址:%s"), lpszClientAddr);
+ XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _X("MQTT客户端离开,MQTT客户端地址:%s,心跳标记:%d"), lpszClientAddr, bHeart);
}
XENGINE_PROTOCOL_USERINFO st_UserInfo;
memset(&st_UserInfo, '\0', sizeof(XENGINE_PROTOCOL_USERINFO));
diff --git a/XEngine_Source/XEngine_MQServiceApp/MQService_Net.h b/XEngine_Source/XEngine_MQServiceApp/MQService_Net.h
index 723b1dd..f16603d 100644
--- a/XEngine_Source/XEngine_MQServiceApp/MQService_Net.h
+++ b/XEngine_Source/XEngine_MQServiceApp/MQService_Net.h
@@ -3,18 +3,22 @@
bool XCALLBACK MessageQueue_Callback_TCPLogin(LPCXSTR lpszClientAddr, XSOCKET hSocket, XPVOID lParam); //用户连接
void XCALLBACK MessageQueue_Callback_TCPRecv(LPCXSTR lpszClientAddr, XSOCKET hSocket, LPCXSTR lpszRecvMsg,int nMsgLen,XPVOID lParam); //接受到数据
void XCALLBACK MessageQueue_Callback_TCPLeave(LPCXSTR lpszClientAddr, XSOCKET hSocket, XPVOID lParam); //用户离开
+void XCALLBACK MessageQueue_Client_TCPHeart(LPCXSTR lpszClientAddr, XSOCKET hSocket, int nStatus, XPVOID lParam);
bool XCALLBACK MessageQueue_Callback_MQTTLogin(LPCXSTR lpszClientAddr, XSOCKET hSocket, XPVOID lParam);
void XCALLBACK MessageQueue_Callback_MQTTRecv(LPCXSTR lpszClientAddr, XSOCKET hSocket, LPCXSTR lpszRecvMsg, int nMsgLen, XPVOID lParam);
void XCALLBACK MessageQueue_Callback_MQTTLeave(LPCXSTR lpszClientAddr, XSOCKET hSocket, XPVOID lParam);
+void XCALLBACK MessageQueue_Client_MQTTHeart(LPCXSTR lpszClientAddr, XSOCKET hSocket, int nStatus, XPVOID lParam);
bool XCALLBACK MessageQueue_Callback_HttpLogin(LPCXSTR lpszClientAddr, XSOCKET hSocket, XPVOID lParam);
void XCALLBACK MessageQueue_Callback_HttpRecv(LPCXSTR lpszClientAddr, XSOCKET hSocket, LPCXSTR lpszRecvMsg, int nMsgLen, XPVOID lParam);
void XCALLBACK MessageQueue_Callback_HttpLeave(LPCXSTR lpszClientAddr, XSOCKET hSocket, XPVOID lParam);
+void XCALLBACK MessageQueue_Client_HttpHeart(LPCXSTR lpszClientAddr, XSOCKET hSocket, int nStatus, XPVOID lParam);
bool XCALLBACK MessageQueue_Callback_WSLogin(LPCXSTR lpszClientAddr, XSOCKET hSocket, XPVOID lParam);
void XCALLBACK MessageQueue_Callback_WSRecv(LPCXSTR lpszClientAddr, XSOCKET hSocket, LPCXSTR lpszRecvMsg, int nMsgLen, XPVOID lParam);
void XCALLBACK MessageQueue_Callback_WSLeave(LPCXSTR lpszClientAddr, XSOCKET hSocket, XPVOID lParam);
+void XCALLBACK MessageQueue_Client_WSHeart(LPCXSTR lpszClientAddr, XSOCKET hSocket, int nStatus, XPVOID lParam);
void XEngine_MQXService_Close(LPCXSTR lpszClientAddr, int nIPProto, bool bHeart);
bool XEngine_MQXService_Send(LPCXSTR lpszClientAddr, LPCXSTR lpszMsgBuffer, int nMsgLen, int nIPProto, XENGINE_PROTOCOL_MSGATTR* pSt_MSGAttr = NULL, LPCXSTR lpszUserName = NULL);
\ No newline at end of file
diff --git a/XEngine_Source/XEngine_MQServiceApp/MQService_TCPTask.cpp b/XEngine_Source/XEngine_MQServiceApp/MQService_TCPTask.cpp
index afbb92b..ba93698 100644
--- a/XEngine_Source/XEngine_MQServiceApp/MQService_TCPTask.cpp
+++ b/XEngine_Source/XEngine_MQServiceApp/MQService_TCPTask.cpp
@@ -314,6 +314,7 @@ bool MessageQueue_TCP_Handle(XENGINE_PROTOCOLHDR* pSt_ProtocolHdr, LPCXSTR lpszC
//可能为空表
st_DBQueue.nQueueSerial = 1;
}
+ st_MQProtocol.nSerial = st_DBQueue.nQueueSerial;
APIHelp_Counter_SerialSet(st_DBQueue.tszQueueName, st_DBQueue.nQueueSerial);
}
}
diff --git a/XEngine_Source/XEngine_MQServiceApp/XEngine_MQServiceApp.cpp b/XEngine_Source/XEngine_MQServiceApp/XEngine_MQServiceApp.cpp
index 519d604..e3cdb87 100644
--- a/XEngine_Source/XEngine_MQServiceApp/XEngine_MQServiceApp.cpp
+++ b/XEngine_Source/XEngine_MQServiceApp/XEngine_MQServiceApp.cpp
@@ -8,6 +8,11 @@ XHANDLE xhHTTPSocket = NULL;
XHANDLE xhWSSocket = NULL;
XHANDLE xhMQTTSocket = NULL;
+XHANDLE xhTCPHeart = NULL;
+XHANDLE xhHTTPHeart = NULL;
+XHANDLE xhWSHeart = NULL;
+XHANDLE xhMQTTHeart = NULL;
+
XHANDLE xhTCPPacket = NULL;
XHANDLE xhHTTPPacket = NULL;
XHANDLE xhWSPacket = NULL;
@@ -32,12 +37,17 @@ void ServiceApp_Stop(int signo)
HttpProtocol_Server_DestroyEx(xhHTTPPacket);
RfcComponents_WSPacket_DestoryEx(xhWSPacket);
MQTTProtocol_Parse_Destory();
-
+
NetCore_TCPXCore_DestroyEx(xhTCPSocket);
NetCore_TCPXCore_DestroyEx(xhHTTPSocket);
NetCore_TCPXCore_DestroyEx(xhWSSocket);
NetCore_TCPXCore_DestroyEx(xhMQTTSocket);
+ SocketOpt_HeartBeat_DestoryEx(xhTCPHeart);
+ SocketOpt_HeartBeat_DestoryEx(xhWSHeart);
+ SocketOpt_HeartBeat_DestoryEx(xhHTTPHeart);
+ SocketOpt_HeartBeat_DestoryEx(xhMQTTHeart);
+
ManagePool_Thread_NQDestroy(xhTCPPool);
ManagePool_Thread_NQDestroy(xhHttpPool);
ManagePool_Thread_NQDestroy(xhWSPool);
@@ -112,14 +122,23 @@ LONG WINAPI Coredump_ExceptionFilter(EXCEPTION_POINTERS* pExceptionPointers)
}
#endif
+// Application entry point.
+// Responsibilities:
+// 1) Perform platform-specific runtime initialization.
+// 2) Initialize service components (logging/network/protocol workers).
+// 3) Start and monitor the service lifecycle until shutdown.
+// 4) Release resources in reverse order on exit paths.
int main(int argc, char** argv)
{
#ifdef _WINDOWS
+ // Windows-only socket runtime initialization.
WSADATA st_WSAData;
WSAStartup(MAKEWORD(2, 2), &st_WSAData);
+ // Register crash handler to generate minidump for post-mortem analysis.
SetUnhandledExceptionFilter(Coredump_ExceptionFilter);
#ifndef _DEBUG
+ // Force UTF-8 locale in non-debug mode to keep runtime text handling consistent.
if (setlocale(LC_ALL, ".UTF8") == NULL)
{
fprintf(stderr, "Error setting locale.\n");
@@ -253,6 +272,21 @@ int main(int argc, char** argv)
XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _X("启动服务中,启动TCP网络服务器成功,TCP端口:%d,IO:%d"), st_ServiceCfg.nTCPPort, st_ServiceCfg.st_XMax.nIOThread);
NetCore_TCPXCore_RegisterCallBackEx(xhTCPSocket, MessageQueue_Callback_TCPLogin, MessageQueue_Callback_TCPRecv, MessageQueue_Callback_TCPLeave);
XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _X("启动服务中,注册TCP网络事件成功"));
+
+ if (st_ServiceCfg.st_XTime.nTCPTime > 0)
+ {
+ xhTCPHeart = SocketOpt_HeartBeat_InitEx(st_ServiceCfg.st_XTime.nHeartCheck, st_ServiceCfg.st_XTime.nTCPTime, MessageQueue_Client_TCPHeart);
+ if (NULL == xhTCPHeart)
+ {
+ XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("启动服务中,初始化TCP验证心跳服务失败,错误:%lX"), NetCore_GetLastError());
+ goto XENGINE_APPEXIST;
+ }
+ XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _X("启动服务中,初始化TCP验证心跳服务成功,检测次数:%d,检测时间:%d"), st_ServiceCfg.st_XTime.nHeartCheck, st_ServiceCfg.st_XTime.nTCPTime);
+ }
+ else
+ {
+ XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_WARN, _X("启动服务中,检测到TCP心跳服务没有启用"));
+ }
//任务池
BaseLib_Memory_Malloc((XPPPMEM)&ppSt_ListTCPParam, st_ServiceCfg.st_XMax.nTCPThread, sizeof(THREADPOOL_PARAMENT));
for (int i = 0; i < st_ServiceCfg.st_XMax.nTCPThread; i++)
@@ -296,6 +330,21 @@ int main(int argc, char** argv)
NetCore_TCPXCore_RegisterCallBackEx(xhHTTPSocket, MessageQueue_Callback_HttpLogin, MessageQueue_Callback_HttpRecv, MessageQueue_Callback_HttpLeave);
XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _X("启动服务中,注册HTTP网络事件成功"));
+ if (st_ServiceCfg.st_XTime.nHTTPTime > 0)
+ {
+ xhHTTPHeart = SocketOpt_HeartBeat_InitEx(st_ServiceCfg.st_XTime.nHeartCheck, st_ServiceCfg.st_XTime.nHTTPTime, MessageQueue_Client_HttpHeart);
+ if (NULL == xhHTTPHeart)
+ {
+ XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("启动服务中,初始化HTTP心跳服务失败,错误:%lX"), NetCore_GetLastError());
+ goto XENGINE_APPEXIST;
+ }
+ XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _X("启动服务中,初始化HTTP心跳服务成功,检测次数:%d,检测时间:%d"), st_ServiceCfg.st_XTime.nHeartCheck, st_ServiceCfg.st_XTime.nHTTPTime);
+ }
+ else
+ {
+ XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_WARN, _X("启动服务中,检测到HTTP心跳服务没有启用"));
+ }
+
BaseLib_Memory_Malloc((XPPPMEM)&ppSt_ListHTTPParam, st_ServiceCfg.st_XMax.nHttpThread, sizeof(THREADPOOL_PARAMENT));
for (int i = 0; i < st_ServiceCfg.st_XMax.nHttpThread; i++)
{
@@ -338,6 +387,21 @@ int main(int argc, char** argv)
NetCore_TCPXCore_RegisterCallBackEx(xhWSSocket, MessageQueue_Callback_WSLogin, MessageQueue_Callback_WSRecv, MessageQueue_Callback_WSLeave);
XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _X("启动服务中,注册Websocket网络事件成功"));
+ if (st_ServiceCfg.st_XTime.nWSTime > 0)
+ {
+ xhWSHeart = SocketOpt_HeartBeat_InitEx(st_ServiceCfg.st_XTime.nHeartCheck, st_ServiceCfg.st_XTime.nWSTime, MessageQueue_Client_WSHeart);
+ if (NULL == xhWSHeart)
+ {
+ XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("启动服务中,初始化WEBSOCKET验证心跳服务失败,错误:%lX"), NetCore_GetLastError());
+ goto XENGINE_APPEXIST;
+ }
+ XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _X("启动服务中,初始化WEBSOCKET验证心跳服务成功,检测次数:%d,检测时间:%d"), st_ServiceCfg.st_XTime.nHeartCheck, st_ServiceCfg.st_XTime.nWSTime);
+ }
+ else
+ {
+ XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_WARN, _X("启动服务中,检测到WEBSOCKET心跳服务没有启用"));
+ }
+
BaseLib_Memory_Malloc((XPPPMEM)&ppSt_ListWSParam, st_ServiceCfg.st_XMax.nWSThread, sizeof(THREADPOOL_PARAMENT));
for (int i = 0; i < st_ServiceCfg.st_XMax.nWSThread; i++)
{
@@ -379,6 +443,21 @@ int main(int argc, char** argv)
NetCore_TCPXCore_RegisterCallBackEx(xhMQTTSocket, MessageQueue_Callback_MQTTLogin, MessageQueue_Callback_MQTTRecv, MessageQueue_Callback_MQTTLeave);
XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _X("启动服务中,注册MQTT网络事件成功"));
+ if (st_ServiceCfg.st_XTime.nMQTime > 0)
+ {
+ xhMQTTHeart = SocketOpt_HeartBeat_InitEx(st_ServiceCfg.st_XTime.nHeartCheck, st_ServiceCfg.st_XTime.nMQTime, MessageQueue_Client_MQTTHeart);
+ if (NULL == xhMQTTHeart)
+ {
+ XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_ERROR, _X("启动服务中,初始化MQTT心跳服务失败,错误:%lX"), NetCore_GetLastError());
+ goto XENGINE_APPEXIST;
+ }
+ XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_INFO, _X("启动服务中,初始化MQTT心跳服务成功,检测次数:%d,检测时间:%d"), st_ServiceCfg.st_XTime.nHeartCheck, st_ServiceCfg.st_XTime.nMQTime);
+ }
+ else
+ {
+ XLOG_PRINT(xhLog, XENGINE_HELPCOMPONENTS_XLOG_IN_LOGLEVEL_WARN, _X("启动服务中,检测到MQTT心跳服务没有启用"));
+ }
+
BaseLib_Memory_Malloc((XPPPMEM)&ppSt_ListMQTTParam, st_ServiceCfg.st_XMax.nMQTTThread, sizeof(THREADPOOL_PARAMENT));
for (int i = 0; i < st_ServiceCfg.st_XMax.nMQTTThread; i++)
{
diff --git a/XEngine_Source/XEngine_MQServiceApp/XEngine_MQServiceApp.vcxproj b/XEngine_Source/XEngine_MQServiceApp/XEngine_MQServiceApp.vcxproj
index 63e0c4d..4a7ebfb 100644
--- a/XEngine_Source/XEngine_MQServiceApp/XEngine_MQServiceApp.vcxproj
+++ b/XEngine_Source/XEngine_MQServiceApp/XEngine_MQServiceApp.vcxproj
@@ -37,39 +37,39 @@
Application
true
- v143
+ v145
Unicode
Application
false
- v143
+ v145
true
Unicode
Application
true
- v143
+ v145
Unicode
Application
true
- v143
+ v145
Unicode
Application
false
- v143
+ v145
true
Unicode
Application
false
- v143
+ v145
true
Unicode
@@ -150,7 +150,7 @@
true
WIN32;NDEBUG;_CONSOLE;_WINDOWS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
true
- MultiThreaded
+ MultiThreadedDLL
4819
stdcpp20
stdc17
@@ -199,7 +199,7 @@
true
WIN64;NDEBUG;_CONSOLE;_WINDOWS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
true
- MultiThreaded
+ MultiThreadedDLL
4819
stdcpp20
stdc17