1+ ---
2+ name : Backported Dependency Changes
3+
4+ on :
5+ # The pull_request_target trigger event allows PRs raised from forks to have write permissions and access secrets.
6+ # We uses it in this workflow to enable writing comments to the PR.
7+ pull_request_target :
8+ types :
9+ - opened
10+ - synchronize
11+ - labeled
12+ - unlabeled
13+ pull_request :
14+ types :
15+ - opened
16+ - synchronize
17+ - labeled
18+ - unlabeled
19+
20+ # This workflow runs for not-yet-reviewed external contributions.
21+ # Following a pull_request_target trigger the workflow would have write permissions,
22+ # so we intentionally restrict the permissions to only include write access on pull-requests.
23+ permissions :
24+ contents : read
25+ pull-requests : write
26+
27+ jobs :
28+ deps-change-comment :
29+ runs-on : ubuntu-latest
30+ steps :
31+ - name : " Identify if go.mod files have changed"
32+ uses : dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
33+ id : changedfiles
34+ with :
35+ filters : |
36+ root-go-mod:
37+ - 'go.mod'
38+ nested-go-mod:
39+ - '**/*/go.mod'
40+ list-files : json
41+
42+ # This step will create or delete an existing comment; responds to changes in the PR.
43+ - name : " Comment on PR if necessary"
44+ uses : actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
45+ with :
46+ script : |
47+ // SETUP - values needed for function definitions below.
48+ const commentStart = "## Backported dependency change";
49+
50+ const { number: issue_number } = context.issue;
51+ const { owner, repo } = context.repo;
52+
53+ // List all comments
54+ const allComments = (await github.rest.issues.listComments({
55+ issue_number,
56+ owner,
57+ repo,
58+ })).data;
59+ const existingComment = allComments.find(c => c.body.startsWith(commentStart));
60+ const comment_id = existingComment?.id;
61+
62+ async function createOrUpdateComment(commentDetails) {
63+ const body = commentStart + "\n\n" + commentDetails;
64+ let resp
65+ if (existingComment) {
66+ resp = await github.rest.issues.updateComment({
67+ owner,
68+ repo,
69+ comment_id,
70+ body,
71+ });
72+ } else {
73+ resp = await github.rest.issues.createComment({
74+ owner,
75+ repo,
76+ issue_number,
77+ body,
78+ });
79+ }
80+ if (resp.status != 200){
81+ console.error("creating/updating comment failed, here's the response:", resp )
82+ core.setFailed("creating/updating comment failed with status code " + resp.status)
83+ }
84+ }
85+
86+ async function deleteCommentIfExists() {
87+ if (existingComment) {
88+ const resp = await github.rest.issues.deleteComment({
89+ owner,
90+ repo,
91+ comment_id,
92+ });
93+ if (resp.status >= 300 ){
94+ // Allow all status codes in 2XX range; deleting a non-existing comment is 204
95+ console.error("deleting comment failed, here's the response:", resp )
96+ core.setFailed("deleting comment failed with status code " + resp.status)
97+ }
98+ }
99+ }
100+
101+ async function getPrLabels() {
102+ const labelsResp = await github.rest.issues.listLabelsOnIssue({
103+ owner,
104+ repo,
105+ issue_number,
106+ });
107+ if (labelsResp.status != 200){
108+ console.error("getting the PR's labels failed, here's the response:", resp )
109+ core.setFailed("getting the PR's labels failed with status code " + resp.status)
110+ }
111+ return labelsResp
112+ }
113+
114+ // INSPECT PR & UPDATE COMMENT
115+
116+ const labels = await getPrLabels()
117+ const filteredLabels = labels.data.filter( label => {
118+ return label.name.includes("backport")
119+ })
120+ const hasBackportLabel = filteredLabels.length > 0
121+ const changedRootGoMod = ${{steps.changedfiles.outputs.root-go-mod}};
122+ const changedNestedGoMod = ${{steps.changedfiles.outputs.nested-go-mod}};
123+ const changesPresent = changedRootGoMod || changedNestedGoMod
124+ if (!changesPresent){
125+ console.log("This PR isn't attempting to change dependencies. No comment needed.")
126+ await deleteCommentIfExists()
127+ } else if (!hasBackportLabel) {
128+ console.log(`This PR contains changes to dependency-related files but doesn't have a backport label. No comment needed.` +
129+ `\nChanged root go.mod? = ${changedRootGoMod}`+
130+ `\nChanged a nested go.mod? = ${changedNestedGoMod}`)
131+ await deleteCommentIfExists()
132+ } else {
133+ console.log("This PR contains changes to dependency-related files and is labelled for backport. Making sure comment is present.")
134+ const comment = "This PR makes changes to dependencies in go.mod file(s) and is labelled for backport.\n\n" +
135+ "Notice to the maintainer: Before merging the backport of this PR please follow our security scanning processes."
136+ await createOrUpdateComment(comment)
137+ }
0 commit comments