From 0759613e8e6ddbec50b537400a19417ba41ee5ec Mon Sep 17 00:00:00 2001 From: Brad Jorsch Date: Wed, 22 Nov 2023 15:51:28 -0500 Subject: [PATCH] ci: Automatically tag project releases This will automatically create tags like "packages/autoloader@3.0.2" or "plugins/jetpack@12.9" as projects are released. The logic used is similar to the autotagger: on push to trunk or prerelease for projects without a release-branch-prefix and on push to corresponding release branches for projects with a release-branch-prefix, if the `/changelog/` directory for the project is empty and the first entry in CHANGELOG.md is a release version number, it'll create the corresponding tag for the project. --- .github/workflows/autotagger.yml | 86 ++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 .github/workflows/autotagger.yml diff --git a/.github/workflows/autotagger.yml b/.github/workflows/autotagger.yml new file mode 100644 index 0000000000000..b41bf8e530bfe --- /dev/null +++ b/.github/workflows/autotagger.yml @@ -0,0 +1,86 @@ +name: Monorepo Auto-tagger + +on: + push: + branches: + - trunk + - prerelease + - '*/branch-*' + +jobs: + tag: + name: Tag + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Fetch tags, shallowly and treeless + run: | + git fetch --depth=1 --filter=tree:0 origin 'refs/tags/*:refs/tags/*' + + - name: Tag projects + run: | + REF=${GITHUB_REF#refs/heads/} + if [[ "$REF" == */branch-* ]]; then + PROJECTS="$(jq -r --arg P "${REF%%/branch-*}" '.extra["release-branch-prefix"] | if type == "array" then . else [ . ] end | if index( $P ) then input_filename | match( "^projects/([^/]+/[^/]+)/composer.json$" ).captures[0].string else empty end' projects/*/*/composer.json)" + if [[ -n "$PROJECTS" ]]; then + echo "Branch $REF seems to be a release branch, checking matching projects." + else + echo "::notice::Branch $REF seems to be a release branch, but nothing uses that prefix so not checking any projects." + exit 0 + fi + else + PROJECTS="$(jq -r 'if .extra["release-branch-prefix"] then empty else input_filename | match( "^projects/([^/]+/[^/]+)/composer.json$" ).captures[0].string end' projects/*/*/composer.json)" + if [[ -n "$PROJECTS" ]]; then + echo "Branch $REF is not a release branch, checking only projects without a release-branch-prefix." + else + echo "::notice::Branch $REF is not a release branch, but somehow no projects lack a release-branch-prefix?" + exit 0 + fi + fi + + TAGS=() + while IFS= read -r SLUG; do + echo "Checking $SLUG..." + cd "$GITHUB_WORKSPACE/projects/$SLUG" + + CHANGES_DIR=$(jq -r '.extra.changelogger["changes-dir"] // "changelog"' composer.json) + if [[ ! -d "$CHANGES_DIR" || -n "$(ls -- "$CHANGES_DIR")" ]]; then + echo " Project $SLUG has changes in projects/$SLUG/$CHANGES_DIR/, not tagging." + continue + fi + + VER=$(sed -nEe 's/^## \[?([^]]*)\]? - .*/\1/;T;p;q' CHANGELOG.md || true) + echo " Version from changelog is ${VER:-}" + if [[ "$VER" =~ ^[0-9]+(\.[0-9]+)+$ ]]; then + echo " Version $VER ok to tag" + TAGS+=( "$SLUG@$VER" ) + else + echo " Not tagging version $VER" + fi + done <<<"$PROJECTS" + + if [[ ${#TAGS[@]} -eq 0 ]]; then + echo "::notice::Nothing to tag." + exit 0 + fi + + export GIT_AUTHOR_NAME=matticbot + export GIT_AUTHOR_EMAIL=matticbot@users.noreply.github.com + export GIT_COMMITTER_NAME=matticbot + export GIT_COMMITTER_EMAIL=matticbot@users.noreply.github.com + + echo "Creating tags..." + TOPUSH=() + for T in "${TAGS[@]}"; do + if git tag "$T"; then + TOPUSH+=( "$T" ) + fi + done + if [[ ${#TOPUSH[@]} -gt 0 ]]; then + echo "Pushing tags..." + git push origin "${TOPUSH[@]}" + echo "::notice::Created tags: ${TOPUSH[*]}" + else + echo "::notice::No tags needed creation." + fi