Skip to content

Release All Components with Changes #17

Release All Components with Changes

Release All Components with Changes #17

Workflow file for this run

# Release workflow that automatically detects and releases all components with changes
# This workflow will:
# 1. Check for changes in the main Modular library (excluding modules/ and non-code files)
# 2. If changes exist, trigger the existing release.yml workflow
# 3. Check each module for changes since its last release (excluding tests and docs)
# 4. Trigger module-release.yml workflow for any modules that have changes
#
# Use this workflow when you want to release everything that has changed.
# Use individual workflows (release.yml, module-release.yml) for specific releases.
name: Release All Components with Changes
run-name: Release All Components with Changes
permissions:
contents: write
actions: write
on:
workflow_dispatch:
inputs:
releaseType:
description: 'Release type for all components'
required: true
type: choice
options:
- patch
- minor
- major
default: 'patch'
jobs:
detect-changes:
runs-on: ubuntu-latest
outputs:
main_has_changes: ${{ steps.check_main.outputs.has_changes }}
modules_with_changes: ${{ steps.check_modules.outputs.modules_with_changes }}
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Check for main library changes
id: check_main
run: |
# Find the latest tag for the main library (excluding module tags)
LATEST_TAG=$(git tag -l "v*" | grep -v "/" | sort -V | tail -n1 || echo "")
echo "Latest main library tag: $LATEST_TAG"
# Define patterns for files that should trigger a release
# Include: .go files (except tests), go.mod, go.sum
# Exclude: *_test.go, *.md, .github/*, examples/, cmd/ (if they don't contain logic)
INCLUDE_PATTERNS="*.go go.mod go.sum"
EXCLUDE_PATTERNS="*_test.go *.md .github/* examples/* docs/*"
if [ -z "$LATEST_TAG" ]; then
echo "No previous main library release found, checking if any relevant files exist"
# Check if there are any .go files or go.mod in the root (excluding modules/)
RELEVANT_FILES=$(find . -maxdepth 1 -name "*.go" -o -name "go.mod" -o -name "go.sum" | grep -v test | head -1)
if [ -n "$RELEVANT_FILES" ]; then
HAS_CHANGES=true
else
HAS_CHANGES=false
fi
else
echo "Checking for relevant changes since $LATEST_TAG in main library"
# Get all changed files since the last tag, excluding modules/ directory
CHANGED_FILES=$(git diff --name-only ${LATEST_TAG}..HEAD | grep -v "^modules/" || true)
echo "Files changed since $LATEST_TAG (excluding modules/):"
echo "$CHANGED_FILES"
# Filter for files that should trigger a release
RELEVANT_CHANGES=""
if [ -n "$CHANGED_FILES" ]; then
for file in $CHANGED_FILES; do
# Skip test files
if [[ $file == *_test.go ]]; then
continue
fi
# Skip documentation files
if [[ $file == *.md ]]; then
continue
fi
# Skip github workflows
if [[ $file == .github/* ]]; then
continue
fi
# Skip example files (unless they contain important logic)
if [[ $file == examples/* ]]; then
continue
fi
# Include .go files, go.mod, go.sum
if [[ $file == *.go ]] || [[ $file == go.mod ]] || [[ $file == go.sum ]]; then
RELEVANT_CHANGES="$RELEVANT_CHANGES $file"
fi
done
fi
if [ -n "$RELEVANT_CHANGES" ]; then
echo "Found relevant changes in main library:"
echo "$RELEVANT_CHANGES"
HAS_CHANGES=true
else
echo "No relevant changes found in main library (only tests, docs, or workflows changed)"
HAS_CHANGES=false
fi
fi
echo "has_changes=$HAS_CHANGES" >> $GITHUB_OUTPUT
echo "Main library has changes: $HAS_CHANGES"
- name: Check for module changes
id: check_modules
run: |
# Get list of all modules
MODULES=$(find modules -maxdepth 1 -mindepth 1 -type d -exec basename {} \; | grep -v "README" || true)
echo "Found modules: $MODULES"
MODULES_WITH_CHANGES=""
for MODULE in $MODULES; do
echo "================================================"
echo "Checking module: $MODULE"
# Find the latest tag for this module
LATEST_TAG=$(git tag -l "modules/${MODULE}/v*" | sort -V | tail -n1 || echo "")
echo "Latest tag for $MODULE: $LATEST_TAG"
if [ -z "$LATEST_TAG" ]; then
echo "No previous release found for $MODULE, checking if module has relevant files"
# Check if module has any .go files or go.mod
RELEVANT_FILES=$(find "modules/${MODULE}" -name "*.go" -o -name "go.mod" -o -name "go.sum" | grep -v test | head -1)
if [ -n "$RELEVANT_FILES" ]; then
HAS_CHANGES=true
else
HAS_CHANGES=false
fi
else
echo "Checking for relevant changes since $LATEST_TAG in modules/$MODULE"
# Get all changed files in this module since the last tag
CHANGED_FILES=$(git diff --name-only ${LATEST_TAG}..HEAD -- "modules/${MODULE}" || true)
echo "Files changed in $MODULE since $LATEST_TAG:"
echo "$CHANGED_FILES"
# Filter for files that should trigger a release
RELEVANT_CHANGES=""
if [ -n "$CHANGED_FILES" ]; then
for file in $CHANGED_FILES; do
# Skip test files
if [[ $file == *_test.go ]]; then
continue
fi
# Skip documentation files
if [[ $file == *.md ]]; then
continue
fi
# Include .go files, go.mod, go.sum
if [[ $file == *.go ]] || [[ $file == go.mod ]] || [[ $file == go.sum ]]; then
RELEVANT_CHANGES="$RELEVANT_CHANGES $file"
fi
done
fi
if [ -n "$RELEVANT_CHANGES" ]; then
echo "Found relevant changes in $MODULE:"
echo "$RELEVANT_CHANGES"
HAS_CHANGES=true
else
echo "No relevant changes found in $MODULE (only tests or docs changed)"
HAS_CHANGES=false
fi
fi
if [ "$HAS_CHANGES" = "true" ]; then
echo "$MODULE has changes and needs a release"
MODULES_WITH_CHANGES="$MODULES_WITH_CHANGES $MODULE"
else
echo "$MODULE has no relevant changes"
fi
done
# Clean up the modules list and output as JSON array for matrix
if [ -n "$MODULES_WITH_CHANGES" ]; then
# Convert space-separated list to JSON array (compact format for GitHub Actions)
MODULES_JSON=$(echo "$MODULES_WITH_CHANGES" | tr ' ' '\n' | grep -v '^$' | jq -R . | jq -s . -c)
echo "modules_with_changes=$MODULES_JSON" >> $GITHUB_OUTPUT
echo "Modules with changes: $MODULES_WITH_CHANGES"
else
echo "modules_with_changes=[]" >> $GITHUB_OUTPUT
echo "No modules have relevant changes"
fi
release-main:
needs: detect-changes
if: needs.detect-changes.outputs.main_has_changes == 'true'
uses: ./.github/workflows/release.yml
with:
releaseType: ${{ github.event.inputs.releaseType }}
secrets: inherit
release-modules:
needs: detect-changes
if: needs.detect-changes.outputs.modules_with_changes != '[]'
strategy:
matrix:
module: ${{ fromJson(needs.detect-changes.outputs.modules_with_changes) }}
uses: ./.github/workflows/module-release.yml
with:
module: ${{ matrix.module }}
releaseType: ${{ github.event.inputs.releaseType }}
secrets: inherit
summary:
runs-on: ubuntu-latest
needs: [detect-changes, release-main, release-modules]
if: always()
steps:
- name: Display Release Summary
run: |
echo "================================================"
echo "🎉 RELEASE SUMMARY"
echo "=================="
if [ "${{ needs.detect-changes.outputs.main_has_changes }}" = "true" ]; then
if [ "${{ needs.release-main.result }}" = "success" ]; then
echo "✅ Main library: Released successfully"
else
echo "❌ Main library: Release failed"
fi
else
echo "⏭️ Main library: No relevant changes, no release needed"
fi
MODULES_WITH_CHANGES='${{ needs.detect-changes.outputs.modules_with_changes }}'
if [ "$MODULES_WITH_CHANGES" != "[]" ]; then
echo "📦 Modules:"
if [ "${{ needs.release-modules.result }}" = "success" ]; then
echo "✅ Module releases: Completed successfully"
else
echo "❌ Module releases: Some releases failed"
fi
echo " Modules processed: $(echo '${{ needs.detect-changes.outputs.modules_with_changes }}' | jq -r '.[]' | tr '\n' ' ')"
else
echo "⏭️ Modules: No relevant changes, no releases needed"
fi
echo "================================================"