Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitb8faef6

Browse files
authored
ci: add stale theme pull request closer action push (anuraghazra#2067)
This commit adds the `stale-theme-pr-closer` closer action. This actionis used to close theme pull requests with an `invalid` label that hasbeen stale for a given number of `STALE_DAYS`.
1 parent986070a commitb8faef6

File tree

10 files changed

+242
-43
lines changed

10 files changed

+242
-43
lines changed

‎.github/workflows/e2e-test.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@ on:
33
deployment_status:
44

55
jobs:
6-
preview:
6+
e2eTests:
77
if:
88
github.event_name == 'deployment_status' &&
99
github.event.deployment_status.state == 'success'
10+
name:Perform 2e2 tests
1011
runs-on:ubuntu-latest
1112
strategy:
1213
matrix:

‎.github/workflows/empty-issues-closer.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ jobs:
1212
runs-on:ubuntu-latest
1313
steps:
1414
-uses:actions/checkout@v3# NOTE: Retrieve issue templates.
15+
1516
-name:Run empty issues closer action
1617
uses:rickstaa/empty-issues-closer-action@v1
1718
env:

‎.github/workflows/generate-theme-doc.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
name:Generate Theme Readme
2-
32
on:
43
push:
54
branches:
@@ -8,8 +7,9 @@ on:
87
-"themes/index.js"
98

109
jobs:
11-
build:
10+
generateThemeDoc:
1211
runs-on:ubuntu-latest
12+
name:Generate theme doc
1313
strategy:
1414
matrix:
1515
node-version:[16.x]

‎.github/workflows/preview-theme.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
name:Theme preview
2-
32
on:
43
pull_request_target:
54
types:[opened, edited, reopened, synchronize]
@@ -10,11 +9,11 @@ on:
109

1110
jobs:
1211
previewTheme:
12+
name:Install & Preview
1313
runs-on:ubuntu-latest
1414
strategy:
1515
matrix:
1616
node-version:[16.x]
17-
name:Install & Preview
1817

1918
steps:
2019
-uses:actions/checkout@v3
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
name:Close stale theme pull requests that have the 'invalid' label.
2+
on:
3+
schedule:
4+
-cron:"0 0 */7 * *"
5+
6+
jobs:
7+
closeOldThemePrs:
8+
name:Close stale 'invalid' theme PRs
9+
runs-on:ubuntu-latest
10+
strategy:
11+
matrix:
12+
node-version:[16.x]
13+
14+
steps:
15+
-uses:actions/checkout@v3
16+
17+
-name:Setup Node
18+
uses:actions/setup-node@v3
19+
with:
20+
node-version:${{ matrix.node-version }}
21+
cache:npm
22+
23+
-uses:bahmutov/npm-install@v1
24+
with:
25+
useLockFile:false
26+
27+
-run:npm run close-stale-theme-prs
28+
env:
29+
STALE_DAYS:15
30+
GITHUB_TOKEN:${{ secrets.GITHUB_TOKEN }}

‎.github/workflows/test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
name:Test
2-
32
on:
43
push:
54
branches:
@@ -10,6 +9,7 @@ on:
109

1110
jobs:
1211
build:
12+
name:Perform tests
1313
runs-on:ubuntu-latest
1414
strategy:
1515
matrix:

‎package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
"test:e2e":"node --experimental-vm-modules node_modules/jest/bin/jest.js --config jest.e2e.config.js",
1212
"theme-readme-gen":"node scripts/generate-theme-doc",
1313
"preview-theme":"node scripts/preview-theme",
14+
"close-stale-theme-prs":"node scripts/close-stale-theme-prs",
1415
"generate-langs-json":"node scripts/generate-langs-json",
1516
"format":"./node_modules/.bin/prettier --write .",
1617
"format:check":"./node_modules/.bin/prettier --check ."

‎scripts/close-stale-theme-prs.js

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
/**
2+
*@file Script that can be used to close stale theme PRs that have a `invalid` label.
3+
*/
4+
import*asdotenvfrom"dotenv";
5+
dotenv.config();
6+
7+
import{debug,setFailed}from"@actions/core";
8+
importgithubfrom"@actions/github";
9+
import{RequestError}from"@octokit/request-error";
10+
import{getGithubToken,getRepoInfo}from"./helpers.js";
11+
12+
// Script parameters
13+
constCLOSING_COMMENT=`
14+
\rThis PR has been automatically closed due to inactivity. Please feel free to reopen it if you need to continue working on it.\
15+
\rThank you for your contributions.
16+
`;
17+
18+
/**
19+
* Fetch open PRs from a given repository.
20+
*@param user The user name of the repository owner.
21+
*@param repo The name of the repository.
22+
*@returns The open PRs.
23+
*/
24+
exportconstfetchOpenPRs=async(octokit,user,repo)=>{
25+
constopenPRs=[];
26+
lethasNextPage=true;
27+
letendCursor;
28+
while(hasNextPage){
29+
try{
30+
const{ repository}=awaitoctokit.graphql(
31+
`
32+
{
33+
repository(owner: "${user}", name: "${repo}") {
34+
open_prs: pullRequests(${
35+
endCursor ?`after: "${endCursor}", ` :""
36+
}
37+
first: 100, states: OPEN, orderBy: {field: CREATED_AT, direction: DESC}) {
38+
nodes {
39+
number
40+
commits(last:1){
41+
nodes{
42+
commit{
43+
pushedDate
44+
}
45+
}
46+
}
47+
labels(first: 100, orderBy:{field: CREATED_AT, direction: DESC}) {
48+
nodes {
49+
name
50+
}
51+
}
52+
reviews(first: 1, states: CHANGES_REQUESTED, author: "github-actions[bot]") {
53+
nodes {
54+
updatedAt
55+
}
56+
}
57+
}
58+
pageInfo {
59+
endCursor
60+
hasNextPage
61+
}
62+
}
63+
}
64+
}
65+
`,
66+
);
67+
openPRs.push(...repository.open_prs.nodes);
68+
hasNextPage=repository.open_prs.pageInfo.hasNextPage;
69+
endCursor=repository.open_prs.pageInfo.endCursor;
70+
}catch(error){
71+
if(errorinstanceofRequestError){
72+
setFailed(`Could not retrieve top PRs using GraphQl:${error.message}`);
73+
}
74+
throwerror;
75+
}
76+
}
77+
returnopenPRs;
78+
};
79+
80+
/**
81+
* Retrieve pull requests that have a given label.
82+
*@param pull The pull requests to check.
83+
*@param label The label to check for.
84+
*/
85+
exportconstpullsWithLabel=(pulls,label)=>{
86+
returnpulls.filter((pr)=>{
87+
returnpr.labels.nodes.some((lab)=>lab.name===label);
88+
});
89+
};
90+
91+
/**
92+
* Check if PR is stale. Meaning that it hasn't been updated in a given time.
93+
*@param {Object} pullRequest request object.
94+
*@param {number} days number of days.
95+
*@returns Boolean indicating if PR is stale.
96+
*/
97+
constisStale=(pullRequest,staleDays)=>{
98+
constlastCommitDate=newDate(
99+
pullRequest.commits.nodes[0].commit.pushedDate,
100+
);
101+
if(pullRequest.reviews.nodes[0]){
102+
constlastReviewDate=newDate(pullRequest.reviews.nodes[0].updatedAt);
103+
constlastUpdateDate=
104+
lastCommitDate>=lastReviewDate ?lastCommitDate :lastReviewDate;
105+
constnow=newDate();
106+
returnnow-lastUpdateDate>1000*60*60*24*staleDays;
107+
}else{
108+
returnfalse;
109+
}
110+
};
111+
112+
/**
113+
* Main function.
114+
*/
115+
construn=async()=>{
116+
try{
117+
// Create octokit client.
118+
constdryRun=process.env.DRY_RUN==="true"||false;
119+
conststaleDays=process.env.STALE_DAYS||15;
120+
debug("Creating octokit client...");
121+
constoctokit=github.getOctokit(getGithubToken());
122+
const{ owner, repo}=getRepoInfo(github.context);
123+
124+
// Retrieve all theme pull requests.
125+
debug("Retrieving all theme pull requests...");
126+
constprs=awaitfetchOpenPRs(octokit,owner,repo);
127+
constthemePRs=pullsWithLabel(prs,"themes");
128+
constinvalidThemePRs=pullsWithLabel(themePRs,"invalid");
129+
debug("Retrieving stale themePRs...");
130+
conststaleThemePRs=invalidThemePRs.filter((pr)=>
131+
isStale(pr,staleDays),
132+
);
133+
conststaleThemePRsNumbers=staleThemePRs.map((pr)=>pr.number);
134+
debug(`Found${staleThemePRs.length} stale theme PRs`);
135+
136+
// Loop through all stale invalid theme pull requests and close them.
137+
for(constprNumberofstaleThemePRsNumbers){
138+
debug(`Closing #${prNumber} because it is stale...`);
139+
if(!dryRun){
140+
awaitoctokit.issues.createComment({
141+
owner,
142+
repo,
143+
issue_number:prNumber,
144+
body:CLOSING_COMMENT,
145+
});
146+
awaitoctokit.pulls.update({
147+
owner,
148+
repo,
149+
pull_number:prNumber,
150+
state:"closed",
151+
});
152+
}else{
153+
debug("Dry run enabled, skipping...");
154+
}
155+
}
156+
}catch(error){
157+
setFailed(error.message);
158+
}
159+
};
160+
161+
run();

‎scripts/helpers.js

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/**
2+
*@file Contains helper functions used in the scripts.
3+
*/
4+
5+
// Script variables.
6+
constOWNER="anuraghazra";
7+
constREPO="github-readme-stats";
8+
9+
/**
10+
* Retrieve information about the repository that ran the action.
11+
*
12+
*@param {Object} context Action context.
13+
*@returns {Object} Repository information.
14+
*/
15+
exportconstgetRepoInfo=(ctx)=>{
16+
try{
17+
return{
18+
owner:ctx.repo.owner,
19+
repo:ctx.repo.repo,
20+
};
21+
}catch(error){
22+
return{
23+
owner:OWNER,
24+
repo:REPO,
25+
};
26+
}
27+
};
28+
29+
/**
30+
* Retrieve github token and throw error if it is not found.
31+
*
32+
*@returns {string} Github token.
33+
*/
34+
exportconstgetGithubToken=()=>{
35+
consttoken=core.getInput("github_token")||process.env.GITHUB_TOKEN;
36+
if(!token){
37+
throwError("Could not find github token");
38+
}
39+
returntoken;
40+
};

‎scripts/preview-theme.js

Lines changed: 3 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import*asdotenvfrom"dotenv";
55
dotenv.config();
66

7-
importcore,{debug,setFailed}from"@actions/core";
7+
import{debug,setFailed}from"@actions/core";
88
importgithubfrom"@actions/github";
99
importColorContrastCheckerfrom"color-contrast-checker";
1010
import{info}from"console";
@@ -14,10 +14,9 @@ import parse from "parse-diff";
1414
import{inspect}from"util";
1515
import{isValidHexColor}from"../src/common/utils.js";
1616
import{themes}from"../themes/index.js";
17+
import{getGithubToken,getRepoInfo}from"./helpers.js";
1718

18-
// Script variables
19-
constOWNER="anuraghazra";
20-
constREPO="github-readme-stats";
19+
// Script variables.
2120
constCOMMENTER="github-actions[bot]";
2221

2322
constCOMMENT_TITLE="Automated Theme Preview";
@@ -43,26 +42,6 @@ const REQUIRED_COLOR_PROPS = [
4342
constINVALID_REVIEW_COMMENT=(commentUrl)=>
4443
`Some themes are invalid. See the [Automated Theme Preview](${commentUrl}) comment above for more information.`;
4544

46-
/**
47-
* Retrieve information about the repository that ran the action.
48-
*
49-
*@param {Object} context Action context.
50-
*@returns {Object} Repository information.
51-
*/
52-
exportconstgetRepoInfo=(ctx)=>{
53-
try{
54-
return{
55-
owner:ctx.repo.owner,
56-
repo:ctx.repo.repo,
57-
};
58-
}catch(error){
59-
return{
60-
owner:OWNER,
61-
repo:REPO,
62-
};
63-
}
64-
};
65-
6645
/**
6746
* Retrieve PR number from the event payload.
6847
*
@@ -86,19 +65,6 @@ const getCommenter = () => {
8665
returnprocess.env.COMMENTER ?process.env.COMMENTER :COMMENTER;
8766
};
8867

89-
/**
90-
* Retrieve github token and throw error if it is not found.
91-
*
92-
*@returns {string} Github token.
93-
*/
94-
constgetGithubToken=()=>{
95-
consttoken=core.getInput("github_token")||process.env.GITHUB_TOKEN;
96-
if(!token){
97-
throwError("Could not find github token");
98-
}
99-
returntoken;
100-
};
101-
10268
/**
10369
* Returns whether the comment is a preview comment.
10470
*

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp