diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2f0d9fe..bd19ec8 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -11,6 +11,11 @@ on: 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 @@ -38,6 +43,7 @@ jobs: uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 with: token: ${{ steps.bot-token.outputs.token }} + fetch-tags: true - name: Configure Git run: | @@ -75,10 +81,19 @@ jobs: exit 1 fi - if git tag | grep -q "^$VERSION$"; then - echo "❌ Error: Version $VERSION already exists" - echo "Please use a different version number" - exit 1 + 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 @@ -97,12 +112,50 @@ jobs: echo "SERVICES_VERSION=$SERVICES_VERSION" >> $GITHUB_ENV fi - - name: Update versions + - name: Prepare release branch run: | - git fetch origin main - git checkout main + 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 - # Update services versions if provided + # Apply services version lock if provided if [ "$SERVICES_VERSION" != "" ]; then ./lock_versions $SERVICES_VERSION git add . @@ -119,14 +172,23 @@ jobs: if ! git diff --staged --quiet; then git commit -m "Update Chart version to $CHART_VERSION" else - echo "No changes to commit for Chart version update" + echo "ℹ️ Chart.yaml already at version $CHART_VERSION" fi - git push origin main + 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