Skip to content

HUBBERRS

HUBBERRS #102

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
jobs:
docs-changelog-pr:
if: ${{ github.repository == 'github/docs-internal' && github.event.issue.pull_request }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- 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@60a0d83039c74a4aee543508d2ffcb1c3799cdea
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@60a0d83039c74a4aee543508d2ffcb1c3799cdea
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 }}</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>`,
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' label to PR
if: env.CONTINUE_WORKFLOW == 'true'
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea
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']
});
- 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 }}