Skip to content
Open
Show file tree
Hide file tree
Changes from 2 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
25 changes: 25 additions & 0 deletions .github/workflows/pkg-go-release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,28 @@ jobs:
sleep 6
done
gh release edit "$TAG" --repo "$REPO" --draft=false

# Once the release is published, open a bump PR against downstream consumers
# of github.com/openfga/language/pkg/go.
downstream-bump:
needs: [finalize-release]
if: startsWith(github.ref, 'refs/tags/')
permissions:
contents: read
strategy:
fail-fast: false
matrix:
target-repo:
- openfga/cli
- openfga/terraform-provider-openfga
uses: ./.github/workflows/reusable-downstream-bump.yaml
with:
target-repo: ${{ matrix.target-repo }}
ecosystem: go
version: ${{ github.ref_name }}
artifact: openfga-language
secrets:
RELEASER_APP_CLIENT_ID: ${{ secrets.RELEASER_APP_CLIENT_ID }}
RELEASER_APP_PRIVATE_KEY: ${{ secrets.RELEASER_APP_PRIVATE_KEY }}
GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }}
GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
24 changes: 24 additions & 0 deletions .github/workflows/pkg-java-release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -121,3 +121,27 @@ jobs:
sleep 6
done
gh release edit "$TAG" --repo "$REPO" --draft=false

# Once the release is published, open a bump PR against downstream consumers
# of dev.openfga:openfga-language.
downstream-bump:
needs: [finalize-release]
if: startsWith(github.ref, 'refs/tags/')
permissions:
contents: read
strategy:
fail-fast: false
matrix:
target-repo:
- openfga/intellij-plugin
uses: ./.github/workflows/reusable-downstream-bump.yaml
with:
target-repo: ${{ matrix.target-repo }}
ecosystem: java
version: ${{ github.ref_name }}
artifact: openfga-language
secrets:
RELEASER_APP_CLIENT_ID: ${{ secrets.RELEASER_APP_CLIENT_ID }}
RELEASER_APP_PRIVATE_KEY: ${{ secrets.RELEASER_APP_PRIVATE_KEY }}
GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }}
GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
24 changes: 24 additions & 0 deletions .github/workflows/pkg-js-release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -107,3 +107,27 @@ jobs:
sleep 6
done
gh release edit "$TAG" --repo "$REPO" --draft=false

# Once the release is published, open a bump PR against downstream consumers
# of @openfga/syntax-transformer.
downstream-bump:
needs: [finalize-release]
if: startsWith(github.ref, 'refs/tags/')
permissions:
contents: read
strategy:
fail-fast: false
matrix:
target-repo:
- openfga/vscode-ext
uses: ./.github/workflows/reusable-downstream-bump.yaml
with:
target-repo: ${{ matrix.target-repo }}
ecosystem: js
version: ${{ github.ref_name }}
artifact: syntax-transformer
secrets:
RELEASER_APP_CLIENT_ID: ${{ secrets.RELEASER_APP_CLIENT_ID }}
RELEASER_APP_PRIVATE_KEY: ${{ secrets.RELEASER_APP_PRIVATE_KEY }}
GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }}
GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
164 changes: 164 additions & 0 deletions .github/workflows/reusable-downstream-bump.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
name: reusable-downstream-bump

# Opens a "bump openfga-language" PR against a downstream repo, authored and
# GPG-signed by the same openfga-releaser-bot identity used by release-please.
#
# Invoked (via a matrix) from the pkg-*-release workflows once a release has
# been published, so downstream consumers pick up the new version automatically.
#
# NOTE: the releaser GitHub App must be installed on each target repo with
# `contents: write` + `pull-requests: write`, otherwise token minting fails.

on:
workflow_call:
inputs:
target-repo:
description: "Downstream repo to bump, e.g. openfga/cli"
type: string
required: true
ecosystem:
description: "js | java | go"
type: string
required: true
version:
description: "Released version (plain semver or a tag ref; normalised)"
type: string
required: true
artifact:
description: "Human name of the bumped artifact, for PR text"
type: string
required: true
secrets:
RELEASER_APP_CLIENT_ID:
required: true
RELEASER_APP_PRIVATE_KEY:
required: true
GPG_PRIVATE_KEY:
required: true
GPG_PASSPHRASE:
required: false

