Skip to content

RFC: SDK Release Automation#33

Open
SoulPancake wants to merge 7 commits intomainfrom
enchancement/sdk-release-automation
Open

RFC: SDK Release Automation#33
SoulPancake wants to merge 7 commits intomainfrom
enchancement/sdk-release-automation

Conversation

@SoulPancake
Copy link
Copy Markdown
Member

@SoulPancake SoulPancake commented Mar 12, 2026

Description

RFC proposing the adoption of Release Please to automate the release process for all OpenFGA SDKs, CLI, and extensions.

What problem is being solved?

Releasing a new SDK version is currently a manual process — updating changelogs, bumping version constants, creating signed tags, and pushing them. This overhead discourages frequent releases and leads to large, batched shipments.

How is it being solved?

A workflow_dispatch-triggered GitHub Actions workflow powered by Release Please. A maintainer selects a bump type from the UI, Release Please opens a Release PR with all version bumps and changelog updates, and merging the PR finalizes the release (tag + GitHub Release). Authentication uses a dedicated GitHub App for short-lived, least-privilege tokens.

What changes are made to solve it?

This RFC covers the full design: workflow configuration, x-release-please-version markers for cross-language version bumping, changelog format standardization (GitHub format), Conventional Commits enforcement via PR title validation, GitHub App identity/signing, migration steps, and a phased rollout plan.

Relevant issue: openfga/sdk-generator#679

References

Review Checklist

  • I have clicked on "allow edits by maintainers".
  • I have added documentation for new/changed functionality in this PR or in a PR to openfga.dev [Provide a link to any relevant PRs in the references section above]
  • The correct base branch is being used, if not main
  • I have added tests to validate that the change in functionality is working as expected

@SoulPancake SoulPancake marked this pull request as ready for review March 12, 2026 07:24
Copilot AI review requested due to automatic review settings March 12, 2026 07:24
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds an RFC documenting a proposed standard release automation approach for OpenFGA SDKs (and related repos) using Release Please and a GitHub App-based workflow to generate release PRs, bump versions (including cross-language markers), and publish tags/releases in a consistent way.

Changes:

  • Introduces an RFC describing a two-phase “Release PR → tag/publish” release model powered by Release Please.
  • Specifies conventions for version bumping (x-release-please-version markers) and standardized GitHub-style changelogs.
  • Proposes enforcement of Conventional Commits via PR title validation and outlines migration/rollout steps.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@SoulPancake SoulPancake marked this pull request as draft March 12, 2026 11:20
@SoulPancake SoulPancake marked this pull request as ready for review March 16, 2026 13:47
Copy link
Copy Markdown
Member

@ewanharris ewanharris left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Love this proposal!


A standardized, near-zero-touch release process where:

1. A maintainer triggers the release workflow from the GitHub Actions UI.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given that (I think) we're aiming to be as frictionless in release as possible, how come we're making it run on-demand rather than every push to main? Is it mostly to support the custom version bumps?

I feel like having the open PR would reduce some of the mental overhead of tracking what's in a releasable state and with what

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The auto generated PR can still be enabled with a small tweak in the workflow ( which could always do a auto bump or maybe using this config to always have a patch etc. ) But we also need to be vary about it making mistakes because of release-please not being able to always perfectly decide the right bump if it was previously a non-standard tag.
The manual gate will always work though. So might just be worth having an open PR ready in each repo 🤔

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like triggering the release workflow manually with a desired version number would reduce any potential issues in having a PR always open and constantly getting updated or us merging it by mistake. It's more intentional this way.

Copy link
Copy Markdown
Member Author

@SoulPancake SoulPancake Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, Usually that's the way release-please is used but as long as they don't build good support for non-conventional tags and auto-update it right when coming from nonconventional tags

@ewanharris @sergiught
I think one step or two step, in both the cases
Merging by mistake shouldn't happen in any of them, what are your thoughts about 2 approvals being required?
Something like this

Select the Required number of approvals before merging dropdown menu, then click the number of approving reviews you would like to require on the branch.

Especially/exclusively for release PRs


- **Nightly builds:** Build `main` on every merge (or nightly) to provide users with a "latest" build for testing prior to an official release.

