-
Notifications
You must be signed in to change notification settings - Fork 66.5k
171 lines (151 loc) · 7.87 KB
/
create-changelog-pr.yml
File metadata and controls
171 lines (151 loc) · 7.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
name: Create a PR to add an entry to the CHANGELOG.md file in this repo
# **What it does**: If a member of the github org posts a changelog comment, it creates a PR to update the CHANGELOG.md file.
# **Why we have it**: This surfaces docs changelog details publicly.
# **Who does it impact**: GitHub users and staff.
on:
issue_comment:
types: [created]
workflow_dispatch:
permissions:
contents: write
pull-requests: write
env:
CHANGELOG_FILE: CHANGELOG.md
CHANGELOG_FILE_URL: https://github.com/github/docs-internal/blob/main/CHANGELOG.md
jobs:
docs-changelog-pr:
if: ${{ github.repository == 'github/docs-internal' && github.event.issue.pull_request }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6.0.1
- name: 'Ensure ${{ env.CHANGELOG_FILE }} exists'
run: |
if [ ! -f ${{ env.CHANGELOG_FILE }} ]; then
echo "${{ env.CHANGELOG_FILE }} is missing at the root of the repository."
exit 1
fi
- name: Check that the user belongs to the github org
id: hubber_check
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd
with:
github-token: ${{ secrets.DOCS_BOT_PAT_BASE }}
script: |
try {
await github.rest.teams.getMembershipForUserInOrg({
org: 'github',
team_slug: 'employees',
username: context.payload.sender.login,
});
core.exportVariable('CONTINUE_WORKFLOW', 'true');
} catch(err) {
core.info("Workflow triggered by a comment, but the commenter is not a Hubber. Exiting.");
core.exportVariable('CONTINUE_WORKFLOW', 'false');
}
- name: Check if comment starts with '## Changelog summary'
if: env.CONTINUE_WORKFLOW == 'true'
id: check_summary
env:
COMMENT_BODY: ${{ github.event.comment.body }}
run: |
# Get the first line of the comment and trim the leading/trailing whitespace:
FIRST_LINE=$(printf "%s\n" "$COMMENT_BODY" | head -n1 | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
if [[ "$FIRST_LINE" != '## Changelog summary' ]]; then
echo "FIRST_LINE=|$FIRST_LINE|"
echo "The pull request comment is not a changelog summary. Exiting."
echo "CONTINUE_WORKFLOW=false" >> $GITHUB_ENV
fi
- name: Create changelog text
if: env.CONTINUE_WORKFLOW == 'true'
id: create_text
env:
COMMENT_BODY: ${{ github.event.comment.body }}
run: |
set -euo pipefail
DATE=$(date +"**%-d %B %Y**")
BODY="$(printf "%s\n" "$COMMENT_BODY" | tail -n +2)"
CHANGELOG_TEXT="$(printf "%s\n" "$BODY" | awk '/^:writing_hand:/{exit} {print}')"
{
echo "$DATE"
echo -e "$CHANGELOG_TEXT\n<hr>"
} > changelog_entry.txt
- name: Set up git
if: env.CONTINUE_WORKFLOW == 'true'
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
- name: Prepare branch
if: env.CONTINUE_WORKFLOW == 'true'
run: |
BRANCH="changelog-update-$(date +%s)"
echo "BRANCH=$BRANCH" >> $GITHUB_ENV
git checkout -b "$BRANCH"
# Insert new changelog entry after the first heading, as follows:
# Print the first line of the existing CHANGELOG.md file into a `tmp` file, followed by an empty line.
# Then, print the contents of `changelog_entry.txt` into the `tmp` file.
# Then, print the rest of the existing CHANGELOG.md file into the `tmp` file.
# Finally, replace the existing CHANGELOG.md file with the `tmp` file.
awk 'NR==1{print; print ""; while ((getline line < "changelog_entry.txt") > 0) print line; next}1' CHANGELOG.md > tmp && mv tmp CHANGELOG.md
git add CHANGELOG.md
git commit -m "Update changelog for $(head -n1 changelog_entry.txt)"
git push origin "$BRANCH"
- name: Create a pull request
if: env.CONTINUE_WORKFLOW == 'true'
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd
id: create_pull_request
with:
github-token: ${{ secrets.DOCS_BOT_PAT_BASE }}
script: |
const { data: pullRequest } = await github.rest.pulls.create({
owner: context.repo.owner,
repo: context.repo.repo,
title: `Update docs changelog (for PR #${context.payload.issue.number})`,
body: `### Automated docs changelog update\n\n**Purpose:** Update the <code>[${{ env.CHANGELOG_FILE }}](${{ env.CHANGELOG_FILE_URL }})</code> file with details of a recent docs change.\n\nThis PR is an automated update, generated by the <code>create-changelog-pr.yml</code> Actions workflow as a result of a "Changelog summary" comment being added to [PR #${context.payload.issue.number}](${context.payload.issue.html_url}).\n\n**Notes for reviewer**:\n- This change to the <code>[${{ env.CHANGELOG_FILE }}](${{ env.CHANGELOG_FILE_URL }})</code> file will be synced to the public docs site, so make sure that the content of the entry is appropriate for public consumption. If the content is wholly inappropriate for public consumption, then this PR can be closed.\n- Make sure the format of this changelog entry is consistent with the other entries in the file.\n\n<details><summary>Original PR comment posted by @${context.payload.comment.user.login}, using the <code>/changelog</code> slash command:</summary>\n\n${context.payload.comment.body}</details>`,
head: process.env.BRANCH,
base: 'main'
});
core.setOutput('pull-request-number', pullRequest.number);
core.setOutput('pull-request-url', pullRequest.html_url);
- name: Add 'ready-for-doc-review' and 'skip FR board' labels to PR
if: env.CONTINUE_WORKFLOW == 'true'
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd
env:
# Get the number of the PR that was just created:
PULL_REQUEST_NUMBER: ${{ steps.create_pull_request.outputs.pull-request-number }}
with:
github-token: ${{ secrets.DOCS_BOT_PAT_BASE }}
script: |
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: Number(process.env.PULL_REQUEST_NUMBER),
labels: ['ready-for-doc-review','skip FR board']
});
- name: Assign PR to commenter
if: env.CONTINUE_WORKFLOW == 'true'
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd
env:
# Reuse the PR number captured earlier
PULL_REQUEST_NUMBER: ${{ steps.create_pull_request.outputs.pull-request-number }}
with:
github-token: ${{ secrets.DOCS_BOT_PAT_BASE }}
script: |
try {
const username = context.payload.comment.user.login;
await github.rest.issues.addAssignees({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: Number(process.env.PULL_REQUEST_NUMBER),
assignees: [username]
});
} catch (err) {
core.info(`Failed to assign PR to @${context.payload.comment.user.login}: ${err.message}`);
}
- uses: ./.github/actions/slack-alert
if: ${{ failure() && github.event_name != 'workflow_dispatch' }}
with:
slack_channel_id: ${{ secrets.DOCS_ALERTS_SLACK_CHANNEL_ID }}
slack_token: ${{ secrets.SLACK_DOCS_BOT_TOKEN }}
- uses: ./.github/actions/create-workflow-failure-issue
if: ${{ failure() && github.event_name != 'workflow_dispatch' }}
with:
token: ${{ secrets.DOCS_BOT_PAT_BASE }}