Skip to content

Prepare Release

Prepare Release #1

name: Prepare Release
on:
workflow_dispatch:
inputs:
version:
description: 'Release version (e.g., 0.40.0)'
required: true
type: string
dry_run:
description: 'Dry run mode (just show what would happen)'
required: true
type: boolean
default: true
permissions:
contents: write
pull-requests: write
jobs:
prepare-release:
runs-on: ubuntu-latest
environment: release
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Validate inputs
run: |
# Validate version format
if [[ ! "${{ inputs.version }}" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "Error: Version must be in format X.Y.Z (e.g., 0.40.0)"
exit 1
fi
# Check if repository is clean
if [ -n "$(git status --porcelain)" ]; then
echo "Error: Repository has uncommitted changes"
git status
exit 1
fi
- name: Get last released version
id: last_version
run: |
# Get the latest tag
LAST_TAG=$(git tag --list 'v*' --sort=-version:refname | head -n1)
if [ -z "$LAST_TAG" ]; then
echo "No previous tags found"
LAST_VERSION="0.0.0"
else
LAST_VERSION=${LAST_TAG#v}
fi
echo "last_version=$LAST_VERSION" >> $GITHUB_OUTPUT
echo "Last released version: $LAST_VERSION"
echo "New version: ${{ inputs.version }}"
- name: Validate version increment
run: |
LAST_VERSION="${{ steps.last_version.outputs.last_version }}"
NEW_VERSION="${{ inputs.version }}"
# Simple version comparison (assumes semantic versioning)
if [ "$LAST_VERSION" != "0.0.0" ]; then
if ! printf '%s\n%s\n' "$LAST_VERSION" "$NEW_VERSION" | sort -V -C; then
echo "Error: New version $NEW_VERSION is not greater than last version $LAST_VERSION"
exit 1
fi
fi
- name: Extract changelog content
id: changelog
run: |
# Extract content from ## Unreleased section
if [ ! -f "CHANGELOG.md" ]; then
echo "Error: CHANGELOG.md not found"
exit 1
fi
# Get unreleased content
UNRELEASED_CONTENT=$(awk '/^## Unreleased/,/^## \[/ {
if (/^## Unreleased/) next
if (/^## \[/) exit
print
}' CHANGELOG.md | sed '/^$/d')
if [ -z "$UNRELEASED_CONTENT" ]; then
echo "Error: No unreleased content found in CHANGELOG.md"
exit 1
fi
# Save to file for later use
echo "$UNRELEASED_CONTENT" > /tmp/changelog_content.txt
echo "Found changelog content:"
cat /tmp/changelog_content.txt
- name: Update CHANGELOG.md
run: |
# Create new changelog with release section
RELEASE_DATE=$(date -u +"%Y-%m-%d")
NEW_VERSION="${{ inputs.version }}"
# Create temporary file with new content
{
# Keep everything up to ## Unreleased
awk '/^## Unreleased/ {print; exit}' CHANGELOG.md
echo ""
# Add new release section
echo "## [${NEW_VERSION}](https://github.com/open-telemetry/otel-arrow/releases/tag/v${NEW_VERSION}) - ${RELEASE_DATE}"
echo ""
# Add unreleased content
cat /tmp/changelog_content.txt
echo ""
# Add rest of changelog (starting from first existing release)
awk '/^## \[.*\]/ {found=1} found {print}' CHANGELOG.md
} > CHANGELOG.md.tmp
mv CHANGELOG.md.tmp CHANGELOG.md
echo "Updated CHANGELOG.md with release $NEW_VERSION"
- name: Dry run - Show planned changes
if: inputs.dry_run
run: |
echo "=== DRY RUN MODE - No changes will be made ==="
echo ""
echo "Planned changes:"
echo "- New version: ${{ inputs.version }}"
echo "- Last version: ${{ steps.last_version.outputs.last_version }}"
echo ""
echo "Git diff:"
git diff
echo ""
echo "Git operations that would occur:"
echo " - Create branch: release-v${{ inputs.version }}"
echo " - Commit version updates"
echo " - Create pull request"
echo ""
echo "Note: After merging the PR, run the 'Push Release' workflow to create git tags and GitHub release"
- name: Create GitHub App token
if: '!inputs.dry_run'
uses: actions/create-github-app-token@v1
id: app-token
with:
app-id: ${{ vars.OTELBOT_APP_ID }}
private-key: ${{ secrets.OTELBOT_PRIVATE_KEY }}
- name: Create release branch and commit changes
if: '!inputs.dry_run'
run: |
# Configure git
git config user.name otelbot
git config user.email 197425009+otelbot@users.noreply.github.com
# Create and switch to release branch
git checkout -b "otelbot/release-v${{ inputs.version }}"
# Add all changes
git add .
# Commit changes
git commit -m "Prepare release v${{ inputs.version }}
- Update CHANGELOG.md with release notes for v${{ inputs.version }}
This commit prepares the repository for release v${{ inputs.version }}."
# Push branch
git push origin "otelbot/release-v${{ inputs.version }}"
- name: Create pull request
if: '!inputs.dry_run'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
# Create PR body content
cat > /tmp/pr_body.md << 'EOF'
## Release v${{ inputs.version }}
This PR prepares the repository for release v${{ inputs.version }}.
### Changes included:
- Updated CHANGELOG.md with release notes
### Release Notes:
```
$(cat /tmp/changelog_content.txt)
```
### Checklist:
- [ ] Verify CHANGELOG.md formatting and content
- [ ] Confirm all tests pass
- [ ] Ready to merge and tag release
After merging this PR, run the **Push Release** workflow to create git tags and publish the GitHub release.
EOF
# Create the pull request using GitHub CLI
gh pr create \
--title "Release v${{ inputs.version }}" \
--body-file /tmp/pr_body.md \
--head "otelbot/release-v${{ inputs.version }}" \
--base main \
--label release
- name: Summary
run: |
if [ "${{ inputs.dry_run }}" = "true" ]; then
echo ":heavy_check_mark: Dry run completed successfully"
echo "No changes were made to the repository"
echo "Review the planned changes above and run again without dry-run when ready"
else
echo ":heavy_check_mark: Release preparation completed successfully"
echo ""
echo "Next steps:"
echo "1. Review and merge the pull request: https://github.com/open-telemetry/otel-arrow/pulls"
echo "2. After merging, run the 'Push Release' workflow to create git tags and GitHub release"
echo ""
echo "Release branch: otelbot/release-v${{ inputs.version }}"
echo "Release version: v${{ inputs.version }}"
fi