Skip to content

Release Management

Release Management #29

Workflow file for this run

name: Release Management
on:
push:
tags:
- 'cli-v*.*.*-*' # e.g. cli-v0.1.0
- 'peng-v*.*.*-*' # e.g. peng-v0.1.0
- 'sdk-v*.*.*-*' # e.g. sdk-v0.1.0
- 'v*.*.*-*' # e.g. v0.1.0
workflow_dispatch: # This is crucial for manual runs
inputs:
test_tag:
description: 'Tag to simulate (e.g., v0.1.0)'
required: true
default: 'v0.1.0'
debug:
description: 'Enable debug logging'
required: false
type: boolean
default: false
jobs:
prepare-release:
runs-on: ubuntu-latest
outputs:
release_type: ${{ steps.release_type.outputs.type }}
version: ${{ steps.release_type.outputs.version }} # Make sure this matches
has_cli: ${{ steps.check_changelog.outputs.has_cli }}
has_planengine: ${{ steps.check_changelog.outputs.has_planengine }}
has_sdk: ${{ steps.check_changelog.outputs.has_sdk }}
steps:
- uses: actions/checkout@v4
- name: Debug Info
if: github.event.inputs.debug == 'true'
run: |
echo "Event name: ${{ github.event_name }}"
echo "Test tag: ${{ github.event.inputs.test_tag }}"
echo "All event inputs: ${{ toJson(github.event.inputs) }}"
- name: Debug prepare-release outputs
run: |
echo "Release type: ${{ steps.release_type.outputs.type }}"
echo "Version: ${{ steps.release_type.outputs.version }}"
echo "Has CLI: ${{ steps.check_changelog.outputs.has_cli }}"
echo "GitHub event name: ${{ github.event_name }}"
echo "Test tag: ${{ github.event.inputs.test_tag }}"
- name: Determine release type and version
id: release_type # This ID is important
run: |
# Enable debug logging if requested
if [[ "${{ github.event.inputs.debug }}" == "true" ]]; then
set -x
fi
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
TEST_TAG="${{ github.event.inputs.test_tag }}"
echo "Running in test mode with tag: $TEST_TAG"
# Use the same tag logic but with test input
if [[ $TEST_TAG == cli-v* ]]; then
echo "type=cli" >> $GITHUB_OUTPUT
echo "version=${TEST_TAG#cli-v}" >> $GITHUB_OUTPUT
elif [[ $TEST_TAG == peng-v* ]]; then
echo "type=controlplane" >> $GITHUB_OUTPUT
echo "version=${TEST_TAG#peng-v}" >> $GITHUB_OUTPUT
elif [[ $TEST_TAG == sdk-v* ]]; then
echo "type=sdk" >> $GITHUB_OUTPUT
echo "version=${TEST_TAG#sdk-v}" >> $GITHUB_OUTPUT
else
echo "type=full" >> $GITHUB_OUTPUT
echo "version=${TEST_TAG#v}" >> $GITHUB_OUTPUT
fi
else
TAG=${GITHUB_REF#refs/tags/}
if [[ $TAG == cli-v* ]]; then
echo "type=cli" >> $GITHUB_OUTPUT
echo "version=${TAG#cli-v}" >> $GITHUB_OUTPUT
elif [[ $TAG == peng-v* ]]; then
echo "type=controlplane" >> $GITHUB_OUTPUT
echo "version=${TAG#peng-v}" >> $GITHUB_OUTPUT
elif [[ $TAG == sdk-v* ]]; then
echo "type=sdk" >> $GITHUB_OUTPUT
echo "version=${TAG#sdk-v}" >> $GITHUB_OUTPUT
else
echo "type=full" >> $GITHUB_OUTPUT
echo "version=${TAG#v}" >> $GITHUB_OUTPUT
fi
# Debug output
echo "Tag: $TAG"
echo "Type: $(cat $GITHUB_OUTPUT | grep type | cut -d= -f2)"
echo "Version: $(cat $GITHUB_OUTPUT | grep version | cut -d= -f2)"
fi
- name: Check for changelog files
id: check_changelog
run: |
VERSION="${{ steps.release_type.outputs.version }}"
RELEASE_TYPE="${{ steps.release_type.outputs.type }}"
echo "Debug: Checking changelogs for version ${VERSION}"
# Check CLI changelog
echo "Checking for CLI changelog at: releases/cli/versions/${VERSION}.md"
if [ -f "releases/cli/versions/${VERSION}.md" ]; then
echo "has_cli=true" >> $GITHUB_OUTPUT
echo "Found CLI changelog"
echo "Content:"
cat "releases/cli/versions/${VERSION}.md"
else
echo "has_cli=false" >> $GITHUB_OUTPUT
echo "No CLI changelog found"
fi
# Check Plan Engine changelog
echo "Checking for Plan Engine changelog at: releases/planengine/versions/${VERSION}.md"
if [ -f "releases/planengine/versions/${VERSION}.md" ]; then
echo "has_planengine=true" >> $GITHUB_OUTPUT
echo "Found Plan Engine changelog"
echo "Content:"
cat "releases/planengine/versions/${VERSION}.md"
else
echo "has_planengine=false" >> $GITHUB_OUTPUT
echo "No Plan Engine changelog found"
fi
# Check SDK changelog
echo "Checking for SDK changelog at: releases/sdks/versions/${VERSION}.md"
if [ -f "releases/sdks/versions/${VERSION}.md" ]; then
echo "has_sdk=true" >> $GITHUB_OUTPUT
echo "Found SDK changelog"
echo "Content:"
cat "releases/sdks/versions/${VERSION}.md"
else
echo "has_sdk=false" >> $GITHUB_OUTPUT
echo "No SDK changelog found"
fi
# Debug output all flags
echo "Final output flags:"
echo "has_cli: $(cat $GITHUB_OUTPUT | grep has_cli || echo 'not set')"
echo "has_planengine: $(cat $GITHUB_OUTPUT | grep has_planengine || echo 'not set')"
echo "has_sdk: $(cat $GITHUB_OUTPUT | grep has_sdk || echo 'not set')"
build-cli:
needs: prepare-release
if: |
needs.prepare-release.outputs.has_cli == 'true' &&
(needs.prepare-release.outputs.release_type == 'cli' || needs.prepare-release.outputs.release_type == 'full')
runs-on: ubuntu-latest
strategy:
matrix:
include:
- os: linux
arch: amd64
binary: orra
- os: darwin
arch: amd64
binary: orra
- os: darwin
arch: arm64
binary: orra
- os: windows
arch: amd64
binary: orra.exe
steps:
- uses: actions/checkout@v4
- name: Set up Go cache
uses: actions/cache@v3
with:
path: |
~/.cache/go-build
~/go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go-
- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: '1.21'
cache: true # Enable Go module cache
- name: Build CLI binary
run: |
mkdir -p dist
cd cli || exit 1
echo "Building binary for ${{ matrix.os }}/${{ matrix.arch }}"
GOOS=${{ matrix.os }} GOARCH=${{ matrix.arch }} go build -v -o ../dist/${{ matrix.binary }}-${{ matrix.os }}-${{ matrix.arch }}
if [ ! -f "../dist/${{ matrix.binary }}-${{ matrix.os }}-${{ matrix.arch }}" ]; then
echo "Failed to build binary"
exit 1
fi
- name: Generate checksum
run: |
cd dist
if [ -f "${{ matrix.binary }}-${{ matrix.os }}-${{ matrix.arch }}" ]; then
sha256sum ${{ matrix.binary }}-${{ matrix.os }}-${{ matrix.arch }} > ${{ matrix.binary }}-${{ matrix.os }}-${{ matrix.arch }}.sha256
else
echo "Binary not found: ${{ matrix.binary }}-${{ matrix.os }}-${{ matrix.arch }}"
exit 1
fi
- name: Upload binary artifacts
uses: actions/upload-artifact@v4
with:
name: cli-${{ matrix.os }}-${{ matrix.arch }}
path: |
dist/${{ matrix.binary }}-${{ matrix.os }}-${{ matrix.arch }}
dist/${{ matrix.binary }}-${{ matrix.os }}-${{ matrix.arch }}.sha256
if-no-files-found: error
retention-days: 5 # Optional: Set retention period
- name: Debug build info
run: |
echo "Go version: $(go version)"
echo "GOOS: ${{ matrix.os }}"
echo "GOARCH: ${{ matrix.arch }}"
echo "Binary name: ${{ matrix.binary }}"
ls -la cli/
ls -la dist/
create-release:
needs: [prepare-release, build-cli]
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4
- name: Debug Info (Test Mode)
if: github.event_name == 'workflow_dispatch'
run: |
echo "This is a test run, skipping actual release"
echo "Would create release with:"
echo "Version: ${{ needs.prepare-release.outputs.version }}"
echo "Release type: ${{ needs.prepare-release.outputs.release_type }}"
- name: Download artifacts
uses: actions/download-artifact@v4
if: needs.prepare-release.outputs.has_cli == 'true'
- name: Prepare release notes
run: |
VERSION=${{ needs.prepare-release.outputs.version }}
RELEASE_TYPE=${{ needs.prepare-release.outputs.release_type }}
echo "Debug: Preparing release notes"
echo "Version: $VERSION"
echo "Release Type: $RELEASE_TYPE"
if [ "$RELEASE_TYPE" = "full" ]; then
echo "# Release v${VERSION}" > RELEASE_NOTES.md
else
echo "# ${RELEASE_TYPE} v${VERSION}" > RELEASE_NOTES.md
fi
echo "" >> RELEASE_NOTES.md
add_component_notes() {
local component=$1
local version=$2
echo "Debug: Checking for ${component} changelog at releases/${component}/versions/${version}.md"
if [ -f "releases/${component}/versions/${version}.md" ]; then
echo "Debug: Found changelog for ${component}"
cat "releases/${component}/versions/${version}.md" >> RELEASE_NOTES.md
echo "" >> RELEASE_NOTES.md
else
echo "Debug: No changelog found for ${component}"
fi
}
if [ "$RELEASE_TYPE" = "full" ]; then
# Only add notes if the component has changes
[ "${{ needs.prepare-release.outputs.has_cli }}" = "true" ] && add_component_notes "cli" "$VERSION" || echo "Skipping CLI notes"
[ "${{ needs.prepare-release.outputs.has_planengine }}" = "true" ] && add_component_notes "controlplane" "$VERSION" || echo "Skipping Plan Engine notes" # Fixed from control-plane to controlplane
[ "${{ needs.prepare-release.outputs.has_sdk }}" = "true" ] && add_component_notes "sdks" "$VERSION" || echo "Skipping SDK notes"
else
add_component_notes "$RELEASE_TYPE" "$VERSION"
fi
echo "Debug: Final RELEASE_NOTES.md content:"
cat RELEASE_NOTES.md
- name: Create GitHub Release
if: github.event_name != 'workflow_dispatch'
uses: softprops/action-gh-release@v1
with:
files: |
cli-*/*
body_path: RELEASE_NOTES.md
draft: true
prerelease: true
token: ${{ secrets.GITHUB_TOKEN }}
- name: Test Release Preview
if: github.event_name == 'workflow_dispatch'
run: |
echo "=== Release Preview ==="
echo "Version: ${{ needs.prepare-release.outputs.version }}"
echo "Release type: ${{ needs.prepare-release.outputs.release_type }}"
echo ""
echo "=== Release Notes Content ==="
cat RELEASE_NOTES.md
echo ""
echo "=== Available Artifacts ==="
ls -R cli-*/* || echo "No CLI artifacts found"
generate-changelogs:
needs: prepare-release
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- uses: actions/checkout@v4
with:
ref: main # Or your default branch
fetch-depth: 0
- name: Configure Git
run: |
git config --local user.email "github-actions[bot]@users.noreply.github.com"
git config --local user.name "github-actions[bot]"
- name: Generate Changelogs
run: |
# Create all changelog directories
mkdir -p releases/cli
mkdir -p releases/planengine
mkdir -p releases/sdks
# CLI Changelog
echo "# CLI Changelog" > releases/cli/CHANGELOG.md
if [ -d "releases/cli/versions" ]; then
find "releases/cli/versions" -name "*.md" -type f -print0 | sort -zr | xargs -0 -I {} bash -c 'cat {} >> releases/cli/CHANGELOG.md; echo "" >> releases/cli/CHANGELOG.md'
fi
# Plan Engine Changelog
echo "# Plan Engine Changelog" > releases/planengine/CHANGELOG.md
if [ -d "releases/planengine/versions" ]; then
find "releases/planengine/versions" -name "*.md" -type f -print0 | sort -zr | xargs -0 -I {} bash -c 'cat {} >> releases/planengine/CHANGELOG.md; echo "" >> releases/planengine/CHANGELOG.md'
fi
# SDK Changelog
echo "# SDK Changelog" > releases/sdks/CHANGELOG.md
if [ -d "releases/sdks/versions" ]; then
find "releases/sdks/versions" -name "*.md" -type f -print0 | sort -zr | xargs -0 -I {} bash -c 'cat {} >> releases/sdks/CHANGELOG.md; echo "" >> releases/sdks/CHANGELOG.md'
fi
- name: Commit updated changelogs
run: |
# Debug output
echo "Debug values:"
echo "Version from needs: ${{ needs.prepare-release.outputs.version }}"
echo "Release type: ${{ needs.prepare-release.outputs.release_type }}"
# Check if there are actual changes in changelog files
CHANGES=$(git diff releases/*/CHANGELOG.md)
if [ -n "$CHANGES" ]; then
echo "Changes detected in changelogs:"
echo "$CHANGES"
VERSION="${{ needs.prepare-release.outputs.version }}"
git add releases/*/CHANGELOG.md
git commit -m "docs: update changelogs for version ${VERSION} [skip ci]"
# Rest of commit/PR logic...
else
echo "No changes detected in changelog files"
exit 0
fi
if [[ -n $(git status --porcelain) ]]; then
VERSION="${{ needs.prepare-release.outputs.version }}"
if [ -z "$VERSION" ]; then
echo "Error: Version is empty"
echo "All prepare-release outputs:"
echo "${{ toJSON(needs.prepare-release.outputs) }}"
exit 1
fi
git add releases/*/CHANGELOG.md
git commit -m "docs: update changelogs for version ${VERSION} [skip ci]"
# Create branch with version
BRANCH_NAME="changelog-update-${VERSION}"
git checkout -b "$BRANCH_NAME"
git push origin "$BRANCH_NAME"
# Create Pull Request
gh pr create \
--title "docs: update changelogs for version ${VERSION}" \
--body "Automated changelog updates for version ${VERSION}" \
--label "documentation" \
--base main \
--head "$BRANCH_NAME"
else
echo "No changelog updates needed"
fi
env:
VERSION: ${{ needs.prepare-release.outputs.version }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Upload changelog artifacts
uses: actions/upload-artifact@v4
with:
name: changelogs
path: releases/**/CHANGELOG.md
retention-days: 5