@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,91 +1,91 @@
|
|
|
1
|
-
# Managed by @plainconceptsplatform/workflows. Source: loops/actions/cleanup-artifacts/action.yml. Update with workflows update --force; consumer edits may be overwritten.
|
|
2
|
-
name: Clean up artifacts
|
|
3
|
-
description: Delete workflow artifacts older than the configured retention period.
|
|
4
|
-
inputs:
|
|
5
|
-
token:
|
|
6
|
-
description: GitHub token with actions write access.
|
|
7
|
-
required: true
|
|
8
|
-
artifact-retention-days:
|
|
9
|
-
description: Retention period in days. Invalid or empty values use 3.
|
|
10
|
-
required: false
|
|
11
|
-
default: ''
|
|
12
|
-
runs:
|
|
13
|
-
using: composite
|
|
14
|
-
steps:
|
|
15
|
-
- name: Delete expired artifacts
|
|
16
|
-
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
|
17
|
-
env:
|
|
18
|
-
ARTIFACT_RETENTION_DAYS: ${{ inputs.artifact-retention-days }}
|
|
19
|
-
with:
|
|
20
|
-
github-token: ${{ inputs.token }}
|
|
21
|
-
script: |
|
|
22
|
-
const parsedDays = Number.parseInt(process.env.ARTIFACT_RETENTION_DAYS, 10);
|
|
23
|
-
const days = Number.isInteger(parsedDays) && parsedDays > 0 ? parsedDays : 3;
|
|
24
|
-
const cutoff = new Date(Date.now() - days * 24 * 60 * 60 * 1000);
|
|
25
|
-
|
|
26
|
-
core.info(`Retention: ${days} days (cutoff ${cutoff.toISOString()})`);
|
|
27
|
-
|
|
28
|
-
const artifacts = await github.paginate(github.rest.actions.listArtifactsForRepo, {
|
|
29
|
-
...context.repo,
|
|
30
|
-
per_page: 100,
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
const expired = artifacts.filter((artifact) => new Date(artifact.created_at) < cutoff);
|
|
34
|
-
|
|
35
|
-
let deleted = 0;
|
|
36
|
-
const failed = [];
|
|
37
|
-
|
|
38
|
-
for (const artifact of expired) {
|
|
39
|
-
// GitHub answers a delete with a 5xx now and then. Three tries, because the
|
|
40
|
-
// alternative is a red daily run over one artifact that tomorrow's run would
|
|
41
|
-
// have removed anyway.
|
|
42
|
-
let lastError;
|
|
43
|
-
for (let attempt = 1; attempt <= 3; attempt += 1) {
|
|
44
|
-
try {
|
|
45
|
-
await github.rest.actions.deleteArtifact({
|
|
46
|
-
...context.repo,
|
|
47
|
-
artifact_id: artifact.id,
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
core.info(`Deleted ${artifact.name} (created ${artifact.created_at})`);
|
|
51
|
-
deleted += 1;
|
|
52
|
-
lastError = undefined;
|
|
53
|
-
break;
|
|
54
|
-
} catch (error) {
|
|
55
|
-
lastError = error;
|
|
56
|
-
if (attempt < 3) await new Promise((wait) => setTimeout(wait, attempt * 2000));
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
if (lastError) {
|
|
61
|
-
core.warning(
|
|
62
|
-
`Could not delete ${artifact.name} (${artifact.id}) after 3 tries: ${lastError.message}`,
|
|
63
|
-
);
|
|
64
|
-
failed.push({ name: artifact.name, status: lastError.status });
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
await core.summary
|
|
69
|
-
.addHeading('Artifact cleanup', 2)
|
|
70
|
-
.addList([
|
|
71
|
-
`Retention: ${days} days (cutoff ${cutoff.toISOString()})`,
|
|
72
|
-
`Deleted: ${deleted}`,
|
|
73
|
-
`Failed to delete: ${failed.length}`,
|
|
74
|
-
`Within retention: ${artifacts.length - expired.length}`,
|
|
75
|
-
])
|
|
76
|
-
.write();
|
|
77
|
-
|
|
78
|
-
// Deleting nothing at all while expired artifacts exist is a permission or
|
|
79
|
-
// configuration problem, and has to be loud. One stubborn artifact among many is
|
|
80
|
-
// the API having a bad minute: tomorrow's run picks it up, and failing here only
|
|
81
|
-
// teaches people to ignore a red cleanup. A 4xx is never transient, so it fails
|
|
82
|
-
// whatever else succeeded.
|
|
83
|
-
const names = failed.map((entry) => entry.name).join(', ');
|
|
84
|
-
const structural = failed.some((entry) => entry.status && entry.status < 500);
|
|
85
|
-
if (failed.length > 0 && (deleted === 0 || structural)) {
|
|
86
|
-
core.setFailed(`${failed.length} artifact(s) could not be deleted: ${names}`);
|
|
87
|
-
} else if (failed.length > 0) {
|
|
88
|
-
core.warning(
|
|
89
|
-
`${failed.length} artifact(s) survived this run and will be retried tomorrow: ${names}`,
|
|
90
|
-
);
|
|
91
|
-
}
|
|
1
|
+
# Managed by @plainconceptsplatform/workflows. Source: loops/actions/cleanup-artifacts/action.yml. Update with workflows update --force; consumer edits may be overwritten.
|
|
2
|
+
name: Clean up artifacts
|
|
3
|
+
description: Delete workflow artifacts older than the configured retention period.
|
|
4
|
+
inputs:
|
|
5
|
+
token:
|
|
6
|
+
description: GitHub token with actions write access.
|
|
7
|
+
required: true
|
|
8
|
+
artifact-retention-days:
|
|
9
|
+
description: Retention period in days. Invalid or empty values use 3.
|
|
10
|
+
required: false
|
|
11
|
+
default: ''
|
|
12
|
+
runs:
|
|
13
|
+
using: composite
|
|
14
|
+
steps:
|
|
15
|
+
- name: Delete expired artifacts
|
|
16
|
+
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
|
17
|
+
env:
|
|
18
|
+
ARTIFACT_RETENTION_DAYS: ${{ inputs.artifact-retention-days }}
|
|
19
|
+
with:
|
|
20
|
+
github-token: ${{ inputs.token }}
|
|
21
|
+
script: |
|
|
22
|
+
const parsedDays = Number.parseInt(process.env.ARTIFACT_RETENTION_DAYS, 10);
|
|
23
|
+
const days = Number.isInteger(parsedDays) && parsedDays > 0 ? parsedDays : 3;
|
|
24
|
+
const cutoff = new Date(Date.now() - days * 24 * 60 * 60 * 1000);
|
|
25
|
+
|
|
26
|
+
core.info(`Retention: ${days} days (cutoff ${cutoff.toISOString()})`);
|
|
27
|
+
|
|
28
|
+
const artifacts = await github.paginate(github.rest.actions.listArtifactsForRepo, {
|
|
29
|
+
...context.repo,
|
|
30
|
+
per_page: 100,
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
const expired = artifacts.filter((artifact) => new Date(artifact.created_at) < cutoff);
|
|
34
|
+
|
|
35
|
+
let deleted = 0;
|
|
36
|
+
const failed = [];
|
|
37
|
+
|
|
38
|
+
for (const artifact of expired) {
|
|
39
|
+
// GitHub answers a delete with a 5xx now and then. Three tries, because the
|
|
40
|
+
// alternative is a red daily run over one artifact that tomorrow's run would
|
|
41
|
+
// have removed anyway.
|
|
42
|
+
let lastError;
|
|
43
|
+
for (let attempt = 1; attempt <= 3; attempt += 1) {
|
|
44
|
+
try {
|
|
45
|
+
await github.rest.actions.deleteArtifact({
|
|
46
|
+
...context.repo,
|
|
47
|
+
artifact_id: artifact.id,
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
core.info(`Deleted ${artifact.name} (created ${artifact.created_at})`);
|
|
51
|
+
deleted += 1;
|
|
52
|
+
lastError = undefined;
|
|
53
|
+
break;
|
|
54
|
+
} catch (error) {
|
|
55
|
+
lastError = error;
|
|
56
|
+
if (attempt < 3) await new Promise((wait) => setTimeout(wait, attempt * 2000));
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (lastError) {
|
|
61
|
+
core.warning(
|
|
62
|
+
`Could not delete ${artifact.name} (${artifact.id}) after 3 tries: ${lastError.message}`,
|
|
63
|
+
);
|
|
64
|
+
failed.push({ name: artifact.name, status: lastError.status });
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
await core.summary
|
|
69
|
+
.addHeading('Artifact cleanup', 2)
|
|
70
|
+
.addList([
|
|
71
|
+
`Retention: ${days} days (cutoff ${cutoff.toISOString()})`,
|
|
72
|
+
`Deleted: ${deleted}`,
|
|
73
|
+
`Failed to delete: ${failed.length}`,
|
|
74
|
+
`Within retention: ${artifacts.length - expired.length}`,
|
|
75
|
+
])
|
|
76
|
+
.write();
|
|
77
|
+
|
|
78
|
+
// Deleting nothing at all while expired artifacts exist is a permission or
|
|
79
|
+
// configuration problem, and has to be loud. One stubborn artifact among many is
|
|
80
|
+
// the API having a bad minute: tomorrow's run picks it up, and failing here only
|
|
81
|
+
// teaches people to ignore a red cleanup. A 4xx is never transient, so it fails
|
|
82
|
+
// whatever else succeeded.
|
|
83
|
+
const names = failed.map((entry) => entry.name).join(', ');
|
|
84
|
+
const structural = failed.some((entry) => entry.status && entry.status < 500);
|
|
85
|
+
if (failed.length > 0 && (deleted === 0 || structural)) {
|
|
86
|
+
core.setFailed(`${failed.length} artifact(s) could not be deleted: ${names}`);
|
|
87
|
+
} else if (failed.length > 0) {
|
|
88
|
+
core.warning(
|
|
89
|
+
`${failed.length} artifact(s) survived this run and will be retried tomorrow: ${names}`,
|
|
90
|
+
);
|
|
91
|
+
}
|
|
@@ -1,43 +1,43 @@
|
|
|
1
|
-
# Managed by @plainconceptsplatform/workflows. Source: loops/actions/close-agent-issues/action.yml. Update with workflows update --force; consumer edits may be overwritten.
|
|
2
|
-
name: Close agent issues
|
|
3
|
-
description: Close every close_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
|
-
runs:
|
|
12
|
-
using: composite
|
|
13
|
-
steps:
|
|
14
|
-
- name: Close issues
|
|
15
|
-
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
|
16
|
-
env:
|
|
17
|
-
AGENT_OUTPUT_LIB: ${{ github.action_path }}/../agent-output.cjs
|
|
18
|
-
OUTPUT_FILE: ${{ inputs.output-file }}
|
|
19
|
-
with:
|
|
20
|
-
github-token: ${{ inputs.token }}
|
|
21
|
-
script: |
|
|
22
|
-
const { readAgentItems } = require(process.env.AGENT_OUTPUT_LIB);
|
|
23
|
-
const items = readAgentItems(process.env.OUTPUT_FILE, 'close_issue');
|
|
24
|
-
|
|
25
|
-
let closed = 0;
|
|
26
|
-
|
|
27
|
-
for (const item of items) {
|
|
28
|
-
if (!item.item_number) {
|
|
29
|
-
core.warning(`close_issue item has no item_number, skipping: ${JSON.stringify(item)}`);
|
|
30
|
-
continue;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
await github.rest.issues.update({
|
|
34
|
-
...context.repo,
|
|
35
|
-
issue_number: Number(item.item_number),
|
|
36
|
-
state: 'closed',
|
|
37
|
-
state_reason: item.state_reason === 'not_planned' ? 'not_planned' : 'completed',
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
closed += 1;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
core.info(`Closed ${closed} issue(s).`);
|
|
1
|
+
# Managed by @plainconceptsplatform/workflows. Source: loops/actions/close-agent-issues/action.yml. Update with workflows update --force; consumer edits may be overwritten.
|
|
2
|
+
name: Close agent issues
|
|
3
|
+
description: Close every close_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
|
+
runs:
|
|
12
|
+
using: composite
|
|
13
|
+
steps:
|
|
14
|
+
- name: Close issues
|
|
15
|
+
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
|
16
|
+
env:
|
|
17
|
+
AGENT_OUTPUT_LIB: ${{ github.action_path }}/../agent-output.cjs
|
|
18
|
+
OUTPUT_FILE: ${{ inputs.output-file }}
|
|
19
|
+
with:
|
|
20
|
+
github-token: ${{ inputs.token }}
|
|
21
|
+
script: |
|
|
22
|
+
const { readAgentItems } = require(process.env.AGENT_OUTPUT_LIB);
|
|
23
|
+
const items = readAgentItems(process.env.OUTPUT_FILE, 'close_issue');
|
|
24
|
+
|
|
25
|
+
let closed = 0;
|
|
26
|
+
|
|
27
|
+
for (const item of items) {
|
|
28
|
+
if (!item.item_number) {
|
|
29
|
+
core.warning(`close_issue item has no item_number, skipping: ${JSON.stringify(item)}`);
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
await github.rest.issues.update({
|
|
34
|
+
...context.repo,
|
|
35
|
+
issue_number: Number(item.item_number),
|
|
36
|
+
state: 'closed',
|
|
37
|
+
state_reason: item.state_reason === 'not_planned' ? 'not_planned' : 'completed',
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
closed += 1;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
core.info(`Closed ${closed} issue(s).`);
|
|
@@ -1,52 +1,52 @@
|
|
|
1
|
-
# Managed by @plainconceptsplatform/workflows. Source: loops/actions/create-agent-issues/action.yml. Update with workflows update --force; consumer edits may be overwritten.
|
|
2
|
-
name: Create agent issues
|
|
3
|
-
description: Create every create_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
|
-
outputs:
|
|
12
|
-
created-count:
|
|
13
|
-
description: Number of issues created.
|
|
14
|
-
value: ${{ steps.create.outputs.created-count }}
|
|
15
|
-
first-issue-number:
|
|
16
|
-
description: Issue number of the first issue created, or empty.
|
|
17
|
-
value: ${{ steps.create.outputs.first-issue-number }}
|
|
18
|
-
runs:
|
|
19
|
-
using: composite
|
|
20
|
-
steps:
|
|
21
|
-
- name: Create issues
|
|
22
|
-
id: create
|
|
23
|
-
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
|
24
|
-
env:
|
|
25
|
-
AGENT_OUTPUT_LIB: ${{ github.action_path }}/../agent-output.cjs
|
|
26
|
-
OUTPUT_FILE: ${{ inputs.output-file }}
|
|
27
|
-
with:
|
|
28
|
-
github-token: ${{ inputs.token }}
|
|
29
|
-
script: |
|
|
30
|
-
const { readAgentItems } = require(process.env.AGENT_OUTPUT_LIB);
|
|
31
|
-
const items = readAgentItems(process.env.OUTPUT_FILE, 'create_issue');
|
|
32
|
-
|
|
33
|
-
const created = [];
|
|
34
|
-
|
|
35
|
-
for (const item of items) {
|
|
36
|
-
if (!item.title) {
|
|
37
|
-
core.warning(`create_issue item has no title, skipping: ${JSON.stringify(item)}`);
|
|
38
|
-
continue;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
const { data } = await github.rest.issues.create({
|
|
42
|
-
...context.repo,
|
|
43
|
-
title: item.title,
|
|
44
|
-
body: item.body ?? '',
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
created.push(data.number);
|
|
48
|
-
core.info(`Created #${data.number}: ${item.title}`);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
core.setOutput('created-count', String(created.length));
|
|
52
|
-
core.setOutput('first-issue-number', created.length > 0 ? String(created[0]) : '');
|
|
1
|
+
# Managed by @plainconceptsplatform/workflows. Source: loops/actions/create-agent-issues/action.yml. Update with workflows update --force; consumer edits may be overwritten.
|
|
2
|
+
name: Create agent issues
|
|
3
|
+
description: Create every create_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
|
+
outputs:
|
|
12
|
+
created-count:
|
|
13
|
+
description: Number of issues created.
|
|
14
|
+
value: ${{ steps.create.outputs.created-count }}
|
|
15
|
+
first-issue-number:
|
|
16
|
+
description: Issue number of the first issue created, or empty.
|
|
17
|
+
value: ${{ steps.create.outputs.first-issue-number }}
|
|
18
|
+
runs:
|
|
19
|
+
using: composite
|
|
20
|
+
steps:
|
|
21
|
+
- name: Create issues
|
|
22
|
+
id: create
|
|
23
|
+
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
|
24
|
+
env:
|
|
25
|
+
AGENT_OUTPUT_LIB: ${{ github.action_path }}/../agent-output.cjs
|
|
26
|
+
OUTPUT_FILE: ${{ inputs.output-file }}
|
|
27
|
+
with:
|
|
28
|
+
github-token: ${{ inputs.token }}
|
|
29
|
+
script: |
|
|
30
|
+
const { readAgentItems } = require(process.env.AGENT_OUTPUT_LIB);
|
|
31
|
+
const items = readAgentItems(process.env.OUTPUT_FILE, 'create_issue');
|
|
32
|
+
|
|
33
|
+
const created = [];
|
|
34
|
+
|
|
35
|
+
for (const item of items) {
|
|
36
|
+
if (!item.title) {
|
|
37
|
+
core.warning(`create_issue item has no title, skipping: ${JSON.stringify(item)}`);
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const { data } = await github.rest.issues.create({
|
|
42
|
+
...context.repo,
|
|
43
|
+
title: item.title,
|
|
44
|
+
body: item.body ?? '',
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
created.push(data.number);
|
|
48
|
+
core.info(`Created #${data.number}: ${item.title}`);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
core.setOutput('created-count', String(created.length));
|
|
52
|
+
core.setOutput('first-issue-number', created.length > 0 ? String(created[0]) : '');
|
|
@@ -1,29 +1,29 @@
|
|
|
1
|
-
# Managed by @plainconceptsplatform/workflows. Source: loops/actions/create-issue-comment/action.yml. Update with workflows update --force; consumer edits may be overwritten.
|
|
2
|
-
name: Create issue comment
|
|
3
|
-
description: Create a comment on 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
|
-
body:
|
|
12
|
-
description: Complete Markdown comment body.
|
|
13
|
-
required: true
|
|
14
|
-
runs:
|
|
15
|
-
using: composite
|
|
16
|
-
steps:
|
|
17
|
-
- name: Create comment
|
|
18
|
-
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
|
19
|
-
env:
|
|
20
|
-
ISSUE_NUMBER: ${{ inputs.issue-number }}
|
|
21
|
-
BODY: ${{ inputs.body }}
|
|
22
|
-
with:
|
|
23
|
-
github-token: ${{ inputs.token }}
|
|
24
|
-
script: |
|
|
25
|
-
await github.rest.issues.createComment({
|
|
26
|
-
...context.repo,
|
|
27
|
-
issue_number: Number(process.env.ISSUE_NUMBER),
|
|
28
|
-
body: process.env.BODY,
|
|
29
|
-
});
|
|
1
|
+
# Managed by @plainconceptsplatform/workflows. Source: loops/actions/create-issue-comment/action.yml. Update with workflows update --force; consumer edits may be overwritten.
|
|
2
|
+
name: Create issue comment
|
|
3
|
+
description: Create a comment on 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
|
+
body:
|
|
12
|
+
description: Complete Markdown comment body.
|
|
13
|
+
required: true
|
|
14
|
+
runs:
|
|
15
|
+
using: composite
|
|
16
|
+
steps:
|
|
17
|
+
- name: Create comment
|
|
18
|
+
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
|
19
|
+
env:
|
|
20
|
+
ISSUE_NUMBER: ${{ inputs.issue-number }}
|
|
21
|
+
BODY: ${{ inputs.body }}
|
|
22
|
+
with:
|
|
23
|
+
github-token: ${{ inputs.token }}
|
|
24
|
+
script: |
|
|
25
|
+
await github.rest.issues.createComment({
|
|
26
|
+
...context.repo,
|
|
27
|
+
issue_number: Number(process.env.ISSUE_NUMBER),
|
|
28
|
+
body: process.env.BODY,
|
|
29
|
+
});
|
|
@@ -1,53 +1,53 @@
|
|
|
1
|
-
# Managed by @plainconceptsplatform/workflows. Source: loops/actions/download-agent-output/action.yml. Update with workflows update --force; consumer edits may be overwritten.
|
|
2
|
-
name: Download agent output
|
|
3
|
-
description: Download the agent artifact and expose the output JSON and bundle paths.
|
|
4
|
-
inputs:
|
|
5
|
-
artifact-name:
|
|
6
|
-
description: >-
|
|
7
|
-
Artifact name to download. gh-aw prefixes it with the value it derives from the
|
|
8
|
-
workflow's inputs, so a workflow_call worker must pass the activation job's
|
|
9
|
-
artifact_prefix output followed by "agent", not the bare name.
|
|
10
|
-
required: true
|
|
11
|
-
outputs:
|
|
12
|
-
output-file:
|
|
13
|
-
description: Path to agent_output.json, or empty if not found.
|
|
14
|
-
value: ${{ steps.download.outputs.output-file }}
|
|
15
|
-
bundle-file:
|
|
16
|
-
description: Path to the git bundle, or empty if not found.
|
|
17
|
-
value: ${{ steps.download.outputs.bundle-file }}
|
|
18
|
-
item-count:
|
|
19
|
-
description: Number of items in the agent output.
|
|
20
|
-
value: ${{ steps.download.outputs.item-count }}
|
|
21
|
-
runs:
|
|
22
|
-
using: composite
|
|
23
|
-
steps:
|
|
24
|
-
- name: Download agent artifact
|
|
25
|
-
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
26
|
-
with:
|
|
27
|
-
name: ${{ inputs.artifact-name }}
|
|
28
|
-
path: agent-artifact
|
|
29
|
-
- name: Locate output and bundle
|
|
30
|
-
id: download
|
|
31
|
-
shell: bash
|
|
32
|
-
env:
|
|
33
|
-
ARTIFACT_NAME: ${{ inputs.artifact-name }}
|
|
34
|
-
run: |
|
|
35
|
-
set -euo pipefail
|
|
36
|
-
OUTPUT_FILE=""
|
|
37
|
-
BUNDLE_FILE=""
|
|
38
|
-
ITEM_COUNT="0"
|
|
39
|
-
|
|
40
|
-
if [ -f "agent-artifact/agent_output.json" ]; then
|
|
41
|
-
OUTPUT_FILE="agent-artifact/agent_output.json"
|
|
42
|
-
ITEM_COUNT=$(jq '.items | length' "$OUTPUT_FILE")
|
|
43
|
-
BUNDLE_FILE=$(ls agent-artifact/aw-*.bundle 2>/dev/null | head -1 || true)
|
|
44
|
-
else
|
|
45
|
-
echo "::error::Artifact '$ARTIFACT_NAME' contained no agent_output.json. Nothing the agent proposed will be applied."
|
|
46
|
-
exit 1
|
|
47
|
-
fi
|
|
48
|
-
|
|
49
|
-
echo "Artifact '$ARTIFACT_NAME' carries $ITEM_COUNT item(s)."
|
|
50
|
-
|
|
51
|
-
echo "output-file=$OUTPUT_FILE" >> "$GITHUB_OUTPUT"
|
|
52
|
-
echo "bundle-file=$BUNDLE_FILE" >> "$GITHUB_OUTPUT"
|
|
53
|
-
echo "item-count=$ITEM_COUNT" >> "$GITHUB_OUTPUT"
|
|
1
|
+
# Managed by @plainconceptsplatform/workflows. Source: loops/actions/download-agent-output/action.yml. Update with workflows update --force; consumer edits may be overwritten.
|
|
2
|
+
name: Download agent output
|
|
3
|
+
description: Download the agent artifact and expose the output JSON and bundle paths.
|
|
4
|
+
inputs:
|
|
5
|
+
artifact-name:
|
|
6
|
+
description: >-
|
|
7
|
+
Artifact name to download. gh-aw prefixes it with the value it derives from the
|
|
8
|
+
workflow's inputs, so a workflow_call worker must pass the activation job's
|
|
9
|
+
artifact_prefix output followed by "agent", not the bare name.
|
|
10
|
+
required: true
|
|
11
|
+
outputs:
|
|
12
|
+
output-file:
|
|
13
|
+
description: Path to agent_output.json, or empty if not found.
|
|
14
|
+
value: ${{ steps.download.outputs.output-file }}
|
|
15
|
+
bundle-file:
|
|
16
|
+
description: Path to the git bundle, or empty if not found.
|
|
17
|
+
value: ${{ steps.download.outputs.bundle-file }}
|
|
18
|
+
item-count:
|
|
19
|
+
description: Number of items in the agent output.
|
|
20
|
+
value: ${{ steps.download.outputs.item-count }}
|
|
21
|
+
runs:
|
|
22
|
+
using: composite
|
|
23
|
+
steps:
|
|
24
|
+
- name: Download agent artifact
|
|
25
|
+
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
26
|
+
with:
|
|
27
|
+
name: ${{ inputs.artifact-name }}
|
|
28
|
+
path: agent-artifact
|
|
29
|
+
- name: Locate output and bundle
|
|
30
|
+
id: download
|
|
31
|
+
shell: bash
|
|
32
|
+
env:
|
|
33
|
+
ARTIFACT_NAME: ${{ inputs.artifact-name }}
|
|
34
|
+
run: |
|
|
35
|
+
set -euo pipefail
|
|
36
|
+
OUTPUT_FILE=""
|
|
37
|
+
BUNDLE_FILE=""
|
|
38
|
+
ITEM_COUNT="0"
|
|
39
|
+
|
|
40
|
+
if [ -f "agent-artifact/agent_output.json" ]; then
|
|
41
|
+
OUTPUT_FILE="agent-artifact/agent_output.json"
|
|
42
|
+
ITEM_COUNT=$(jq '.items | length' "$OUTPUT_FILE")
|
|
43
|
+
BUNDLE_FILE=$(ls agent-artifact/aw-*.bundle 2>/dev/null | head -1 || true)
|
|
44
|
+
else
|
|
45
|
+
echo "::error::Artifact '$ARTIFACT_NAME' contained no agent_output.json. Nothing the agent proposed will be applied."
|
|
46
|
+
exit 1
|
|
47
|
+
fi
|
|
48
|
+
|
|
49
|
+
echo "Artifact '$ARTIFACT_NAME' carries $ITEM_COUNT item(s)."
|
|
50
|
+
|
|
51
|
+
echo "output-file=$OUTPUT_FILE" >> "$GITHUB_OUTPUT"
|
|
52
|
+
echo "bundle-file=$BUNDLE_FILE" >> "$GITHUB_OUTPUT"
|
|
53
|
+
echo "item-count=$ITEM_COUNT" >> "$GITHUB_OUTPUT"
|
|
@@ -1,40 +1,40 @@
|
|
|
1
|
-
# Managed by @plainconceptsplatform/workflows. Source: loops/actions/link-pr-to-issue/action.yml. Update with workflows update --force; consumer edits may be overwritten.
|
|
2
|
-
name: Link pull request to issue
|
|
3
|
-
description: Ensure the pull request body carries a closing reference to its source issue.
|
|
4
|
-
inputs:
|
|
5
|
-
token:
|
|
6
|
-
description: GitHub token with pull-requests write access.
|
|
7
|
-
required: true
|
|
8
|
-
pr-number:
|
|
9
|
-
description: Pull request number.
|
|
10
|
-
required: true
|
|
11
|
-
issue-number:
|
|
12
|
-
description: Issue number the pull request should close.
|
|
13
|
-
required: true
|
|
14
|
-
runs:
|
|
15
|
-
using: composite
|
|
16
|
-
steps:
|
|
17
|
-
- name: Ensure a closing reference
|
|
18
|
-
shell: bash
|
|
19
|
-
env:
|
|
20
|
-
GH_TOKEN: ${{ inputs.token }}
|
|
21
|
-
REPO: ${{ github.repository }}
|
|
22
|
-
PR_NUMBER: ${{ inputs.pr-number }}
|
|
23
|
-
ISSUE_NUMBER: ${{ inputs.issue-number }}
|
|
24
|
-
run: |
|
|
25
|
-
set -euo pipefail
|
|
26
|
-
|
|
27
|
-
pr="$(gh pr view "$PR_NUMBER" --repo "$REPO" --json closingIssuesReferences,body)"
|
|
28
|
-
|
|
29
|
-
if [ "$(jq '.closingIssuesReferences | length' <<<"$pr")" -gt 0 ]; then
|
|
30
|
-
echo "PR #$PR_NUMBER already closes an issue."
|
|
31
|
-
exit 0
|
|
32
|
-
fi
|
|
33
|
-
|
|
34
|
-
# A closing reference can only be created from the pull request body; there is no
|
|
35
|
-
# REST or GraphQL mutation for it.
|
|
36
|
-
body="$(jq -r '.body // ""' <<<"$pr")"
|
|
37
|
-
printf '%s\n\nCloses #%s\n' "$body" "$ISSUE_NUMBER" > /tmp/pr-body.md
|
|
38
|
-
|
|
39
|
-
gh pr edit "$PR_NUMBER" --repo "$REPO" --body-file /tmp/pr-body.md
|
|
40
|
-
echo "Added 'Closes #$ISSUE_NUMBER' to PR #$PR_NUMBER."
|
|
1
|
+
# Managed by @plainconceptsplatform/workflows. Source: loops/actions/link-pr-to-issue/action.yml. Update with workflows update --force; consumer edits may be overwritten.
|
|
2
|
+
name: Link pull request to issue
|
|
3
|
+
description: Ensure the pull request body carries a closing reference to its source issue.
|
|
4
|
+
inputs:
|
|
5
|
+
token:
|
|
6
|
+
description: GitHub token with pull-requests write access.
|
|
7
|
+
required: true
|
|
8
|
+
pr-number:
|
|
9
|
+
description: Pull request number.
|
|
10
|
+
required: true
|
|
11
|
+
issue-number:
|
|
12
|
+
description: Issue number the pull request should close.
|
|
13
|
+
required: true
|
|
14
|
+
runs:
|
|
15
|
+
using: composite
|
|
16
|
+
steps:
|
|
17
|
+
- name: Ensure a closing reference
|
|
18
|
+
shell: bash
|
|
19
|
+
env:
|
|
20
|
+
GH_TOKEN: ${{ inputs.token }}
|
|
21
|
+
REPO: ${{ github.repository }}
|
|
22
|
+
PR_NUMBER: ${{ inputs.pr-number }}
|
|
23
|
+
ISSUE_NUMBER: ${{ inputs.issue-number }}
|
|
24
|
+
run: |
|
|
25
|
+
set -euo pipefail
|
|
26
|
+
|
|
27
|
+
pr="$(gh pr view "$PR_NUMBER" --repo "$REPO" --json closingIssuesReferences,body)"
|
|
28
|
+
|
|
29
|
+
if [ "$(jq '.closingIssuesReferences | length' <<<"$pr")" -gt 0 ]; then
|
|
30
|
+
echo "PR #$PR_NUMBER already closes an issue."
|
|
31
|
+
exit 0
|
|
32
|
+
fi
|
|
33
|
+
|
|
34
|
+
# A closing reference can only be created from the pull request body; there is no
|
|
35
|
+
# REST or GraphQL mutation for it.
|
|
36
|
+
body="$(jq -r '.body // ""' <<<"$pr")"
|
|
37
|
+
printf '%s\n\nCloses #%s\n' "$body" "$ISSUE_NUMBER" > /tmp/pr-body.md
|
|
38
|
+
|
|
39
|
+
gh pr edit "$PR_NUMBER" --repo "$REPO" --body-file /tmp/pr-body.md
|
|
40
|
+
echo "Added 'Closes #$ISSUE_NUMBER' to PR #$PR_NUMBER."
|