- **Publishing to GitHub Packages Registry (GPR):** Publish SDK artifacts to GPR in addition to the primary language registries (npm, PyPI, Maven Central, NuGet, pkg.go.dev).
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know we've started this so maybe hard to stop, but I'm curious why. Does anyone use it?


| Commit type | Section | Visible |
|---|---|---|
| `feat` | Added | ✅ |
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about "build" PRs? I believe dependabot always opens PRs with "build(something): something".

Copy link
Copy Markdown
Member Author

@SoulPancake SoulPancake Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have navigated that using openfga/vscode-ext#485
It auto prefixes the PRs with these, we can ensure this is configured all across

There was a small issue with this but i have raised an issue with dependabot and they are handling it, This shouldn't affect any of our flows

P.S. The issue is only relevant for existing dependabot PRs that have build(something) , Doesn't affect any of the new/upcoming ones

Copy link
Copy Markdown
Member

@rhamzeh rhamzeh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a section on security:

  • Bot commits and tags MUST be GPG signed with our GPG public key
  • Maintainers must not be able to push tags
  • Both the bot and maintainers must not be able to push directly to main without a codeowner review


The release workflow has two triggers:

- **`push` to `main`** — the job only runs when the head commit message starts with `chore(release)` (the Release PR merge commit title set by Release Please). All other pushes to `main` are skipped entirely.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- **`push` to `main`** — the job only runs when the head commit message starts with `chore(release)` (the Release PR merge commit title set by Release Please). All other pushes to `main` are skipped entirely.
- **`push` to `main`** — the job only runs when the head commit message starts with `release` (the Release PR merge commit title set by Release Please). All other pushes to `main` are skipped entirely.

release-please:
runs-on: ubuntu-latest
# On push: only run when the merge commit is a release PR commit
# (title starts with "chore(release)"). This prevents the job firing on
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# (title starts with "chore(release)"). This prevents the job firing on
# (title starts with "release"). This prevents the job firing on

# On push: only run when the merge commit is a release PR commit
# (title starts with "chore(release)"). This prevents the job firing on
# every single push to main. The release PR merge commit always has this
# title because release-please sets the PR title to "chore(release): ...".
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# title because release-please sets the PR title to "chore(release): ...".
# title because release-please sets the PR title to "release: ...".

# On workflow_dispatch: always run (manual trigger for creating releases).
if: |
github.event_name == 'workflow_dispatch' ||
startsWith(github.event.head_commit.message, 'chore(release)')
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
startsWith(github.event.head_commit.message, 'chore(release)')
startsWith(github.event.head_commit.message, 'release')

Key details:

- **`Generate token`** mints a short-lived GitHub App token at the start of each job. All git operations and GitHub API calls use this App identity — never a personal token or the generic `github-actions[bot]` for PR-facing work.
- **Job-level `if` guard:** On `push` events the job is skipped unless the head commit message starts with `chore(release)` — the title Release Please always gives Release PR merge commits. On `workflow_dispatch` the job always runs.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- **Job-level `if` guard:** On `push` events the job is skipped unless the head commit message starts with `chore(release)` — the title Release Please always gives Release PR merge commits. On `workflow_dispatch` the job always runs.
- **Job-level `if` guard:** On `push` events the job is skipped unless the head commit message starts with `release` — the title Release Please always gives Release PR merge commits. On `workflow_dispatch` the job always runs.


**On push to `main` (Release PR merge):**

When a Release PR is merged, the merge commit message starts with `chore(release):`. The job-level `if` guard matches this pattern, so Release Please runs with `target-branch: main` and finalizes the release — creating the git tag and the GitHub Release. For all other merges to `main`, the job is skipped entirely.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
When a Release PR is merged, the merge commit message starts with `chore(release):`. The job-level `if` guard matches this pattern, so Release Please runs with `target-branch: main` and finalizes the release — creating the git tag and the GitHub Release. For all other merges to `main`, the job is skipped entirely.
When a Release PR is merged, the merge commit message starts with `release:`. The job-level `if` guard matches this pattern, so Release Please runs with `target-branch: main` and finalizes the release — creating the git tag and the GitHub Release. For all other merges to `main`, the job is skipped entirely.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants