From 8daf5194752ed2ff3dab1236ef262c847a32966d Mon Sep 17 00:00:00 2001 From: Marco Walz Date: Fri, 23 Jan 2026 19:36:39 +0100 Subject: [PATCH] chore: simplify release workflow and add interactive makefile prompts --- .github/CONTRIBUTING.md | 44 ++++++-------- .github/workflows/release-recipe.yml | 87 +++++----------------------- Makefile | 77 +++++++++++++++++++++--- 3 files changed, 103 insertions(+), 105 deletions(-) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index bd19d24..b2f56f1 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -90,20 +90,27 @@ Releases are managed automatically through GitHub Actions. Each recipe is versio To create a new release for a recipe: -1. **Create and push a version tag** for the specific recipe: +1. **Use the Makefile** to create and push the release tag: ```bash - # For a Rust recipe release - git tag rust-v4.0.0 - git push origin rust-v4.0.0 + # For a single recipe release + make release-recipe RECIPE=rust VERSION_TAG=v4.0.0 + + # For releasing all recipes with the same version + make release-recipes VERSION_TAG=v1.0.0 ``` + The script will: + - Show a summary of commands to be executed and ask for confirmation + - Create and push the versioned tag (e.g., `rust-v4.0.0`) + - Prompt whether to also update the `-latest` tag + 2. **The workflow automatically**: - - Creates a GitHub release for `rust-v4.0.0` with changelog and release artifacts - - Updates the `rust-latest` tag to point to the same commit as `rust-v4.0.0` - - Creates/updates the `rust-latest` release with: - - The same changelog as `rust-v4.0.0` - - The same release artifacts (but named with "latest") - - A fresh timestamp showing when it was updated + - Creates a GitHub release for the versioned tag with changelog and release artifacts + +3. **If you updated the `-latest` tag**, manually create/update the `-latest` release on GitHub: + - Go to the [Releases page](https://github.com/dfinity/icp-cli-recipes/releases) + - Edit the existing `-latest` release or create a new one + - Use the same release notes as the versioned release ### Release Naming Convention @@ -120,23 +127,6 @@ Release notes are automatically generated and include: - A link to the full changelog comparing the two versions - Release artifacts (tar.gz, zip files, checksums) -### What is the `-latest` Release? - -Each recipe has two types of releases: - -1. **Versioned releases** (e.g., `rust-v4.0.0`): - - Permanent, immutable releases - - Pin to specific versions for stability - - Example: `rust-v4.0.0`, `rust-v3.0.0`, etc. - -2. **Latest release** (e.g., `rust-latest`): - - Always points to the most recent version - - Updated automatically when a new version is released - - Same content as the newest versioned release, but with: - - Updated timestamp - - "latest" naming for artifacts - - Use this to always get the newest recipe version - ### Viewing Releases Each recipe has its own release history: diff --git a/.github/workflows/release-recipe.yml b/.github/workflows/release-recipe.yml index acf3eb1..c5b4900 100644 --- a/.github/workflows/release-recipe.yml +++ b/.github/workflows/release-recipe.yml @@ -4,13 +4,9 @@ on: push: tags: - "rust-v*" - - "rust-latest" - "motoko-v*" - - "motoko-latest" - "asset-canister-v*" - - "asset-canister-latest" - "prebuilt-v*" - - "prebuilt-latest" permissions: contents: write @@ -31,16 +27,8 @@ jobs: RECIPE=$(echo "$TAG" | sed 's/-[^-]*$//') VERSION=$(echo "$TAG" | sed 's/^.*-//') - # Handle latest tags specially - if [ "$VERSION" = "latest" ]; then - echo "recipe=$RECIPE" >> "$GITHUB_OUTPUT" - echo "version=latest" >> "$GITHUB_OUTPUT" - echo "is_latest=true" >> "$GITHUB_OUTPUT" - else - echo "recipe=$RECIPE" >> "$GITHUB_OUTPUT" - echo "version=$VERSION" >> "$GITHUB_OUTPUT" - echo "is_latest=false" >> "$GITHUB_OUTPUT" - fi + echo "recipe=$RECIPE" >> "$GITHUB_OUTPUT" + echo "version=$VERSION" >> "$GITHUB_OUTPUT" - name: Package Recipe run: | @@ -63,55 +51,32 @@ jobs: run: | RECIPE="${{ steps.tag_info.outputs.recipe }}" CURRENT_TAG="${GITHUB_REF#refs/tags/}" - IS_LATEST="${{ steps.tag_info.outputs.is_latest }}" - - if [ "$IS_LATEST" = "true" ]; then - # For -latest tags: find the versioned tag pointing to the same commit - CURRENT_COMMIT=$(git rev-parse HEAD) - CURRENT_VERSION_TAG=$(git tag --sort=-version:refname -l "${RECIPE}-v*" | while read -r tag; do - if [ "$(git rev-parse "$tag")" = "$CURRENT_COMMIT" ]; then - echo "$tag" - break - fi - done) - - if [ -z "$CURRENT_VERSION_TAG" ]; then - echo "::error::No versioned tag found for this commit. A -latest tag must have a corresponding versioned tag (e.g., ${RECIPE}-v1.0.0) on the same commit." - exit 1 - else - echo "Found versioned tag for this commit: ${CURRENT_VERSION_TAG}" - # Find the previous version before the current versioned tag - PREV_TAG=$(git tag --sort=-version:refname -l "${RECIPE}-v*" | grep -v "${CURRENT_VERSION_TAG}" | head -n 1) - echo "previous_tag=${PREV_TAG}" >> "$GITHUB_OUTPUT" - echo "compare_tag=${CURRENT_VERSION_TAG}" >> "$GITHUB_OUTPUT" - fi - else - # For versioned tags: find the previous version tag - PREV_TAG=$(git tag --sort=-version:refname -l "${RECIPE}-v*" | grep -v "${CURRENT_TAG}" | head -n 1) - if [ -z "$PREV_TAG" ]; then - echo "No previous version found for ${RECIPE}" - echo "previous_tag=" >> "$GITHUB_OUTPUT" - else - echo "Found previous tag: ${PREV_TAG}" - echo "previous_tag=${PREV_TAG}" >> "$GITHUB_OUTPUT" - fi - echo "compare_tag=${CURRENT_TAG}" >> "$GITHUB_OUTPUT" + # Find the previous version tag + PREV_TAG=$(git tag --sort=-version:refname -l "${RECIPE}-v*" | grep -v "^${CURRENT_TAG}$" | head -n 1) + + if [ -z "$PREV_TAG" ]; then + echo "No previous version found for ${RECIPE}" + echo "previous_tag=" >> "$GITHUB_OUTPUT" + else + echo "Found previous tag: ${PREV_TAG}" + echo "previous_tag=${PREV_TAG}" >> "$GITHUB_OUTPUT" fi - name: Generate Release Notes Body id: release_notes run: | RECIPE="${{ steps.tag_info.outputs.recipe }}" + VERSION="${{ steps.tag_info.outputs.version }}" PREV_TAG="${{ steps.prev_version.outputs.previous_tag }}" - COMPARE_TAG="${{ steps.prev_version.outputs.compare_tag }}" + CURRENT_TAG="${RECIPE}-${VERSION}" - if [ -n "$PREV_TAG" ] && [ -n "$COMPARE_TAG" ]; then + if [ -n "$PREV_TAG" ]; then echo "## What's Changed" > release_notes.md echo "" >> release_notes.md # Get commits that affect this recipe's directory - COMMITS=$(git log ${PREV_TAG}..${COMPARE_TAG} --pretty=format:"* %s (%h)" --no-merges -- recipes/${RECIPE}/) + COMMITS=$(git log ${PREV_TAG}..${CURRENT_TAG} --pretty=format:"* %s (%h)" --no-merges -- recipes/${RECIPE}/) if [ -n "$COMMITS" ]; then echo "Changes since ${PREV_TAG}:" >> release_notes.md @@ -124,7 +89,7 @@ jobs: fi echo "" >> release_notes.md - echo "**Full Changelog**: https://github.com/${{ github.repository }}/compare/${PREV_TAG}...${COMPARE_TAG}" >> release_notes.md + echo "**Full Changelog**: https://github.com/${{ github.repository }}/compare/${PREV_TAG}...${CURRENT_TAG}" >> release_notes.md else echo "## What's Changed" > release_notes.md echo "" >> release_notes.md @@ -140,23 +105,3 @@ jobs: body_path: release_notes.md env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: Update latest tag - if: steps.tag_info.outputs.is_latest == 'false' - run: | - RECIPE="${{ steps.tag_info.outputs.recipe }}" - CURRENT_TAG="${GITHUB_REF#refs/tags/}" - - echo "Updating ${RECIPE}-latest to point to ${CURRENT_TAG}" - - # Delete the old latest tag locally and remotely - git tag -d ${RECIPE}-latest 2>/dev/null || true - git push origin :refs/tags/${RECIPE}-latest 2>/dev/null || true - - # Create new latest tag pointing to current commit - git tag ${RECIPE}-latest - - # Push the new latest tag - git push origin ${RECIPE}-latest - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/Makefile b/Makefile index ecc864e..5d9c7ac 100644 --- a/Makefile +++ b/Makefile @@ -16,19 +16,54 @@ release-recipes: echo "Usage: make release-recipes VERSION_TAG=v1.0.0"; \ exit 1; \ fi + @echo "" + @echo "=== Release Summary ===" + @echo "Version: $(VERSION_TAG)" + @echo "" + @echo "The following recipes will be released:" + @for recipe in $$(ls recipes/); do \ + echo " - $$recipe-$(VERSION_TAG)"; \ + done + @echo "" + @echo "For each recipe, the following commands will be executed:" + @echo " 1. git tag -a -$(VERSION_TAG) -m \"Release recipe $(VERSION_TAG)\"" + @echo " 2. git push origin -$(VERSION_TAG)" + @echo "" + @echo "This will trigger GitHub Actions to create releases with:" + @echo " - Auto-generated changelogs" + @echo " - Release artifacts (tar.gz, zip, checksums)" + @echo "" + @read -p "Proceed with releases? [y/N] " confirm; \ + if [ "$$confirm" != "y" ] && [ "$$confirm" != "Y" ]; then \ + echo "Releases cancelled."; \ + exit 1; \ + fi + @echo "" @echo "Creating release tags for all recipes with version: $(VERSION_TAG)" @for recipe in $$(ls recipes/); do \ echo "Creating tag for $$recipe: $$recipe-$(VERSION_TAG)"; \ git tag -a "$$recipe-$(VERSION_TAG)" -m "Release $$recipe recipe $(VERSION_TAG)"; \ - echo "Creating/updating latest tag for $$recipe: $$recipe-latest"; \ - git tag -a "$$recipe-latest" -m "Latest $$recipe recipe ($(VERSION_TAG))" -f; \ done + @echo "" @echo "Pushing all recipe tags..." @for recipe in $$(ls recipes/); do \ git push origin "$$recipe-$(VERSION_TAG)"; \ - git push origin "$$recipe-latest" -f; \ done + @echo "" @echo "All recipe release tags created! GitHub Actions will build and publish the releases." + @echo "" + @read -p "Also update all -latest tags to point to this version? [y/N] " answer; \ + if [ "$$answer" = "y" ] || [ "$$answer" = "Y" ]; then \ + for recipe in $$(ls recipes/); do \ + echo "Creating/updating latest tag: $$recipe-latest"; \ + git tag -a "$$recipe-latest" -m "Latest $$recipe recipe ($(VERSION_TAG))" -f; \ + git push origin "$$recipe-latest" -f; \ + done; \ + echo ""; \ + echo "Latest tags updated! Remember to manually create/update the -latest releases on GitHub."; \ + else \ + echo "Skipping latest tags update."; \ + fi release-recipe: @if [ -z "$(RECIPE)" ]; then \ @@ -46,10 +81,38 @@ release-recipe: echo "Available recipes: $$(ls recipes/)"; \ exit 1; \ fi + @echo "" + @echo "=== Release Summary ===" + @echo "Recipe: $(RECIPE)" + @echo "Version: $(VERSION_TAG)" + @echo "" + @echo "The following commands will be executed:" + @echo " 1. git tag -a $(RECIPE)-$(VERSION_TAG) -m \"Release $(RECIPE) recipe $(VERSION_TAG)\"" + @echo " 2. git push origin $(RECIPE)-$(VERSION_TAG)" + @echo "" + @echo "This will trigger GitHub Actions to create a release with:" + @echo " - Auto-generated changelog" + @echo " - Release artifacts (tar.gz, zip, checksums)" + @echo "" + @read -p "Proceed with release? [y/N] " confirm; \ + if [ "$$confirm" != "y" ] && [ "$$confirm" != "Y" ]; then \ + echo "Release cancelled."; \ + exit 1; \ + fi + @echo "" @echo "Creating $(RECIPE) recipe release tag: $(RECIPE)-$(VERSION_TAG)" git tag -a $(RECIPE)-$(VERSION_TAG) -m "Release $(RECIPE) recipe $(VERSION_TAG)" - @echo "Creating/updating latest tag: $(RECIPE)-latest" - git tag -a $(RECIPE)-latest -m "Latest $(RECIPE) recipe ($(VERSION_TAG))" -f git push origin $(RECIPE)-$(VERSION_TAG) - git push origin $(RECIPE)-latest -f - @echo "Release tags created! GitHub Actions will build and publish the releases." + @echo "" + @echo "Release tag created! GitHub Actions will build and publish the release." + @echo "" + @read -p "Also update $(RECIPE)-latest tag to point to this version? [y/N] " answer; \ + if [ "$$answer" = "y" ] || [ "$$answer" = "Y" ]; then \ + echo "Creating/updating latest tag: $(RECIPE)-latest"; \ + git tag -a $(RECIPE)-latest -m "Latest $(RECIPE) recipe ($(VERSION_TAG))" -f; \ + git push origin $(RECIPE)-latest -f; \ + echo ""; \ + echo "Latest tag updated! Remember to manually create/update the $(RECIPE)-latest release on GitHub."; \ + else \ + echo "Skipping latest tag update."; \ + fi