Use an action from this repo in your workflow like this:
- name: Pull MindsDB Github Actions
uses: actions/checkout@v4
with:
repository: mindsdb/github-actions
path: github-actions
- uses: ./github-actions/<action-name>
NOTE: This needs to go AFTER any actions/checkout step for the current repo
Three reusable workflows automate the weekly staging → main release cycle.
They live in .github/workflows/ and are called from ~25-line per-repo wrappers
(same pattern as stale-deploy-label.yml):
| Reusable workflow | Name (keep identical in callers) | What it does |
|---|---|---|
release-freeze.yml |
Staging Freeze |
Activates the staging-freeze ruleset to lock staging (skips if staging == main) |
release-pr.yml |
Create staging to main release PR |
Opens the staging → main PR (idempotent) |
release-unfreeze.yml |
Staging Unfreeze |
Disables the ruleset when the release PR merges, then syncs main back into staging |
The chain is event-driven: Staging Freeze finishing fires the release-PR
workflow via workflow_run; merging that PR fires Staging Unfreeze. The
workflow_run link matches on the caller workflow's name, so callers must
keep the names above verbatim.
mindsdb-release-trainGitHub App withAdministration,Contents, andPull requests: write, installed on each repo, and set as a bypass actor on thestagingruleset. Per-job tokens are minted withactions/create-github-app-token.vars.RELEASE_APP_CLIENT_ID(org variable) andsecrets.RELEASE_APP_PRIVATE_KEY(org secret) — the private key reaches the reusable workflows viasecrets: inheritin the caller.- A pre-provisioned
staging-freezeruleset in each repo: oneupdaterule targetingstaging, createddisabled, with the App as bypass actor. The workflows only flip itsenforcementbetweenactiveanddisabled— they never touch the underlying branch protection.
Drop these three files into each repo's .github/workflows/. Adjust the cron
per repo if desired; branch names default to staging/main.
Pinning: the examples below use
@mainfor readability. For production, pin eachuses:to a full commit SHA with a version comment (e.g.…/release-freeze.yml@<sha> # v1) so Dependabot can manage bumps.
staging-freeze.yml:
name: Staging Freeze
on:
schedule:
# Friday 13:47 UTC — off the top of the hour (GitHub's documented high-load
# slot) and off a DST-sensitive "6am PST" wording.
- cron: '47 13 * * 5'
workflow_dispatch:
permissions:
contents: read
jobs:
freeze:
uses: mindsdb/github-actions/.github/workflows/release-freeze.yml@main
secrets: inheritweekly-merge-staging.yml:
name: Create staging to main release PR
on:
workflow_run:
workflows: ["Staging Freeze"]
types: [completed]
workflow_dispatch:
permissions:
contents: read
jobs:
create-pr:
if: >
github.event_name == 'workflow_dispatch' ||
github.event.workflow_run.conclusion == 'success'
uses: mindsdb/github-actions/.github/workflows/release-pr.yml@main
secrets: inheritstaging-unfreeze.yml:
name: Staging Unfreeze
on:
pull_request:
types: [closed]
branches: [main]
workflow_dispatch:
permissions:
contents: read
jobs:
unfreeze:
if: >
github.event_name == 'workflow_dispatch' ||
(github.event.pull_request.merged == true &&
github.event.pull_request.head.ref == 'staging' &&
github.event.pull_request.head.repo.full_name == github.repository)
uses: mindsdb/github-actions/.github/workflows/release-unfreeze.yml@main
secrets: inherit