permissions:
contents: read

jobs:
bump:
runs-on: ubuntu-latest
steps:
- name: Normalise version
id: ver
env:
RAW: ${{ inputs.version }}
run: |
set -euo pipefail
v="${RAW##*/}" # strip any pkg/<lang>/ prefix
v="${v#v}" # strip leading v
echo "version=${v}" >> "$GITHUB_OUTPUT"

- name: Split target owner/repo
id: repo
env:
TARGET: ${{ inputs.target-repo }}
run: |
set -euo pipefail
echo "owner=${TARGET%%/*}" >> "$GITHUB_OUTPUT"
echo "name=${TARGET##*/}" >> "$GITHUB_OUTPUT"

# Token scoped to the *target* repo so the bot can push a branch + open a PR.
- name: Generate GitHub App token (target repo)
id: app-token
uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
with:
client-id: ${{ secrets.RELEASER_APP_CLIENT_ID }}
private-key: ${{ secrets.RELEASER_APP_PRIVATE_KEY }}
owner: ${{ steps.repo.outputs.owner }}
repositories: ${{ steps.repo.outputs.name }}
Comment thread
SoulPancake marked this conversation as resolved.

# The bump script lives in *this* repo; check it out separately so we can
# run it against the downstream checkout regardless of downstream layout.
- name: Checkout scripts (this repo)
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
path: _scripts
sparse-checkout: .github/workflows/scripts
sparse-checkout-cone-mode: false

- name: Checkout target repo
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
repository: ${{ inputs.target-repo }}
token: ${{ steps.app-token.outputs.token }}
path: target
fetch-depth: 0

- name: Set up Node (js)
if: inputs.ecosystem == 'js'
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: '24.x'
registry-url: "https://registry.npmjs.org"

- name: Set up Go (go)
if: inputs.ecosystem == 'go'
uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0
with:
go-version: ">=1.25.0"
check-latest: true
Comment thread
SoulPancake marked this conversation as resolved.
Outdated

- name: Import GPG key and enable signed commits
id: import-gpg
uses: crazy-max/ghaction-import-gpg@2dc316deee8e90f13e1a351ab510b4d5bc0c82cd # v7.0.0
with:
gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
passphrase: ${{ secrets.GPG_PASSPHRASE }}
git_user_signingkey: true
git_commit_gpgsign: true
workdir: target

- name: Apply bump and open PR
env:
GH_TOKEN: ${{ steps.app-token.outputs.token }}
ECOSYSTEM: ${{ inputs.ecosystem }}
VERSION: ${{ steps.ver.outputs.version }}
ARTIFACT: ${{ inputs.artifact }}
TARGET_REPO: ${{ inputs.target-repo }}
BOT_EMAIL: ${{ steps.import-gpg.outputs.email }}
working-directory: target
run: |
set -euo pipefail

git config user.name "openfga-releaser-bot"
git config user.email "${BOT_EMAIL}"
git config commit.gpgSign true

BRANCH="chore/bump-${ARTIFACT}-${VERSION}"

# Idempotency: if a bump PR for this exact version is already open, stop.
if gh pr list --repo "${TARGET_REPO}" --state open --head "${BRANCH}" \
--json number --jq '.[0].number' | grep -q '[0-9]'; then
echo "PR for ${BRANCH} already open; nothing to do."
exit 0
fi

git checkout -b "${BRANCH}"

# Apply the edit (script checked out in the sibling _scripts dir).
bash "${GITHUB_WORKSPACE}/_scripts/.github/workflows/scripts/downstream-bump.sh" \
"${ECOSYSTEM}" "${VERSION}"

if git diff --quiet; then
echo "No changes after bump (already up to date); nothing to do."
exit 0
fi

TITLE="chore(deps): bump ${ARTIFACT} to ${VERSION}"
git commit -am "${TITLE}"
git push -f origin "${BRANCH}"
Comment thread
SoulPancake marked this conversation as resolved.
Outdated

