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
44 changes: 17 additions & 27 deletions .github/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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:
Expand Down
87 changes: 16 additions & 71 deletions .github/workflows/release-recipe.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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: |
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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 }}
77 changes: 70 additions & 7 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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 <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 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 \
Expand All @@ -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