Skip to content

Commit 92ddd31

Browse files
authored
Support mirroring issues to tracking repo (#8999)
1 parent 8bf3fd1 commit 92ddd31

1 file changed

Lines changed: 118 additions & 0 deletions

File tree

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
name: Mirror New Issues
2+
3+
on:
4+
issues:
5+
types: [opened]
6+
7+
workflow_dispatch:
8+
inputs:
9+
issue_number:
10+
description: "Issue number to mirror"
11+
required: true
12+
type: number
13+
14+
jobs:
15+
mirror-issue:
16+
name: Mirror Issue
17+
runs-on: ubuntu-latest
18+
permissions:
19+
contents: read
20+
issues: read
21+
env:
22+
TARGET_REPO_ORG: ${{ secrets.WARP_ISSUES_REPO_ORG }}
23+
TARGET_REPO_NAME: ${{ secrets.WARP_ISSUES_REPO_NAME }}
24+
TARGET_APP_ID: ${{ secrets.WARP_ISSUES_APP_ID }}
25+
TARGET_APP_PRIVATE_KEY: ${{ secrets.WARP_ISSUES_APP_PRIVATE_KEY }}
26+
steps:
27+
- name: Validate configuration
28+
run: |
29+
if [ -z "${TARGET_REPO_ORG}" ]; then
30+
echo "secrets.WARP_ISSUES_REPO_ORG must be set to the destination owner."
31+
exit 1
32+
fi
33+
34+
if [ -z "${TARGET_REPO_NAME}" ]; then
35+
echo "secrets.WARP_ISSUES_REPO_NAME must be set to the destination repository name."
36+
exit 1
37+
fi
38+
39+
if [ "${TARGET_REPO_ORG}/${TARGET_REPO_NAME}" = "${{ github.repository }}" ]; then
40+
echo "The destination repository must be different from ${{ github.repository }}."
41+
exit 1
42+
fi
43+
44+
if [ -z "${TARGET_APP_ID}" ]; then
45+
echo "secrets.WARP_ISSUES_APP_ID must be set to the GitHub App ID."
46+
exit 1
47+
fi
48+
49+
if [ -z "${TARGET_APP_PRIVATE_KEY}" ]; then
50+
echo "secrets.WARP_ISSUES_APP_PRIVATE_KEY must be set to the GitHub App private key."
51+
exit 1
52+
fi
53+
54+
- name: Mint GitHub App installation token
55+
id: app-token
56+
uses: actions/create-github-app-token@v1
57+
with:
58+
app-id: ${{ secrets.WARP_ISSUES_APP_ID }}
59+
private-key: ${{ secrets.WARP_ISSUES_APP_PRIVATE_KEY }}
60+
owner: ${{ secrets.WARP_ISSUES_REPO_ORG }}
61+
repositories: ${{ secrets.WARP_ISSUES_REPO_NAME }}
62+
63+
- name: Mirror issue
64+
uses: actions/github-script@v7
65+
env:
66+
TARGET_APP_TOKEN: ${{ steps.app-token.outputs.token }}
67+
with:
68+
script: |
69+
const { getOctokit } = require("@actions/github");
70+
const targetOwner = process.env.TARGET_REPO_ORG;
71+
const targetName = process.env.TARGET_REPO_NAME;
72+
const targetToken = process.env.TARGET_APP_TOKEN;
73+
74+
if (!targetOwner || !targetName) {
75+
core.setFailed(
76+
"secrets.WARP_ISSUES_REPO_ORG and secrets.WARP_ISSUES_REPO_NAME must both be set.",
77+
);
78+
return;
79+
}
80+
81+
if (!targetToken) {
82+
core.setFailed("Failed to mint a GitHub App installation token.");
83+
return;
84+
}
85+
86+
let issue;
87+
88+
if (context.eventName === "workflow_dispatch") {
89+
const issueNumberInput = context.payload.inputs?.issue_number;
90+
const issueNumber = Number(issueNumberInput);
91+
92+
if (!Number.isInteger(issueNumber) || issueNumber <= 0) {
93+
core.setFailed(`Invalid issue_number input: "${issueNumberInput}".`);
94+
return;
95+
}
96+
97+
const response = await github.rest.issues.get({
98+
owner: context.repo.owner,
99+
repo: context.repo.repo,
100+
issue_number: issueNumber,
101+
});
102+
103+
issue = response.data;
104+
} else {
105+
issue = context.payload.issue;
106+
}
107+
108+
const mirroredBody = issue.body?.trim()
109+
? `[Original issue](${issue.html_url})\n\n${issue.body}`
110+
: `[Original issue](${issue.html_url})`;
111+
112+
const targetGitHub = getOctokit(targetToken);
113+
await targetGitHub.rest.issues.create({
114+
owner: targetOwner,
115+
repo: targetName,
116+
title: issue.title,
117+
body: mirroredBody,
118+
});

0 commit comments

Comments
 (0)