BODY="$(printf 'Automated bump of \x60%s\x60 to \x60%s\x60, published from openfga/language.\n\nOpened by openfga-releaser-bot as part of the language release flow.' "${ARTIFACT}" "${VERSION}")"

gh pr create --repo "${TARGET_REPO}" \
--head "${BRANCH}" \
--base "$(gh repo view "${TARGET_REPO}" --json defaultBranchRef --jq '.defaultBranchRef.name')" \
--title "${TITLE}" \
--body "${BODY}"
90 changes: 90 additions & 0 deletions .github/workflows/scripts/downstream-bump.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
#!/usr/bin/env bash
# Applies a version bump of an openfga-language artifact inside a checked-out
# downstream repository. Kept out of the workflow YAML so the edit logic can be
# unit-tested independently (mirrors parse-release.sh).
#
# Run from the root of the *downstream* repo checkout.
#
# Usage:
# downstream-bump.sh js <version> # bumps @openfga/syntax-transformer in
# # client/ and server/ workspaces
# downstream-bump.sh java <version> # bumps dev.openfga:openfga-language in
# # build.gradle.kts
# downstream-bump.sh go <version> # bumps github.com/openfga/language/pkg/go
# # in the module containing go.mod
#
# <version> is the plain semver (e.g. 0.2.2), without a leading "v".
#
# Requires the relevant toolchain on PATH: npm for js, go for go. java needs
# nothing beyond coreutils.
Comment thread
Copilot marked this conversation as resolved.
Outdated
set -euo pipefail

ecosystem="${1:?ecosystem required: js|java|go}"
version="${2:?version required}"

# Normalise: callers may pass a tag ref like "pkg/js/v0.2.2" or "v0.2.2".
version="${version##*/}" # strip any "pkg/<lang>/" prefix
version="${version#v}" # strip a leading "v"

case "${ecosystem}" in
js)
# Update each workspace that declares the dependency. npm rewrites both
# package.json (to ^<version>) and package-lock.json (with the correct
# integrity hash + refreshed transitive deps), matching the manual PRs.
found=0
for dir in client server; do
if [[ -f "${dir}/package.json" ]] \
&& grep -q '@openfga/syntax-transformer' "${dir}/package.json"; then
echo "Bumping @openfga/syntax-transformer in ${dir}/"
( cd "${dir}" && npm install "@openfga/syntax-transformer@^${version}" )
found=1
fi
done
if [[ "${found}" -eq 0 ]]; then
echo "No workspace declares @openfga/syntax-transformer" >&2
exit 1
fi
;;

java)
file="build.gradle.kts"
[[ -f "${file}" ]] || file="build.gradle"
if [[ ! -f "${file}" ]]; then
echo "No build.gradle(.kts) found" >&2
exit 1
fi
if ! grep -q 'dev\.openfga:openfga-language:' "${file}"; then
echo "${file} does not depend on dev.openfga:openfga-language" >&2
exit 1
fi
echo "Bumping dev.openfga:openfga-language to ${version} in ${file}"
# Replace the version segment of the coordinate, whatever it currently is
# (e.g. 0.2.0-beta.2 -> 0.2.1). Only touch chars up to the closing quote.
# perl for portability (GNU vs BSD sed differ on -i / backrefs).
perl -i -pe "s/(dev\.openfga:openfga-language:)[^\"]+/\${1}${version}/g" "${file}"
Comment thread
SoulPancake marked this conversation as resolved.
Outdated
;;

go)
module="github.com/openfga/language/pkg/go"
if [[ ! -f "go.mod" ]]; then
echo "No go.mod in current directory" >&2
exit 1
fi
if ! grep -q "${module}" go.mod; then
echo "go.mod does not require ${module}" >&2
exit 1
fi
echo "Bumping ${module} to v${version}"
# proxy.golang.org first; fall back to direct if the tag isn't indexed yet.
export GOPROXY="proxy.golang.org,direct"
go get "${module}@v${version}"
go mod tidy
;;

*)
echo "Unknown ecosystem: ${ecosystem} (expected js|java|go)" >&2
exit 1
;;
esac

echo "Bump applied for ${ecosystem} -> ${version}"
Loading