@plainconceptsplatform/workflows 1.3.0 → 1.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/loops/actions/add-issue-labels/action.yml +50 -50
- package/loops/actions/agent-output.cjs +17 -17
- package/loops/actions/apply-agent-bundle/action.yml +24 -24
- package/loops/actions/apply-agent-comments/action.yml +42 -42
- package/loops/actions/apply-agent-labels/action.yml +55 -55
- package/loops/actions/apply-agent-output/action.yml +108 -108
- package/loops/actions/cleanup-artifacts/action.yml +91 -91
- package/loops/actions/close-agent-issues/action.yml +43 -43
- package/loops/actions/create-agent-issues/action.yml +52 -52
- package/loops/actions/create-issue-comment/action.yml +29 -29
- package/loops/actions/download-agent-output/action.yml +53 -53
- package/loops/actions/link-pr-to-issue/action.yml +40 -40
- package/loops/actions/list-open-issues/action.yml +33 -33
- package/loops/actions/load-issue-context/action.yml +45 -45
- package/loops/actions/merge-agent-pr/action.yml +49 -49
- package/loops/actions/push-agent-branch/action.yml +45 -45
- package/loops/actions/remove-issue-labels/action.yml +37 -37
- package/loops/actions/update-agent-issues/action.yml +58 -58
- package/loops/actions/validate-merge-gate-output/action.yml +6 -1
- package/loops/actions/validate-merge-gate-output/validate-merge-gate-output.sh +9 -2
- package/loops/actions/validate-review-output/action.yml +35 -35
- package/loops/actions/validate-triage-output/action.yml +36 -36
- package/loops/actions/verify-composite-actions/action.yml +9 -9
- package/loops/actions/verify-refine-output/action.yml +9 -9
- package/loops/actions/verify-route-matrix/action.yml +9 -9
- package/loops/actions/verify-route-matrix/verify-route-matrix.sh +10 -2
- package/loops/templates/agentics/agentics-maintenance.yml +121 -121
- package/loops/templates/issues/bug_report.yml +109 -109
- package/loops/templates/issues/feature_request.yml +75 -75
- package/loops/templates/release/github-release.yml +30 -30
- package/loops/workflows/agent-apply-review.md +5 -0
- package/loops/workflows/agent-implement.md +6 -0
- package/loops/workflows/agent-merge-gate.md +62 -2
- package/loops/workflows/authorize-bot-work.yml +105 -105
- package/loops/workflows/shared/platform-defaults.md +23 -23
- package/package.json +1 -1
|
@@ -1,33 +1,33 @@
|
|
|
1
|
-
# Managed by @plainconceptsplatform/workflows. Source: loops/actions/list-open-issues/action.yml. Update with workflows update --force; consumer edits may be overwritten.
|
|
2
|
-
name: List open issues
|
|
3
|
-
description: |
|
|
4
|
-
Writes all open issues (number, title, labels) to `/tmp/gh-aw/agent/open-issues.json`
|
|
5
|
-
so the agent can check for semantic duplicates without spending turns discovering them.
|
|
6
|
-
inputs:
|
|
7
|
-
token:
|
|
8
|
-
description: GitHub token with issues:read permission.
|
|
9
|
-
required: true
|
|
10
|
-
repo:
|
|
11
|
-
description: Repository in `owner/name` format.
|
|
12
|
-
required: true
|
|
13
|
-
output-path:
|
|
14
|
-
description: Path to write the JSON output.
|
|
15
|
-
required: false
|
|
16
|
-
default: /tmp/gh-aw/agent/open-issues.json
|
|
17
|
-
runs:
|
|
18
|
-
using: composite
|
|
19
|
-
steps:
|
|
20
|
-
- name: List open issues
|
|
21
|
-
shell: bash
|
|
22
|
-
env:
|
|
23
|
-
GH_TOKEN: ${{ inputs.token }}
|
|
24
|
-
REPO: ${{ inputs.repo }}
|
|
25
|
-
OUTPUT_PATH: ${{ inputs.output-path }}
|
|
26
|
-
run: |
|
|
27
|
-
set -euo pipefail
|
|
28
|
-
mkdir -p "$(dirname "$OUTPUT_PATH")"
|
|
29
|
-
gh issue list --repo "$REPO" --state open --limit 500 \
|
|
30
|
-
--json number,title,labels \
|
|
31
|
-
--jq '[.[] | {number, title, labels: [.labels[].name]}]' \
|
|
32
|
-
> "$OUTPUT_PATH"
|
|
33
|
-
echo "Wrote $(jq 'length' "$OUTPUT_PATH") open issues to $OUTPUT_PATH"
|
|
1
|
+
# Managed by @plainconceptsplatform/workflows. Source: loops/actions/list-open-issues/action.yml. Update with workflows update --force; consumer edits may be overwritten.
|
|
2
|
+
name: List open issues
|
|
3
|
+
description: |
|
|
4
|
+
Writes all open issues (number, title, labels) to `/tmp/gh-aw/agent/open-issues.json`
|
|
5
|
+
so the agent can check for semantic duplicates without spending turns discovering them.
|
|
6
|
+
inputs:
|
|
7
|
+
token:
|
|
8
|
+
description: GitHub token with issues:read permission.
|
|
9
|
+
required: true
|
|
10
|
+
repo:
|
|
11
|
+
description: Repository in `owner/name` format.
|
|
12
|
+
required: true
|
|
13
|
+
output-path:
|
|
14
|
+
description: Path to write the JSON output.
|
|
15
|
+
required: false
|
|
16
|
+
default: /tmp/gh-aw/agent/open-issues.json
|
|
17
|
+
runs:
|
|
18
|
+
using: composite
|
|
19
|
+
steps:
|
|
20
|
+
- name: List open issues
|
|
21
|
+
shell: bash
|
|
22
|
+
env:
|
|
23
|
+
GH_TOKEN: ${{ inputs.token }}
|
|
24
|
+
REPO: ${{ inputs.repo }}
|
|
25
|
+
OUTPUT_PATH: ${{ inputs.output-path }}
|
|
26
|
+
run: |
|
|
27
|
+
set -euo pipefail
|
|
28
|
+
mkdir -p "$(dirname "$OUTPUT_PATH")"
|
|
29
|
+
gh issue list --repo "$REPO" --state open --limit 500 \
|
|
30
|
+
--json number,title,labels \
|
|
31
|
+
--jq '[.[] | {number, title, labels: [.labels[].name]}]' \
|
|
32
|
+
> "$OUTPUT_PATH"
|
|
33
|
+
echo "Wrote $(jq 'length' "$OUTPUT_PATH") open issues to $OUTPUT_PATH"
|
|
@@ -1,45 +1,45 @@
|
|
|
1
|
-
# Managed by @plainconceptsplatform/workflows. Source: loops/actions/load-issue-context/action.yml. Update with workflows update --force; consumer edits may be overwritten.
|
|
2
|
-
name: Load issue context
|
|
3
|
-
description: Write issue metadata and comment context to a JSON file.
|
|
4
|
-
inputs:
|
|
5
|
-
token:
|
|
6
|
-
description: GitHub token used by github-script.
|
|
7
|
-
required: true
|
|
8
|
-
issue-number:
|
|
9
|
-
description: Issue number to load.
|
|
10
|
-
required: true
|
|
11
|
-
output-path:
|
|
12
|
-
description: Absolute path where context JSON is written.
|
|
13
|
-
required: true
|
|
14
|
-
runs:
|
|
15
|
-
using: composite
|
|
16
|
-
steps:
|
|
17
|
-
- name: Load issue and comments
|
|
18
|
-
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
|
19
|
-
env:
|
|
20
|
-
ISSUE_NUMBER: ${{ inputs.issue-number }}
|
|
21
|
-
OUTPUT_PATH: ${{ inputs.output-path }}
|
|
22
|
-
with:
|
|
23
|
-
github-token: ${{ inputs.token }}
|
|
24
|
-
script: |
|
|
25
|
-
const fs = require('fs');
|
|
26
|
-
const issueNumber = Number(process.env.ISSUE_NUMBER);
|
|
27
|
-
const issue = await github.rest.issues.get({ ...context.repo, issue_number: issueNumber });
|
|
28
|
-
const comments = await github.paginate(github.rest.issues.listComments, {
|
|
29
|
-
...context.repo, issue_number: issueNumber, per_page: 100,
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
fs.mkdirSync(require('path').dirname(process.env.OUTPUT_PATH), { recursive: true });
|
|
33
|
-
fs.writeFileSync(process.env.OUTPUT_PATH, JSON.stringify({
|
|
34
|
-
number: issue.data.number,
|
|
35
|
-
title: issue.data.title,
|
|
36
|
-
body: issue.data.body,
|
|
37
|
-
author: issue.data.user.login,
|
|
38
|
-
authorAssociation: issue.data.author_association,
|
|
39
|
-
labels: issue.data.labels.map(({ name }) => name),
|
|
40
|
-
comments: comments.map(({ user, author_association, body }) => ({
|
|
41
|
-
author: user.login,
|
|
42
|
-
association: author_association,
|
|
43
|
-
body,
|
|
44
|
-
})),
|
|
45
|
-
}, null, 2));
|
|
1
|
+
# Managed by @plainconceptsplatform/workflows. Source: loops/actions/load-issue-context/action.yml. Update with workflows update --force; consumer edits may be overwritten.
|
|
2
|
+
name: Load issue context
|
|
3
|
+
description: Write issue metadata and comment context to a JSON file.
|
|
4
|
+
inputs:
|
|
5
|
+
token:
|
|
6
|
+
description: GitHub token used by github-script.
|
|
7
|
+
required: true
|
|
8
|
+
issue-number:
|
|
9
|
+
description: Issue number to load.
|
|
10
|
+
required: true
|
|
11
|
+
output-path:
|
|
12
|
+
description: Absolute path where context JSON is written.
|
|
13
|
+
required: true
|
|
14
|
+
runs:
|
|
15
|
+
using: composite
|
|
16
|
+
steps:
|
|
17
|
+
- name: Load issue and comments
|
|
18
|
+
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
|
19
|
+
env:
|
|
20
|
+
ISSUE_NUMBER: ${{ inputs.issue-number }}
|
|
21
|
+
OUTPUT_PATH: ${{ inputs.output-path }}
|
|
22
|
+
with:
|
|
23
|
+
github-token: ${{ inputs.token }}
|
|
24
|
+
script: |
|
|
25
|
+
const fs = require('fs');
|
|
26
|
+
const issueNumber = Number(process.env.ISSUE_NUMBER);
|
|
27
|
+
const issue = await github.rest.issues.get({ ...context.repo, issue_number: issueNumber });
|
|
28
|
+
const comments = await github.paginate(github.rest.issues.listComments, {
|
|
29
|
+
...context.repo, issue_number: issueNumber, per_page: 100,
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
fs.mkdirSync(require('path').dirname(process.env.OUTPUT_PATH), { recursive: true });
|
|
33
|
+
fs.writeFileSync(process.env.OUTPUT_PATH, JSON.stringify({
|
|
34
|
+
number: issue.data.number,
|
|
35
|
+
title: issue.data.title,
|
|
36
|
+
body: issue.data.body,
|
|
37
|
+
author: issue.data.user.login,
|
|
38
|
+
authorAssociation: issue.data.author_association,
|
|
39
|
+
labels: issue.data.labels.map(({ name }) => name),
|
|
40
|
+
comments: comments.map(({ user, author_association, body }) => ({
|
|
41
|
+
author: user.login,
|
|
42
|
+
association: author_association,
|
|
43
|
+
body,
|
|
44
|
+
})),
|
|
45
|
+
}, null, 2));
|
|
@@ -1,49 +1,49 @@
|
|
|
1
|
-
# Managed by @plainconceptsplatform/workflows. Source: loops/actions/merge-agent-pr/action.yml. Update with workflows update --force; consumer edits may be overwritten.
|
|
2
|
-
name: Merge agent pull request
|
|
3
|
-
description: Read merge_pull_request from agent_output.json and merge the PR via gh.
|
|
4
|
-
inputs:
|
|
5
|
-
output-file:
|
|
6
|
-
description: Path to agent_output.json.
|
|
7
|
-
required: true
|
|
8
|
-
token:
|
|
9
|
-
description: GitHub token with pull-requests:write and contents:write.
|
|
10
|
-
required: true
|
|
11
|
-
repo:
|
|
12
|
-
description: Target repository in owner/name format.
|
|
13
|
-
required: false
|
|
14
|
-
default: ${{ github.repository }}
|
|
15
|
-
runs:
|
|
16
|
-
using: composite
|
|
17
|
-
steps:
|
|
18
|
-
- name: Merge pull request
|
|
19
|
-
shell: bash
|
|
20
|
-
env:
|
|
21
|
-
GH_TOKEN: ${{ inputs.token }}
|
|
22
|
-
OUTPUT_FILE: ${{ inputs.output-file }}
|
|
23
|
-
REPO: ${{ inputs.repo }}
|
|
24
|
-
run: |
|
|
25
|
-
set -euo pipefail
|
|
26
|
-
[ -f "$OUTPUT_FILE" ] || exit 0
|
|
27
|
-
|
|
28
|
-
jq -c '.items[] | select(.type == "merge_pull_request")' "$OUTPUT_FILE" | while read -r item; do
|
|
29
|
-
PR_NUM=$(echo "$item" | jq -er '.pr_number // .item_number // empty')
|
|
30
|
-
[[ "$PR_NUM" =~ ^[1-9][0-9]*$ ]] || { echo "::error::Invalid pull request number: $PR_NUM"; exit 1; }
|
|
31
|
-
|
|
32
|
-
HEAD_SHA=$(gh pr view "$PR_NUM" --repo "$REPO" --json headRefOid --jq '.headRefOid')
|
|
33
|
-
[[ "$HEAD_SHA" =~ ^[0-9a-fA-F]{40}$ ]] || { echo "::error::Invalid pull request head SHA for #$PR_NUM"; exit 1; }
|
|
34
|
-
|
|
35
|
-
HEAD_REF=$(gh pr view "$PR_NUM" --repo "$REPO" --json headRefName --jq '.headRefName')
|
|
36
|
-
|
|
37
|
-
gh pr merge "$PR_NUM" --repo "$REPO" --squash --match-head-commit "$HEAD_SHA"
|
|
38
|
-
|
|
39
|
-
# Delete the branch, because nothing else ever has: four repositories had accumulated
|
|
40
|
-
# 47 non-main branches, every one the head of a pull request merged or closed months
|
|
41
|
-
# ago. Done after the merge and with its failure swallowed rather than through
|
|
42
|
-
# `gh pr merge --delete-branch`, which also tries to delete the local branch and can
|
|
43
|
-
# turn a completed merge into a red step. `delete_branch_on_merge` on the repository
|
|
44
|
-
# does the same job, but only where someone remembered to switch it on.
|
|
45
|
-
if [ -n "$HEAD_REF" ] && [ "$HEAD_REF" != "null" ]; then
|
|
46
|
-
gh api -X DELETE "repos/$REPO/git/refs/heads/$HEAD_REF" >/dev/null 2>&1 ||
|
|
47
|
-
echo "::notice::branch $HEAD_REF was already gone or is protected"
|
|
48
|
-
fi
|
|
49
|
-
done
|
|
1
|
+
# Managed by @plainconceptsplatform/workflows. Source: loops/actions/merge-agent-pr/action.yml. Update with workflows update --force; consumer edits may be overwritten.
|
|
2
|
+
name: Merge agent pull request
|
|
3
|
+
description: Read merge_pull_request from agent_output.json and merge the PR via gh.
|
|
4
|
+
inputs:
|
|
5
|
+
output-file:
|
|
6
|
+
description: Path to agent_output.json.
|
|
7
|
+
required: true
|
|
8
|
+
token:
|
|
9
|
+
description: GitHub token with pull-requests:write and contents:write.
|
|
10
|
+
required: true
|
|
11
|
+
repo:
|
|
12
|
+
description: Target repository in owner/name format.
|
|
13
|
+
required: false
|
|
14
|
+
default: ${{ github.repository }}
|
|
15
|
+
runs:
|
|
16
|
+
using: composite
|
|
17
|
+
steps:
|
|
18
|
+
- name: Merge pull request
|
|
19
|
+
shell: bash
|
|
20
|
+
env:
|
|
21
|
+
GH_TOKEN: ${{ inputs.token }}
|
|
22
|
+
OUTPUT_FILE: ${{ inputs.output-file }}
|
|
23
|
+
REPO: ${{ inputs.repo }}
|
|
24
|
+
run: |
|
|
25
|
+
set -euo pipefail
|
|
26
|
+
[ -f "$OUTPUT_FILE" ] || exit 0
|
|
27
|
+
|
|
28
|
+
jq -c '.items[] | select(.type == "merge_pull_request")' "$OUTPUT_FILE" | while read -r item; do
|
|
29
|
+
PR_NUM=$(echo "$item" | jq -er '.pr_number // .item_number // empty')
|
|
30
|
+
[[ "$PR_NUM" =~ ^[1-9][0-9]*$ ]] || { echo "::error::Invalid pull request number: $PR_NUM"; exit 1; }
|
|
31
|
+
|
|
32
|
+
HEAD_SHA=$(gh pr view "$PR_NUM" --repo "$REPO" --json headRefOid --jq '.headRefOid')
|
|
33
|
+
[[ "$HEAD_SHA" =~ ^[0-9a-fA-F]{40}$ ]] || { echo "::error::Invalid pull request head SHA for #$PR_NUM"; exit 1; }
|
|
34
|
+
|
|
35
|
+
HEAD_REF=$(gh pr view "$PR_NUM" --repo "$REPO" --json headRefName --jq '.headRefName')
|
|
36
|
+
|
|
37
|
+
gh pr merge "$PR_NUM" --repo "$REPO" --squash --match-head-commit "$HEAD_SHA"
|
|
38
|
+
|
|
39
|
+
# Delete the branch, because nothing else ever has: four repositories had accumulated
|
|
40
|
+
# 47 non-main branches, every one the head of a pull request merged or closed months
|
|
41
|
+
# ago. Done after the merge and with its failure swallowed rather than through
|
|
42
|
+
# `gh pr merge --delete-branch`, which also tries to delete the local branch and can
|
|
43
|
+
# turn a completed merge into a red step. `delete_branch_on_merge` on the repository
|
|
44
|
+
# does the same job, but only where someone remembered to switch it on.
|
|
45
|
+
if [ -n "$HEAD_REF" ] && [ "$HEAD_REF" != "null" ]; then
|
|
46
|
+
gh api -X DELETE "repos/$REPO/git/refs/heads/$HEAD_REF" >/dev/null 2>&1 ||
|
|
47
|
+
echo "::notice::branch $HEAD_REF was already gone or is protected"
|
|
48
|
+
fi
|
|
49
|
+
done
|
|
@@ -1,45 +1,45 @@
|
|
|
1
|
-
# Managed by @plainconceptsplatform/workflows. Source: loops/actions/push-agent-branch/action.yml. Update with workflows update --force; consumer edits may be overwritten.
|
|
2
|
-
name: Push agent branch
|
|
3
|
-
description: Read push_to_pull_request_branch from agent_output.json and fast-forward from its git bundle.
|
|
4
|
-
inputs:
|
|
5
|
-
output-file:
|
|
6
|
-
description: Path to agent_output.json.
|
|
7
|
-
required: true
|
|
8
|
-
bundle-file:
|
|
9
|
-
description: Path to the git bundle from the agent artifact.
|
|
10
|
-
required: false
|
|
11
|
-
default: ''
|
|
12
|
-
token:
|
|
13
|
-
description: GitHub token with contents:write.
|
|
14
|
-
required: true
|
|
15
|
-
runs:
|
|
16
|
-
using: composite
|
|
17
|
-
steps:
|
|
18
|
-
- name: Configure git credentials
|
|
19
|
-
shell: bash
|
|
20
|
-
env:
|
|
21
|
-
GH_TOKEN: ${{ inputs.token }}
|
|
22
|
-
run: |
|
|
23
|
-
git config --global url."https://x-access-token:${GH_TOKEN}@github.com/".insteadOf "https://github.com/"
|
|
24
|
-
- name: Read pull request branch
|
|
25
|
-
id: request
|
|
26
|
-
shell: bash
|
|
27
|
-
env:
|
|
28
|
-
GH_TOKEN: ${{ inputs.token }}
|
|
29
|
-
OUTPUT_FILE: ${{ inputs.output-file }}
|
|
30
|
-
BUNDLE_FILE: ${{ inputs.bundle-file }}
|
|
31
|
-
run: |
|
|
32
|
-
set -euo pipefail
|
|
33
|
-
[ -f "$OUTPUT_FILE" ] || exit 0
|
|
34
|
-
|
|
35
|
-
ITEM=$(jq -c '.items[] | select(.type == "push_to_pull_request_branch")' "$OUTPUT_FILE")
|
|
36
|
-
[ -n "$ITEM" ] || exit 0
|
|
37
|
-
|
|
38
|
-
BRANCH=$(echo "$ITEM" | jq -r '.branch')
|
|
39
|
-
echo "branch=$BRANCH" >> "$GITHUB_OUTPUT"
|
|
40
|
-
- name: Apply bundle to pull request branch
|
|
41
|
-
if: steps.request.outputs.branch != '' && inputs.bundle-file != ''
|
|
42
|
-
uses: ./.github/actions/apply-agent-bundle
|
|
43
|
-
with:
|
|
44
|
-
bundle-file: ${{ inputs.bundle-file }}
|
|
45
|
-
target-branch: ${{ steps.request.outputs.branch }}
|
|
1
|
+
# Managed by @plainconceptsplatform/workflows. Source: loops/actions/push-agent-branch/action.yml. Update with workflows update --force; consumer edits may be overwritten.
|
|
2
|
+
name: Push agent branch
|
|
3
|
+
description: Read push_to_pull_request_branch from agent_output.json and fast-forward from its git bundle.
|
|
4
|
+
inputs:
|
|
5
|
+
output-file:
|
|
6
|
+
description: Path to agent_output.json.
|
|
7
|
+
required: true
|
|
8
|
+
bundle-file:
|
|
9
|
+
description: Path to the git bundle from the agent artifact.
|
|
10
|
+
required: false
|
|
11
|
+
default: ''
|
|
12
|
+
token:
|
|
13
|
+
description: GitHub token with contents:write.
|
|
14
|
+
required: true
|
|
15
|
+
runs:
|
|
16
|
+
using: composite
|
|
17
|
+
steps:
|
|
18
|
+
- name: Configure git credentials
|
|
19
|
+
shell: bash
|
|
20
|
+
env:
|
|
21
|
+
GH_TOKEN: ${{ inputs.token }}
|
|
22
|
+
run: |
|
|
23
|
+
git config --global url."https://x-access-token:${GH_TOKEN}@github.com/".insteadOf "https://github.com/"
|
|
24
|
+
- name: Read pull request branch
|
|
25
|
+
id: request
|
|
26
|
+
shell: bash
|
|
27
|
+
env:
|
|
28
|
+
GH_TOKEN: ${{ inputs.token }}
|
|
29
|
+
OUTPUT_FILE: ${{ inputs.output-file }}
|
|
30
|
+
BUNDLE_FILE: ${{ inputs.bundle-file }}
|
|
31
|
+
run: |
|
|
32
|
+
set -euo pipefail
|
|
33
|
+
[ -f "$OUTPUT_FILE" ] || exit 0
|
|
34
|
+
|
|
35
|
+
ITEM=$(jq -c '.items[] | select(.type == "push_to_pull_request_branch")' "$OUTPUT_FILE")
|
|
36
|
+
[ -n "$ITEM" ] || exit 0
|
|
37
|
+
|
|
38
|
+
BRANCH=$(echo "$ITEM" | jq -r '.branch')
|
|
39
|
+
echo "branch=$BRANCH" >> "$GITHUB_OUTPUT"
|
|
40
|
+
- name: Apply bundle to pull request branch
|
|
41
|
+
if: steps.request.outputs.branch != '' && inputs.bundle-file != ''
|
|
42
|
+
uses: ./.github/actions/apply-agent-bundle
|
|
43
|
+
with:
|
|
44
|
+
bundle-file: ${{ inputs.bundle-file }}
|
|
45
|
+
target-branch: ${{ steps.request.outputs.branch }}
|
|
@@ -1,37 +1,37 @@
|
|
|
1
|
-
# Managed by @plainconceptsplatform/workflows. Source: loops/actions/remove-issue-labels/action.yml. Update with workflows update --force; consumer edits may be overwritten.
|
|
2
|
-
name: Remove issue labels
|
|
3
|
-
description: Remove one or more labels from an issue or pull request.
|
|
4
|
-
inputs:
|
|
5
|
-
token:
|
|
6
|
-
description: GitHub token used by github-script.
|
|
7
|
-
required: true
|
|
8
|
-
issue-number:
|
|
9
|
-
description: Issue or pull request number.
|
|
10
|
-
required: true
|
|
11
|
-
labels:
|
|
12
|
-
description: Labels to remove, one per line. A comma-separated list is accepted as well.
|
|
13
|
-
required: true
|
|
14
|
-
runs:
|
|
15
|
-
using: composite
|
|
16
|
-
steps:
|
|
17
|
-
- name: Remove labels
|
|
18
|
-
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
|
19
|
-
env:
|
|
20
|
-
ISSUE_NUMBER: ${{ inputs.issue-number }}
|
|
21
|
-
LABELS: ${{ inputs.labels }}
|
|
22
|
-
with:
|
|
23
|
-
github-token: ${{ inputs.token }}
|
|
24
|
-
script: |
|
|
25
|
-
// Callers wrote `labels: a,b` while this split on newlines, so one label named "a,b"
|
|
26
|
-
// was removed: a 404, swallowed below, and neither label ever came off.
|
|
27
|
-
for (const label of process.env.LABELS.split(/\r?\n|,/).map((label) => label.trim()).filter(Boolean)) {
|
|
28
|
-
try {
|
|
29
|
-
await github.rest.issues.removeLabel({
|
|
30
|
-
...context.repo,
|
|
31
|
-
issue_number: Number(process.env.ISSUE_NUMBER),
|
|
32
|
-
name: label,
|
|
33
|
-
});
|
|
34
|
-
} catch (error) {
|
|
35
|
-
if (error.status !== 404) throw error;
|
|
36
|
-
}
|
|
37
|
-
}
|
|
1
|
+
# Managed by @plainconceptsplatform/workflows. Source: loops/actions/remove-issue-labels/action.yml. Update with workflows update --force; consumer edits may be overwritten.
|
|
2
|
+
name: Remove issue labels
|
|
3
|
+
description: Remove one or more labels from an issue or pull request.
|
|
4
|
+
inputs:
|
|
5
|
+
token:
|
|
6
|
+
description: GitHub token used by github-script.
|
|
7
|
+
required: true
|
|
8
|
+
issue-number:
|
|
9
|
+
description: Issue or pull request number.
|
|
10
|
+
required: true
|
|
11
|
+
labels:
|
|
12
|
+
description: Labels to remove, one per line. A comma-separated list is accepted as well.
|
|
13
|
+
required: true
|
|
14
|
+
runs:
|
|
15
|
+
using: composite
|
|
16
|
+
steps:
|
|
17
|
+
- name: Remove labels
|
|
18
|
+
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
|
19
|
+
env:
|
|
20
|
+
ISSUE_NUMBER: ${{ inputs.issue-number }}
|
|
21
|
+
LABELS: ${{ inputs.labels }}
|
|
22
|
+
with:
|
|
23
|
+
github-token: ${{ inputs.token }}
|
|
24
|
+
script: |
|
|
25
|
+
// Callers wrote `labels: a,b` while this split on newlines, so one label named "a,b"
|
|
26
|
+
// was removed: a 404, swallowed below, and neither label ever came off.
|
|
27
|
+
for (const label of process.env.LABELS.split(/\r?\n|,/).map((label) => label.trim()).filter(Boolean)) {
|
|
28
|
+
try {
|
|
29
|
+
await github.rest.issues.removeLabel({
|
|
30
|
+
...context.repo,
|
|
31
|
+
issue_number: Number(process.env.ISSUE_NUMBER),
|
|
32
|
+
name: label,
|
|
33
|
+
});
|
|
34
|
+
} catch (error) {
|
|
35
|
+
if (error.status !== 404) throw error;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -1,58 +1,58 @@
|
|
|
1
|
-
# Managed by @plainconceptsplatform/workflows. Source: loops/actions/update-agent-issues/action.yml. Update with workflows update --force; consumer edits may be overwritten.
|
|
2
|
-
name: Update agent issues
|
|
3
|
-
description: Apply every update_issue item from agent_output.json.
|
|
4
|
-
inputs:
|
|
5
|
-
output-file:
|
|
6
|
-
description: Path to agent_output.json.
|
|
7
|
-
required: true
|
|
8
|
-
token:
|
|
9
|
-
description: GitHub token with issues:write.
|
|
10
|
-
required: true
|
|
11
|
-
fallback-issue-number:
|
|
12
|
-
description: Issue an item targets when it names none.
|
|
13
|
-
required: false
|
|
14
|
-
default: ''
|
|
15
|
-
runs:
|
|
16
|
-
using: composite
|
|
17
|
-
steps:
|
|
18
|
-
- name: Update issues
|
|
19
|
-
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
|
20
|
-
env:
|
|
21
|
-
AGENT_OUTPUT_LIB: ${{ github.action_path }}/../agent-output.cjs
|
|
22
|
-
OUTPUT_FILE: ${{ inputs.output-file }}
|
|
23
|
-
FALLBACK_ISSUE_NUMBER: ${{ inputs.fallback-issue-number }}
|
|
24
|
-
with:
|
|
25
|
-
github-token: ${{ inputs.token }}
|
|
26
|
-
script: |
|
|
27
|
-
const { readAgentItems } = require(process.env.AGENT_OUTPUT_LIB);
|
|
28
|
-
const items = readAgentItems(process.env.OUTPUT_FILE, 'update_issue');
|
|
29
|
-
|
|
30
|
-
let updated = 0;
|
|
31
|
-
|
|
32
|
-
for (const item of items) {
|
|
33
|
-
const target = item.item_number ?? process.env.FALLBACK_ISSUE_NUMBER;
|
|
34
|
-
|
|
35
|
-
if (!target) {
|
|
36
|
-
core.warning(`update_issue item has no item_number and no fallback, skipping: ${JSON.stringify(item)}`);
|
|
37
|
-
continue;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
const changes = {};
|
|
41
|
-
if (item.title) changes.title = item.title;
|
|
42
|
-
if (item.body) changes.body = item.body;
|
|
43
|
-
|
|
44
|
-
if (Object.keys(changes).length === 0) {
|
|
45
|
-
core.warning(`update_issue item changes nothing, skipping: ${JSON.stringify(item)}`);
|
|
46
|
-
continue;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
await github.rest.issues.update({
|
|
50
|
-
...context.repo,
|
|
51
|
-
issue_number: Number(target),
|
|
52
|
-
...changes,
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
updated += 1;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
core.info(`Updated ${updated} issue(s).`);
|
|
1
|
+
# Managed by @plainconceptsplatform/workflows. Source: loops/actions/update-agent-issues/action.yml. Update with workflows update --force; consumer edits may be overwritten.
|
|
2
|
+
name: Update agent issues
|
|
3
|
+
description: Apply every update_issue item from agent_output.json.
|
|
4
|
+
inputs:
|
|
5
|
+
output-file:
|
|
6
|
+
description: Path to agent_output.json.
|
|
7
|
+
required: true
|
|
8
|
+
token:
|
|
9
|
+
description: GitHub token with issues:write.
|
|
10
|
+
required: true
|
|
11
|
+
fallback-issue-number:
|
|
12
|
+
description: Issue an item targets when it names none.
|
|
13
|
+
required: false
|
|
14
|
+
default: ''
|
|
15
|
+
runs:
|
|
16
|
+
using: composite
|
|
17
|
+
steps:
|
|
18
|
+
- name: Update issues
|
|
19
|
+
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
|
20
|
+
env:
|
|
21
|
+
AGENT_OUTPUT_LIB: ${{ github.action_path }}/../agent-output.cjs
|
|
22
|
+
OUTPUT_FILE: ${{ inputs.output-file }}
|
|
23
|
+
FALLBACK_ISSUE_NUMBER: ${{ inputs.fallback-issue-number }}
|
|
24
|
+
with:
|
|
25
|
+
github-token: ${{ inputs.token }}
|
|
26
|
+
script: |
|
|
27
|
+
const { readAgentItems } = require(process.env.AGENT_OUTPUT_LIB);
|
|
28
|
+
const items = readAgentItems(process.env.OUTPUT_FILE, 'update_issue');
|
|
29
|
+
|
|
30
|
+
let updated = 0;
|
|
31
|
+
|
|
32
|
+
for (const item of items) {
|
|
33
|
+
const target = item.item_number ?? process.env.FALLBACK_ISSUE_NUMBER;
|
|
34
|
+
|
|
35
|
+
if (!target) {
|
|
36
|
+
core.warning(`update_issue item has no item_number and no fallback, skipping: ${JSON.stringify(item)}`);
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const changes = {};
|
|
41
|
+
if (item.title) changes.title = item.title;
|
|
42
|
+
if (item.body) changes.body = item.body;
|
|
43
|
+
|
|
44
|
+
if (Object.keys(changes).length === 0) {
|
|
45
|
+
core.warning(`update_issue item changes nothing, skipping: ${JSON.stringify(item)}`);
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
await github.rest.issues.update({
|
|
50
|
+
...context.repo,
|
|
51
|
+
issue_number: Number(target),
|
|
52
|
+
...changes,
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
updated += 1;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
core.info(`Updated ${updated} issue(s).`);
|
|
@@ -27,6 +27,10 @@ inputs:
|
|
|
27
27
|
description: Agent confidence below which the pull request goes to a human.
|
|
28
28
|
required: false
|
|
29
29
|
default: '0.8'
|
|
30
|
+
code-rules:
|
|
31
|
+
description: "check-diff result on the pull request: pass, fail or absent. Empty means it did not report."
|
|
32
|
+
required: false
|
|
33
|
+
default: absent
|
|
30
34
|
outputs:
|
|
31
35
|
valid:
|
|
32
36
|
description: Whether the output produced a usable disposition.
|
|
@@ -48,12 +52,13 @@ runs:
|
|
|
48
52
|
PROTECTED_HIT: ${{ inputs.protected-hit }}
|
|
49
53
|
OWNER_HIT: ${{ inputs.owner-hit }}
|
|
50
54
|
CONFIDENCE_THRESHOLD: ${{ inputs.confidence-threshold }}
|
|
55
|
+
CODE_RULES: ${{ inputs.code-rules }}
|
|
51
56
|
run: |
|
|
52
57
|
set -euo pipefail
|
|
53
58
|
|
|
54
59
|
outcome="$(bash "${{ github.action_path }}/validate-merge-gate-output.sh" \
|
|
55
60
|
"$OUTPUT_FILE" "$ISSUE_NUMBER" "$CI_CONCLUSION" \
|
|
56
|
-
"$BLAST_LEVEL" "$PROTECTED_HIT" "$OWNER_HIT" "$CONFIDENCE_THRESHOLD")"
|
|
61
|
+
"$BLAST_LEVEL" "$PROTECTED_HIT" "$OWNER_HIT" "$CONFIDENCE_THRESHOLD" "$CODE_RULES")"
|
|
57
62
|
echo "outcome=$outcome" >> "$GITHUB_OUTPUT"
|
|
58
63
|
echo "valid=$([ "$outcome" != 'invalid' ] && echo true || echo false)" >> "$GITHUB_OUTPUT"
|
|
59
64
|
|
|
@@ -18,7 +18,8 @@
|
|
|
18
18
|
#
|
|
19
19
|
# Usage:
|
|
20
20
|
# validate-merge-gate-output.sh OUTPUT_FILE ISSUE CI_CONCLUSION \
|
|
21
|
-
# BLAST_LEVEL PROTECTED_HIT OWNER_HIT CONFIDENCE_THRESHOLD
|
|
21
|
+
# BLAST_LEVEL PROTECTED_HIT OWNER_HIT CONFIDENCE_THRESHOLD \
|
|
22
|
+
# CODE_RULES
|
|
22
23
|
|
|
23
24
|
set -euo pipefail
|
|
24
25
|
|
|
@@ -33,6 +34,9 @@ blast_level="${4-low}"
|
|
|
33
34
|
protected_hit="${5-false}"
|
|
34
35
|
owner_hit="${6-false}"
|
|
35
36
|
confidence_threshold="${7-0.8}"
|
|
37
|
+
# pass, fail or absent (the repository has no check-diff). An empty value is a job that did not
|
|
38
|
+
# report, and like every other unmeasured fact it goes to a person.
|
|
39
|
+
code_rules="${8-absent}"
|
|
36
40
|
|
|
37
41
|
# An empty measured level is not a low-risk pull request, it is a job that did not report. The
|
|
38
42
|
# defaults above exist for a caller that genuinely has nothing to say; an empty string arriving
|
|
@@ -56,7 +60,8 @@ jq -r \
|
|
|
56
60
|
--arg blast "$blast_level" \
|
|
57
61
|
--arg protected "$protected_hit" \
|
|
58
62
|
--arg owner "$owner_hit" \
|
|
59
|
-
--arg threshold "$confidence_threshold"
|
|
63
|
+
--arg threshold "$confidence_threshold" \
|
|
64
|
+
--arg code "$code_rules" '
|
|
60
65
|
|
|
61
66
|
def level_rank: {"low": 0, "medium": 1, "high": 2}[.];
|
|
62
67
|
def is_bool: type == "boolean";
|
|
@@ -143,11 +148,13 @@ jq -r \
|
|
|
143
148
|
|
|
144
149
|
| if $conclusion != "success" then "blocked"
|
|
145
150
|
elif $blockers > 0 then "blocked"
|
|
151
|
+
elif $code == "fail" then "blocked"
|
|
146
152
|
elif $protected == "true" or $owner == "true" or $level == 2 then "owner-review"
|
|
147
153
|
# A fact the workflow could not measure is not a fact. Anything other than a
|
|
148
154
|
# clean true or false here means protected_changes did not report, and the
|
|
149
155
|
# pull request goes to a person rather than through on a default.
|
|
150
156
|
elif $protected != "false" or $owner != "false" then "human-review"
|
|
157
|
+
elif $code != "pass" and $code != "absent" then "human-review"
|
|
151
158
|
elif $level == 1 and $recoverability == "low" then "human-review"
|
|
152
159
|
elif ($report | has("acceptanceCriteriaMet")) and $report.acceptanceCriteriaMet == false then "human-review"
|
|
153
160
|
elif $confidence < ($threshold | tonumber) then "human-review"
|