Release Helm Chart #50
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Release Helm Chart | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| version: | |
| description: 'Semver version number (e.g., 1.2.3, 1.2.3-prerelease)' | |
| required: true | |
| type: string | |
| services_version: | |
| description: 'Lock onto Braintrust services version (e.g., 1.2.3)' | |
| required: false | |
| type: string | |
| force_republish: | |
| description: 'Re-publish an existing version' | |
| required: false | |
| type: boolean | |
| default: false | |
| env: | |
| CHART_PATH: ./braintrust | |
| # Note: The Chart name is appended automatically by helm to the registry path | |
| ECR_REGISTRY: public.ecr.aws/braintrust/helm | |
| CHART_NAME: braintrust | |
| jobs: | |
| release: | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| packages: write | |
| id-token: write | |
| steps: | |
| - name: Create GitHub App Token | |
| uses: actions/create-github-app-token@d72941d797fd3113feb6b93fd0dec494b13a2547 # v1.12.0 | |
| id: bot-token | |
| with: | |
| app-id: ${{ secrets.GH_BOT_APP_ID }} | |
| private-key: ${{ secrets.GH_BOT_APP_PRIVATE_KEY }} | |
| - name: Checkout code | |
| uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 | |
| with: | |
| token: ${{ steps.bot-token.outputs.token }} | |
| fetch-tags: true | |
| - name: Configure Git | |
| run: | | |
| git config --global user.name "Braintrust Bot" | |
| git config --global user.email "215900051+braintrust-bot[bot]@users.noreply.github.com" | |
| - name: Configure AWS credentials | |
| uses: aws-actions/configure-aws-credentials@7474bc4690e29a8392af63c5b98e7449536d5c3a # v4.3.1 | |
| with: | |
| role-to-assume: ${{ secrets.AWS_ROLE_ARN }} | |
| aws-region: us-east-1 | |
| - name: Login to Amazon ECR Public | |
| id: login-ecr-public | |
| uses: aws-actions/amazon-ecr-login@c962da2960ed15f492addc26fffa274485265950 # v2.0.2 | |
| with: | |
| registry-type: public | |
| - name: Validate and fixup Helm version | |
| run: | | |
| INPUT_VERSION="${{ github.event.inputs.version }}" | |
| # Strip v prefix if present for helm chart version | |
| if [[ $INPUT_VERSION == v* ]]; then | |
| VERSION="${INPUT_VERSION#v}" | |
| echo "ℹ️ Stripped 'v' prefix from version: $INPUT_VERSION -> $VERSION" | |
| else | |
| VERSION="$INPUT_VERSION" | |
| fi | |
| # Check if version matches semver pattern (x.y.z with optional pre-release and build metadata) | |
| if [[ ! $VERSION =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?(\+[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?$ ]]; then | |
| echo "❌ Error: Version '$INPUT_VERSION' is not a valid semver format" | |
| echo "Expected format: x.y.z[-prerelease][+build] (e.g., 1.2.3, v1.2.3, 1.2.3-alpha.1)" | |
| exit 1 | |
| fi | |
| if [[ "${{ github.event.inputs.force_republish }}" != "true" ]]; then | |
| if [[ -n "$(git tag --list "$VERSION")" ]]; then | |
| echo "❌ Error: Version $VERSION already exists" | |
| echo "Please use a different version number" | |
| exit 1 | |
| fi | |
| else | |
| if [[ -z "$(git tag --list "$VERSION")" ]]; then | |
| echo "❌ Error: force_republish=true but tag $VERSION does not exist" | |
| echo "There is no existing release to republish" | |
| exit 1 | |
| fi | |
| echo "⚠️ force_republish=true — will republish from existing tag $VERSION" | |
| fi | |
| # Store the cleaned version for later use | |
| echo "CHART_VERSION=$VERSION" >> $GITHUB_ENV | |
| - name: Validate and fixup services version | |
| run: | | |
| if [ "${{ inputs.services_version }}" != "" ]; then | |
| INPUT_SERVICES_VERSION="${{ inputs.services_version }}" | |
| if [[ $INPUT_SERVICES_VERSION == v* ]]; then | |
| SERVICES_VERSION="$INPUT_SERVICES_VERSION" | |
| else | |
| SERVICES_VERSION="v$INPUT_SERVICES_VERSION" | |
| echo "ℹ️ Added 'v' prefix to services version: ${{ inputs.services_version }} -> $SERVICES_VERSION" | |
| fi | |
| echo "SERVICES_VERSION=$SERVICES_VERSION" >> $GITHUB_ENV | |
| fi | |
| - name: Prepare release branch | |
| run: | | |
| if [[ "${{ github.event.inputs.force_republish }}" == "true" ]]; then | |
| # Capture the SHA from the existing (broken) tag before we delete anything | |
| START_POINT=$(git rev-parse $CHART_VERSION) | |
| echo "ℹ️ Republishing from existing tag $CHART_VERSION @ $START_POINT" | |
| # Delete the existing GitHub release if present | |
| if gh release view $CHART_VERSION &>/dev/null; then | |
| echo "⚠️ Deleting existing release $CHART_VERSION" | |
| gh release delete $CHART_VERSION --yes | |
| fi | |
| # Always delete the tag explicitly | |
| if git ls-remote --exit-code origin refs/tags/$CHART_VERSION &>/dev/null; then | |
| echo "⚠️ Deleting existing tag $CHART_VERSION" | |
| git push origin --delete refs/tags/$CHART_VERSION | |
| fi | |
| # Delete old release branch if it exists | |
| if git ls-remote --exit-code origin refs/heads/release/$CHART_VERSION &>/dev/null; then | |
| echo "⚠️ Deleting existing release branch release/$CHART_VERSION" | |
| git push origin --delete release/$CHART_VERSION | |
| fi | |
| else | |
| # Normal flow publishes from main | |
| START_POINT=origin/main | |
| # Refresh origin/main — it's both the branch point (START_POINT) | |
| # and the fast-forward target at the end of this step. | |
| git fetch origin main | |
| # Fail fast if release branch already exists — indicates a partial release | |
| if git ls-remote --exit-code origin refs/heads/release/$CHART_VERSION &>/dev/null; then | |
| echo "❌ Error: release/$CHART_VERSION already exists — this release may be partially complete" | |
| echo "Use force_republish=true to redo it from scratch" | |
| exit 1 | |
| fi | |
| fi | |
| # Create the release branch from the chosen starting point | |
| git checkout -b release/$CHART_VERSION $START_POINT | |
| # Apply services version lock if provided | |
| if [ "$SERVICES_VERSION" != "" ]; then | |
| ./lock_versions $SERVICES_VERSION | |
| git add . | |
| if ! git diff --staged --quiet; then | |
| git commit -m "Update Braintrust Services versions to $SERVICES_VERSION" | |
| else | |
| echo "No changes to commit for services version update" | |
| fi | |
| fi | |
| # Update Chart version | |
| sed -i "s/^version: .*/version: $CHART_VERSION/" $CHART_PATH/Chart.yaml | |
| git add $CHART_PATH/Chart.yaml | |
| if ! git diff --staged --quiet; then | |
| git commit -m "Update Chart version to $CHART_VERSION" | |
| else | |
| echo "ℹ️ Chart.yaml already at version $CHART_VERSION" | |
| fi | |
| git push origin release/$CHART_VERSION | |
| # In normal mode, fast-forward main to include the version bumps. | |
| # (Skipped for force_republish: the release branch diverges from main.) | |
| if [[ "${{ github.event.inputs.force_republish }}" != "true" ]]; then | |
| git push origin release/$CHART_VERSION:main | |
| fi | |
| env: | |
| GH_TOKEN: ${{ steps.bot-token.outputs.token }} | |
| - name: Create GitHub Release | |
| run: | | |
| gh release create $CHART_VERSION \ | |
| --target release/$CHART_VERSION \ | |
| --draft \ | |
| --title "$CHART_VERSION" \ | |
| --generate-notes | |
| env: | |
| GH_TOKEN: ${{ steps.bot-token.outputs.token }} | |
| - name: Package Helm chart | |
| run: | | |
| helm package $CHART_PATH | |
| mv $CHART_NAME-$CHART_VERSION.tgz $CHART_NAME.tgz | |
| - name: Push chart to ECR Public | |
| id: push-chart | |
| run: | | |
| # Push the chart to ECR Public | |
| helm push $CHART_NAME.tgz oci://$ECR_REGISTRY | |
| # Store chart URL for release notes | |
| echo "chart_url=oci://$ECR_REGISTRY" >> $GITHUB_OUTPUT | |
| # Create job summary | |
| cat >> $GITHUB_STEP_SUMMARY << EOF | |
| ## 📦 Chart Details | |
| - **Chart Name**: ${{ env.CHART_NAME }} | |
| - **Version**: $CHART_VERSION | |
| - **Chart URL**: \`oci://${{ env.ECR_REGISTRY }}\` | |
| EOF | |
| - name: Update Release with Chart Link | |
| run: | | |
| # Get the current release notes | |
| gh release view $CHART_VERSION --json body --jq .body > current_notes.md | |
| # Add Braintrust Services version information if provided | |
| if [ "$SERVICES_VERSION" != "" ]; then | |
| cat >> current_notes.md << EOF | |
| ## 🔧 Braintrust Services | |
| * Updated Braintrust Services to \`$SERVICES_VERSION\` | |
| EOF | |
| fi | |
| # Add chart information to release notes | |
| cat >> current_notes.md << EOF | |
| ## 📦 Helm Chart | |
| - **Chart Name**: ${{ env.CHART_NAME }} | |
| - **Version**: $CHART_VERSION | |
| - **Chart URL**: \`oci://${{ env.ECR_REGISTRY }}\` | |
| ### Installation | |
| \`\`\`bash | |
| helm install braintrust ${{ steps.push-chart.outputs.chart_url }}/${{ env.CHART_NAME }} --version $CHART_VERSION | |
| \`\`\` | |
| EOF | |
| # Update the release with new notes | |
| gh release edit $CHART_VERSION --notes-file current_notes.md --draft=false | |
| env: | |
| GH_TOKEN: ${{ steps.bot-token.outputs.token }} |