Skip to content
Merged
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
50 changes: 45 additions & 5 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ jobs:
contents: write
packages: write
runs-on: ubuntu-latest
outputs:
# Gates the docs deploy on the release actually existing rather than on this
# job's overall conclusion, so a failure in a downstream distribution channel
# (Homebrew, ghcr) cannot skip the schema publish.
published: ${{ steps.released.outputs.published }}
version: ${{ steps.version.outputs.version }}
steps:
- uses: actions/checkout@v7
with:
Expand All @@ -34,13 +40,26 @@ jobs:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}

# Idempotent so a release that failed partway (e.g. a bad tap credential)
# can be re-dispatched with the same tag instead of dying here.
- name: Create Tag
if: ${{ github.event.inputs.tag != '' }}
run: |
git tag ${{ github.event.inputs.tag }}
git push origin ${{ github.event.inputs.tag }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAG: ${{ github.event.inputs.tag }}
run: |
set -euo pipefail
if git rev-parse -q --verify "refs/tags/${TAG}" >/dev/null; then
echo "Tag ${TAG} already exists locally - reusing"
elif git ls-remote --exit-code --tags origin "refs/tags/${TAG}" >/dev/null 2>&1; then
echo "Tag ${TAG} already exists on origin - fetching"
git fetch origin "refs/tags/${TAG}:refs/tags/${TAG}"
else
git tag "${TAG}"
git push origin "${TAG}"
fi

- name: Extract version from tag
id: version
run: |
Expand All @@ -51,8 +70,10 @@ jobs:
fi
echo "version=${VERSION}" >> $GITHUB_OUTPUT
echo "Releasing version: ${VERSION}"

- name: Install release tools
run: go install github.com/goreleaser/goreleaser/v2@v2.12.5

- uses: flowexec/action@v1
with:
executable: 'publish release --param VERSION=${{ steps.version.outputs.version }}'
Expand All @@ -62,15 +83,34 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
HOMEBREW_FLOW_GITHUB_TOKEN: ${{ secrets.HOMEBREW_FLOW_GITHUB_TOKEN }}

# Records whether the GitHub release exists, regardless of what happened
# after it was cut. Runs even on failure so the docs gate is accurate.
- name: Check release published
id: released
if: always()
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
if gh release view "${{ steps.version.outputs.version }}" \
--repo "${{ github.repository }}" >/dev/null 2>&1; then
echo "published=true" >> $GITHUB_OUTPUT
echo "Release ${{ steps.version.outputs.version }} is published."
else
echo "published=false" >> $GITHUB_OUTPUT
echo "Release ${{ steps.version.outputs.version }} was NOT published."
fi

# Publishing the docs is part of releasing: the site serves the JSON schemas
# that editors validate flowfiles against, so skipping it ships a release whose
# schema the world cannot see. This runs here rather than off the tag push
# because a tag pushed with GITHUB_TOKEN does not trigger workflows.
release-docs:
needs: release-binary
# Only for a dispatched release. A tag pushed by a human triggers
# Gate on the release having been published, not on release-binary's overall
# conclusion - a Homebrew or ghcr failure must not stop the schemas shipping.
# Only for a dispatched release: a tag pushed by a human triggers
# release-docs.yaml on its own, and calling it here too would deploy twice.
if: github.event_name == 'workflow_dispatch'
if: ${{ always() && github.event_name == 'workflow_dispatch' && needs.release-binary.outputs.published == 'true' }}
permissions:
contents: read
uses: ./.github/workflows/release-docs.yaml
Expand Down