Skip to content

Commit 549689c

Browse files
hubwriterheiskr
andauthored
Add a workflow to create a CHANGELOG.md update PR (#56079)
Co-authored-by: Kevin Heis <heiskr@users.noreply.github.com>
1 parent 5b75825 commit 549689c

File tree

2 files changed

+175
-0
lines changed

2 files changed

+175
-0
lines changed
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
name: Create a PR to add an entry to the CHANGELOG.md file in this repo
2+
3+
# **What it does**: If a member of the github org posts a changelog comment, it creates a PR to update the CHANGELOG.md file.
4+
# **Why we have it**: This surfaces docs changelog details publicly.
5+
# **Who does it impact**: GitHub users and staff.
6+
7+
on:
8+
issue_comment:
9+
types: [created]
10+
workflow_dispatch:
11+
12+
permissions:
13+
contents: write
14+
pull-requests: write
15+
16+
env:
17+
CHANGELOG_FILE: CHANGELOG.md
18+
19+
jobs:
20+
docs-changelog-pr:
21+
if: ${{ github.repository == 'github/docs-internal' && github.event.issue.pull_request }}
22+
runs-on: ubuntu-latest
23+
24+
steps:
25+
- uses: actions/checkout@v4
26+
27+
- name: 'Ensure ${{ env.CHANGELOG_FILE }} exists'
28+
run: |
29+
if [ ! -f ${{ env.CHANGELOG_FILE }} ]; then
30+
echo "${{ env.CHANGELOG_FILE }} is missing at the root of the repository."
31+
exit 1
32+
fi
33+
34+
- name: Check that the user belongs to the github org
35+
id: hubber_check
36+
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea
37+
with:
38+
github-token: ${{ secrets.DOCS_BOT_PAT_BASE }}
39+
script: |
40+
try {
41+
await github.rest.teams.getMembershipForUserInOrg({
42+
org: 'github',
43+
team_slug: 'employees',
44+
username: context.payload.sender.login,
45+
});
46+
core.exportVariable('CONTINUE_WORKFLOW', 'true');
47+
} catch(err) {
48+
core.info("Workflow triggered by a comment, but the commenter is not a Hubber. Exiting.");
49+
core.exportVariable('CONTINUE_WORKFLOW', 'false');
50+
}
51+
52+
- name: Check if comment starts with '## Changelog summary'
53+
if: env.CONTINUE_WORKFLOW == 'true'
54+
id: check_summary
55+
env:
56+
COMMENT_BODY: ${{ github.event.comment.body }}
57+
run: |
58+
# Get the first line of the comment and trim the leading/trailing whitespace:
59+
FIRST_LINE=$(printf "%s\n" "$COMMENT_BODY" | head -n1 | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
60+
if [[ "$FIRST_LINE" != '## Changelog summary' ]]; then
61+
echo "FIRST_LINE=|$FIRST_LINE|"
62+
echo "The pull request comment is not a changelog summary. Exiting."
63+
echo "CONTINUE_WORKFLOW=false" >> $GITHUB_ENV
64+
fi
65+
66+
- name: Create changelog text
67+
if: env.CONTINUE_WORKFLOW == 'true'
68+
id: create_text
69+
env:
70+
COMMENT_BODY: ${{ github.event.comment.body }}
71+
run: |
72+
set -euo pipefail
73+
DATE=$(date +"**%-d %B %Y**")
74+
BODY="$(printf "%s\n" "$COMMENT_BODY" | tail -n +2)"
75+
CHANGELOG_TEXT="$(printf "%s\n" "$BODY" | awk '/^:writing_hand:/{exit} {print}')"
76+
{
77+
echo "$DATE"
78+
echo -e "$CHANGELOG_TEXT\n<hr>"
79+
} > changelog_entry.txt
80+
81+
- name: Set up git
82+
if: env.CONTINUE_WORKFLOW == 'true'
83+
run: |
84+
git config user.name "github-actions[bot]"
85+
git config user.email "github-actions[bot]@users.noreply.github.com"
86+
87+
- name: Prepare branch
88+
if: env.CONTINUE_WORKFLOW == 'true'
89+
run: |
90+
BRANCH="changelog-update-$(date +%s)"
91+
echo "BRANCH=$BRANCH" >> $GITHUB_ENV
92+
git checkout -b "$BRANCH"
93+
94+
# Insert new changelog entry after the first heading, as follows:
95+
# Print the first line of the existing CHANGELOG.md file into a `tmp` file, followed by an empty line.
96+
# Then, print the contents of `changelog_entry.txt` into the `tmp` file.
97+
# Then, print the rest of the existing CHANGELOG.md file into the `tmp` file.
98+
# Finally, replace the existing CHANGELOG.md file with the `tmp` file.
99+
awk 'NR==1{print; print ""; while ((getline line < "changelog_entry.txt") > 0) print line; next}1' CHANGELOG.md > tmp && mv tmp CHANGELOG.md
100+
101+
git add CHANGELOG.md
102+
git commit -m "Update changelog for $(head -n1 changelog_entry.txt)"
103+
git push origin "$BRANCH"
104+
105+
- name: Create a pull request
106+
if: env.CONTINUE_WORKFLOW == 'true'
107+
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea
108+
id: create_pull_request
109+
with:
110+
github-token: ${{ secrets.DOCS_BOT_PAT_BASE }}
111+
script: |
112+
const { data: pullRequest } = await github.rest.pulls.create({
113+
owner: context.repo.owner,
114+
repo: context.repo.repo,
115+
title: `Update docs changelog (for PR #${context.payload.issue.number})`,
116+
body: `### Automated docs changelog update\n\n**Purpose:** Update the <code>${{ env.CHANGELOG_FILE }}</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**Note for reviewer**: This change to the <code>${{ env.CHANGELOG_FILE }}</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\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>`,
117+
head: process.env.BRANCH,
118+
base: 'main'
119+
});
120+
121+
core.setOutput('pull-request-number', pullRequest.number);
122+
core.setOutput('pull-request-url', pullRequest.html_url);
123+
124+
- name: Add 'ready-for-doc-review' label to PR
125+
if: env.CONTINUE_WORKFLOW == 'true'
126+
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea
127+
env:
128+
# Get the number of the PR that was just created:
129+
PULL_REQUEST_NUMBER: ${{ steps.create_pull_request.outputs.pull-request-number }}
130+
with:
131+
github-token: ${{ secrets.DOCS_BOT_PAT_BASE }}
132+
script: |
133+
await github.rest.issues.addLabels({
134+
owner: context.repo.owner,
135+
repo: context.repo.repo,
136+
issue_number: Number(process.env.PULL_REQUEST_NUMBER),
137+
labels: ['ready-for-doc-review']
138+
});
139+
140+
- uses: ./.github/actions/slack-alert
141+
if: ${{ failure() && github.event_name != 'workflow_dispatch' }}
142+
with:
143+
slack_channel_id: ${{ secrets.DOCS_ALERTS_SLACK_CHANNEL_ID }}
144+
slack_token: ${{ secrets.SLACK_DOCS_BOT_TOKEN }}

CHANGELOG.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Docs changelog
2+
3+
**13 June 2025**
4+
5+
We've published a new article for people learning to code: "[Developing your project locally](https://docs.github.com/en/get-started/learning-to-code/developing-your-project-locally)."
6+
7+
This tutorial helps learners gain core skills needed to set up any project locally by working through an example client-side application using HTML, CSS, and JavaScript. The goal is to help new coders use GitHub tools to recognize patterns across different technologies and build confidence in their ability to set up any project locally.
8+
9+
<hr>
10+
11+
**13 June 2025**
12+
13+
To manage System for Cross-domain Identity Management (SCIM) integration with confidence, customers need to understand the different types of deprovisioning, the actions that trigger them, and their options for reinstating deprovisioned users.
14+
15+
We've published a new article to answer questions around suspending and reinstating Enterprise Managed Users, or users where SCIM is enabled on GitHub Enterprise Server: "[Deprovisioning and reinstating users with SCIM](https://docs.github.com/en/enterprise-cloud@latest/admin/managing-iam/provisioning-user-accounts-with-scim/deprovisioning-and-reinstating-users)".
16+
17+
<hr>
18+
19+
**11 June 2025**
20+
21+
We've added a new scenario-based guide for the Builder persona: "[Using Copilot to explore a codebase](https://docs.github.com/en/copilot/using-github-copilot/guides-on-using-github-copilot/using-copilot-to-explore-a-codebase)."
22+
23+
<hr>
24+
25+
**24 April 2025**
26+
27+
To help learners feel confident they are building real coding skills while using Copilot, we published [Setting up Copilot for learning to code](https://docs.github.com/en/get-started/learning-to-code/setting-up-copilot-for-learning-to-code).
28+
29+
This article helps learners take their first steps in coding with Copilot acting as a tutor, rather than a code completion tool. Configuring Copilot for learning emphasizes skill development and gives learners a way to use Copilot as a daily tool to foster learning and coding independence.
30+
31+
<hr>

0 commit comments

Comments
 (0)