Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<!-- Describe your Pull Request here - anything within the ```s will end up in the changelog -->

## Changelog entry
```
TODO: Replace this inner text with a useful message
for users of the affected modules!
```
147 changes: 147 additions & 0 deletions .github/workflows/actions/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
# GHA does not support dynamic outputs for matrix jobs https://github.com/orgs/community/discussions/26639
# This composite action is a workaround to allow modules to be separately versioned w/o a bunch of hacks
# Whenever https://github.com/actions/runner/pull/2477#issuecomment-2445640849 lands, this can be folded back in
name: 'version-and-doc'
description: 'handle version bumps & doc generation for TF modules monorepo'
inputs:
package-name:
description: 'Package to version bump & doc'
required: true
changelog-entry:
description: 'Changelog contents from PR body'
required: true
release-type:
description: 'Semver release type'
required: true
outputs:
new-version:
description: "Version after bumping"
value: ${{ steps.new-version.outputs.result }}
runs:
using: "composite"
steps:
- name: Render terraform docs inside the README.md and push changes back to PR branch
uses: terraform-docs/gh-actions@v1.3.0
with:
working-dir: ${{ inputs.package-name }}
output-file: README.md
git-push: "true"
config-file: .terraform-docs.yml
- name: Checkout all tags
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Detect previous version number
id: prev-version
env:
PACKAGE_NAME: ${{ inputs.package-name }}
shell: bash
run: |
git fetch --tags
TAG=$(git for-each-ref --sort=-creatordate --count 1 --format="%(refname:short)" "refs/tags/$PACKAGE_NAME-[0-9].[0-9].[0-9]")

if [ -z "$TAG" ] ; then
echo "No git tag found for $PACKAGE_NAME, using 0.0.0 as previous version"
echo "result=0.0.0" >> "$GITHUB_OUTPUT"
exit 0
fi

TAG_VERSION="${TAG#*-}"
echo "TAG_VERSION = $TAG_VERSION"
SEMVER_REGEX="^[0-9].[0-9].[0-9]$"
if [[ $TAG_VERSION =~ $SEMVER_REGEX ]] ; then
echo "$TAG is valid semver, using it"
echo "result=${TAG_VERSION}" >> "$GITHUB_OUTPUT"
exit 0
else
echo "Error: $TAG does not end in a valid semver"
exit 1
fi
- name: Determine new version number
uses: actions/github-script@v7
id: new-version
env:
PREV_VERSION: ${{ steps.prev-version.outputs.result }}
RELEASE_TYPE: ${{ inputs.release-type }}
with:
script: |
const { PREV_VERSION, RELEASE_TYPE } = process.env;
console.log('Previous version was', PREV_VERSION);
console.log('Release type is', RELEASE_TYPE);

const numbers = PREV_VERSION.split('.');
const numberIdx = ['major', 'minor', 'patch'].indexOf(RELEASE_TYPE);
numbers[numberIdx] = parseInt(numbers[numberIdx]) + 1;
for (let i = numberIdx + 1; i < numbers.length; i++) {
numbers[i] = 0;
}
return numbers.join('.');
result-encoding: string
- name: Store version numbers
shell: bash
run: |
mkdir output
echo '${{ steps.prev-version.outputs.result }}' > output/previous-version.txt
echo '${{ steps.new-version.outputs.result }}' > output/new-version.txt
- name: Upload version artifacts
uses: actions/upload-artifact@v4
with:
name: ${{ inputs.package-name }}
path: output
retention-days: 5
- name: Checkout repository
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.ref }}
repository: ${{ github.event.pull_request.head.repo.full_name }}
- name: Sparse checkout unmodified changelogs from main
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.base.ref }}
repository: ${{ github.event.pull_request.base.repo.full_name }}
sparse-checkout: '${{ inputs.package-name }}/'
path: 'old'
- name: Write changelogs(s)
env:
CHANGELOG_ENTRY: ${{ inputs.changelog-entry }}
PACKAGE_NAME: ${{ inputs.package-name }}
NEW_VERSION: ${{ steps.new-version.outputs.result }}
shell: bash
run: |
ORIGINAL_CHANGELOG_PATH="old/$PACKAGE_NAME/CHANGELOG.md"
NEW_CHANGELOG_PATH="$PACKAGE_NAME/CHANGELOG.md"
# Trim off "s that sneak in when passing multiline GHA outputs
CHANGELOG_ENTRY=`sed -e 's/^"//' -e 's/"$//' <<<"$CHANGELOG_ENTRY"`

if [ -f "$ORIGINAL_CHANGELOG_PATH" ] ; then
echo "Changelog already exists for $PACKAGE_NAME, prepending to it"
# Newline literal to pass to sed since it doesn't like /n
nl=$'\n'
sed -i "1i ${CHANGELOG_ENTRY} ${nl}" "$ORIGINAL_CHANGELOG_PATH"
sed -i "1i ## ${NEW_VERSION} ${nl}" "$ORIGINAL_CHANGELOG_PATH"
mv "$ORIGINAL_CHANGELOG_PATH" "$NEW_CHANGELOG_PATH"
else
echo "No existing changelog found for $PACKAGE_NAME, creating one"
echo -e "## $NEW_VERSION" > "$NEW_CHANGELOG_PATH"
echo -e "$CHANGELOG_ENTRY" >> "$NEW_CHANGELOG_PATH"
fi
echo "New changelog contents:"
cat "$NEW_CHANGELOG_PATH"
- name: Commit changelogs(s)
env:
PACKAGE_NAME: ${{ inputs.package-name }}
shell: bash
run: |
rm '.git/COMMIT_EDITMSG' || true # Prevent fatal: could not open '.git/COMMIT_EDITMSG'
git config --global user.name "github-actions[bot]"
git config --global user.email "github-actions[bot]@users.noreply.github.com"
git pull # In case we have multiple changelog updates
git add "$PACKAGE_NAME/CHANGELOG.md"
if ! git diff --quiet --exit-code --cached ; then
echo "Committing changes to CHANGELOG.md"
git commit -m "Automated changelog for $PACKAGE_NAME"
git push
else
echo "No changes to CHANGELOG.md"
exit 0
fi
33 changes: 33 additions & 0 deletions .github/workflows/monorepo-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: 'Monorepo: Release'
on:
repository_dispatch:
types: [monorepo_release]

jobs:

tag:
runs-on: ubuntu-latest
name: 'Tag Releases'
permissions:
contents: write
steps:
- uses: actions/github-script@v7
env:
CLIENT_PAYLOAD: ${{ toJSON(github.event.client_payload) }}
with:
script: |
const { sha, releases } = JSON.parse(process.env.CLIENT_PAYLOAD);

for (const release of releases) {
const tagName = `${release.module}-${release.newVersion}`;

const ref = `refs/tags/${tagName}`;
console.log('Tagging', tagName, 'as', sha);
console.log('Owner', context.repo.owner, 'repo', context.repo.repo);
await github.rest.git.createRef({
owner: context.repo.owner,
repo: context.repo.repo,
ref: ref,
sha: sha
});
}
Loading
Loading