Skip to content
Draft
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
119 changes: 119 additions & 0 deletions .github/workflows/openapi-spec-updated.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
name: openapi-spec-updated

# Regenerates the typed client when the ClickFunnels platform publishes a new
# OpenAPI spec.
#
# Trigger: the platform's publishing pipeline sends a repository_dispatch event
# of type `openapi-spec-updated` after a deploy, carrying the published spec's
# SHA-256 in `client_payload.sha256` (the same value the spec endpoint returns
# in its `X-OpenAPI-SHA256` response header). `workflow_dispatch` allows manual
# runs, with an optional expected checksum.
#
# The job fetches the spec from the live API, verifies the checksum, runs the
# existing `make generate` pipeline, sanity-builds, and opens a DRAFT pull
# request when the committed generated files changed. It never pushes to main
# and never merges anything; when the client already matches the spec it exits
# quietly (the codegen is deterministic, so the diff itself is the dedupe).
#
# Repository configuration (Settings -> Secrets and variables -> Actions):
# OPENAPI_SPEC_URL secret - full URL of the spec endpoint
# (GET <api base>/api/v2/openapi.yaml)
# OPENAPI_SPEC_TOKEN secret - an API bearer token authorized to read it

on:
repository_dispatch:
types: [openapi-spec-updated]
workflow_dispatch:
inputs:
sha256:
description: Expected spec SHA-256 (verified when provided)
required: false
type: string

permissions:
contents: write # push the sync branch
pull-requests: write # open the draft PR

concurrency:
group: openapi-spec-sync
cancel-in-progress: false

jobs:
regenerate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: actions/setup-go@v5
with:
go-version-file: go.mod

# `make generate` shells out to npx for the OpenAPI 3.1 -> 3.0 down-convert.
- uses: actions/setup-node@v4
with:
node-version: "22"

- name: Fetch the published spec
env:
SPEC_URL: ${{ secrets.OPENAPI_SPEC_URL }}
SPEC_TOKEN: ${{ secrets.OPENAPI_SPEC_TOKEN }}
run: |
if [ -z "$SPEC_URL" ] || [ -z "$SPEC_TOKEN" ]; then
echo "OPENAPI_SPEC_URL / OPENAPI_SPEC_TOKEN are not configured in this repository's Actions settings." >&2
exit 1
fi
curl -fsSL -H "Authorization: Bearer $SPEC_TOKEN" "$SPEC_URL" -o /tmp/openapi.yaml
sha256sum /tmp/openapi.yaml

- name: Verify the announced checksum
env:
EXPECTED_SHA256: ${{ github.event.client_payload.sha256 || inputs.sha256 }}
run: |
if [ -z "$EXPECTED_SHA256" ]; then
echo "No expected sha256 provided - skipping verification (manual run)."
exit 0
fi
# A mismatch usually means this fetch raced the deploy that published
# the spec; re-run the workflow once the deploy has settled.
echo "$EXPECTED_SHA256 /tmp/openapi.yaml" | sha256sum -c

- name: Regenerate the client
run: make generate SPEC_SRC=/tmp/openapi.yaml

- name: Sanity build and tests
run: |
make vet
make test
make build

- name: Open a draft PR when the generated files changed
env:
GH_TOKEN: ${{ github.token }}
TRIGGER: ${{ github.event_name }}
SOURCE: ${{ github.event.client_payload.source || 'manual' }}
run: |
if git diff --quiet -- internal/api/api.gen.go cmd/operations.gen.go; then
echo "Generated client already matches the published spec - nothing to do."
exit 0
fi
spec_sha=$(sha256sum /tmp/openapi.yaml | cut -d' ' -f1)
branch="openapi-sync/${spec_sha:0:12}"
if gh api "repos/${GITHUB_REPOSITORY}/branches/${branch}" > /dev/null 2>&1; then
echo "Branch ${branch} already exists - a sync PR for this spec is already open."
exit 0
fi
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git checkout -b "$branch"
git add internal/api/api.gen.go cmd/operations.gen.go
git commit -m "Regenerate client from published OpenAPI spec (${spec_sha:0:12})"
git push origin "$branch"
gh pr create --draft \
--title "Regenerate client from published OpenAPI spec (${spec_sha:0:12})" \
--body "Automated sync from the published OpenAPI spec.

- Spec SHA-256: \`${spec_sha}\`
- Trigger: \`${TRIGGER}\` (source: \`${SOURCE}\`)
- Pipeline: \`make generate\` (down-convert -> normalize -> oapi-codegen), then \`make vet && make test && make build\`

Review the generated diff before merging; this PR is never auto-merged."