Skip to content
Merged
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
14 changes: 14 additions & 0 deletions .github/workflows/module-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,20 @@ on:
- minor
- major
default: 'patch'
workflow_call:
inputs:
module:
description: 'Module to release'
required: true
type: string
version:
description: 'Version to release (leave blank for auto-increment)'
required: false
type: string
releaseType:
description: 'Release type'
required: true
type: string

jobs:
prepare-release:
Expand Down
248 changes: 248 additions & 0 deletions .github/workflows/release-all.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,248 @@
# 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
MODULES_JSON=$(echo "$MODULES_WITH_CHANGES" | tr ' ' '\n' | grep -v '^$' | jq -R . | jq -s .)
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 "================================================"
10 changes: 10 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,16 @@ on:
- minor
- major
default: 'patch'
workflow_call:
inputs:
version:
description: 'Version to release (leave blank for auto-increment)'
required: false
type: string
releaseType:
description: 'Release type'
required: true
type: string

jobs:
release:
Expand Down