Skip to content

Commit d599649

Browse files
chore(ci): create pull request on changelog update (#2224)
Co-authored-by: Leandro Damascena <[email protected]>
1 parent 9da2ef0 commit d599649

File tree

2 files changed

+132
-11
lines changed

2 files changed

+132
-11
lines changed

Diff for: .github/scripts/create_pr_for_staged_changes.sh

+116
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
#!/bin/bash
2+
set -uxo pipefail # enable debugging, prevent accessing unset env vars, prevent masking pipeline errors to the next command
3+
4+
#docs
5+
#title :create_pr_for_staged_changes.sh
6+
#description :This script will create a PR for staged changes and detect and close duplicate PRs.
7+
#author :@heitorlessa
8+
#date :May 8th 2023
9+
#version :0.1
10+
#usage :bash create_pr_for_staged_changes.sh {git_staged_files_or_directories_separated_by_space}
11+
#notes :Meant to use in GitHub Actions only. Temporary branch will be named $TEMP_BRANCH_PREFIX-$GITHUB_RUN_ID
12+
#os_version :Ubuntu 22.04.2 LTS
13+
#required_env_vars :COMMIT_MSG, PR_TITLE, TEMP_BRANCH_PREFIX, GH_TOKEN, GITHUB_RUN_ID, GITHUB_SERVER_URL, GITHUB_REPOSITORY
14+
#==============================================================================
15+
16+
PR_BODY="This is an automated PR created from the following workflow"
17+
FILENAME=".github/scripts/$(basename "$0")"
18+
readonly PR_BODY
19+
readonly FILENAME
20+
21+
# Sets GitHub Action with error message to ease troubleshooting
22+
function raise_validation_error() {
23+
echo "::error file=${FILENAME}::$1"
24+
exit 1
25+
}
26+
27+
function debug() {
28+
echo "::debug::$1"
29+
}
30+
31+
function notice() {
32+
echo "::notice file=${FILENAME}::$1"
33+
}
34+
35+
function has_required_config() {
36+
# Default GitHub Actions Env Vars: https://docs.github.com/en/actions/learn-github-actions/variables#default-environment-variables
37+
debug "Do we have required environment variables?"
38+
test -z "${TEMP_BRANCH_PREFIX}" && raise_validation_error "TEMP_BRANCH_PREFIX env must be set to create a PR"
39+
test -z "${GH_TOKEN}" && raise_validation_error "GH_TOKEN env must be set for GitHub CLI"
40+
test -z "${COMMIT_MSG}" && raise_validation_error "COMMIT_MSG env must be set"
41+
test -z "${PR_TITLE}" && raise_validation_error "PR_TITLE env must be set"
42+
test -z "${GITHUB_RUN_ID}" && raise_validation_error "GITHUB_RUN_ID env must be set to trace Workflow Run ID back to PR"
43+
test -z "${GITHUB_SERVER_URL}" && raise_validation_error "GITHUB_SERVER_URL env must be set to trace Workflow Run ID back to PR"
44+
test -z "${GITHUB_REPOSITORY}" && raise_validation_error "GITHUB_REPOSITORY env must be set to trace Workflow Run ID back to PR"
45+
46+
set_environment_variables
47+
}
48+
49+
function set_environment_variables() {
50+
WORKFLOW_URL="${GITHUB_SERVER_URL}"/"${GITHUB_REPOSITORY}"/actions/runs/"${GITHUB_RUN_ID}" # e.g., heitorlessa/aws-lambda-powertools-test/actions/runs/4913570678
51+
TEMP_BRANCH="${TEMP_BRANCH_PREFIX}"-"${GITHUB_RUN_ID}" # e.g., ci-changelog-4894658712
52+
53+
export readonly WORKFLOW_URL
54+
export readonly TEMP_BRANCH
55+
}
56+
57+
function has_anything_changed() {
58+
debug "Is there an update to the source code?"
59+
HAS_ANY_SOURCE_CODE_CHANGED="$(git status --porcelain)"
60+
61+
test -z "${HAS_ANY_SOURCE_CODE_CHANGED}" && echo "Nothing to update" && exit 0
62+
}
63+
64+
function create_temporary_branch_with_changes() {
65+
debug "Creating branch ${TEMP_BRANCH}"
66+
git checkout -b "${TEMP_BRANCH}"
67+
68+
debug "Committing staged files: $*"
69+
git add "$@"
70+
git commit -m "${COMMIT_MSG}"
71+
72+
debug "Creating branch remotely"
73+
git push origin "${TEMP_BRANCH}"
74+
}
75+
76+
function create_pr() {
77+
debug "Creating PR against ${BRANCH} branch"
78+
NEW_PR_URL=$(gh pr create --title "${PR_TITLE}" --body "${PR_BODY}: ${WORKFLOW_URL}" --base "${BRANCH}") # e.g, https://github.com/awslabs/aws-lambda-powertools/pull/13
79+
80+
# greedy remove any string until the last URL path, including the last '/'. https://opensource.com/article/17/6/bash-parameter-expansion
81+
NEW_PR_ID="${NEW_PR_URL##*/}" # 13
82+
export NEW_PR_URL
83+
export NEW_PR_ID
84+
}
85+
86+
function close_duplicate_prs() {
87+
debug "Do we have any duplicate PRs?"
88+
DUPLICATE_PRS=$(gh pr list --search "${PR_TITLE}" --json number --jq ".[] | select(.number != ${NEW_PR_ID}) | .number") # e.g, 13\n14
89+
90+
debug "Closing duplicated PRs if any"
91+
echo "${DUPLICATE_PRS}" | xargs -L1 gh pr close --delete-branch --comment "Superseded by #${NEW_PR_ID}"
92+
export readonly DUPLICATE_PRS
93+
}
94+
95+
function report_summary() {
96+
debug "Creating job summary"
97+
echo "### Pull request created successfully :rocket: #${NEW_PR_URL} <br/><br/> Closed duplicated PRs (if any): ${DUPLICATE_PRS}" >>"$GITHUB_STEP_SUMMARY"
98+
99+
notice "PR_URL is ${NEW_PR_URL}"
100+
notice "PR_BRANCH is ${TEMP_BRANCH}"
101+
notice "PR_DUPLICATES are ${DUPLICATE_PRS}"
102+
}
103+
104+
function main() {
105+
# Sanity check
106+
has_anything_changed
107+
has_required_config
108+
109+
create_temporary_branch_with_changes "$@"
110+
create_pr
111+
close_duplicate_prs
112+
113+
report_summary
114+
}
115+
116+
main "$@"

Diff for: .github/workflows/reusable_publish_changelog.yml

+16-11
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,6 @@ name: Build and publish latest changelog
33
on:
44
workflow_call:
55

6-
permissions:
7-
contents: write
8-
96
env:
107
BRANCH: develop
118

@@ -16,6 +13,9 @@ jobs:
1613
concurrency:
1714
group: changelog-build
1815
runs-on: ubuntu-latest
16+
permissions:
17+
contents: write
18+
pull-requests: write
1919
steps:
2020
- name: Checkout repository # reusable workflows start clean, so we need to checkout again
2121
uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2
@@ -30,11 +30,16 @@ jobs:
3030
git pull origin "${BRANCH}"
3131
- name: "Generate latest changelog"
3232
run: make changelog
33-
- name: Update Changelog in trunk
34-
run: |
35-
HAS_CHANGE=$(git status --porcelain)
36-
test -z "${HAS_CHANGE}" && echo "Nothing to update" && exit 0
37-
git add CHANGELOG.md
38-
git commit -m "update changelog with latest changes"
39-
git pull origin "${BRANCH}" # prevents concurrent branch update failing push
40-
git push origin HEAD:refs/heads/"${BRANCH}"
33+
- name: Create PR
34+
run: bash .github/scripts/create_pr_for_staged_changes.sh CHANGELOG.md
35+
env:
36+
COMMIT_MSG: "chore(ci): update changelog with latest changes"
37+
PR_TITLE: "chore(ci): changelog rebuild"
38+
TEMP_BRANCH_PREFIX: "ci-changelog"
39+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
40+
- name: Cleanup orphaned branch
41+
if: failure()
42+
run: git push origin --delete "${TEMP_BRANCH_PREFIX}-${GITHUB_RUN_ID}" || echo "Must have failed before creating temporary branch; no cleanup needed."
43+
env:
44+
TEMP_BRANCH_PREFIX: "ci-changelog"
45+
GITHUB_RUN_ID: ${{ github.run_id }}

0 commit comments

Comments
 (0)