Skip to content
Merged
Show file tree
Hide file tree
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
6 changes: 5 additions & 1 deletion .github/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -258,4 +258,8 @@ Releases are cut from GitHub Actions, never from a local machine.

Stable versions must match `X.Y.Z` and can only be cut from `main`.

The workflow pushes with a token minted from the Portabase GitHub App (`APP_ID` repository variable, `APP_PRIVATE_KEY` secret), scoped to *Contents: write*. The app must be installed on this repository and allowed to push to `main`. A tag pushed with the default `GITHUB_TOKEN` would not trigger the release workflows.
### Beta releases

Every push to `dev` publishes a beta automatically (**Beta release** workflow): no version commit, no Discord notification. The version is the next patch of `pyproject.toml` suffixed with the run number (`26.09.2` → `26.09.3b57`), baked into the binaries at build time and published as a GitHub prerelease. Install it with `portabase config channel beta`; stable users never receive it.

The Bump version workflow pushes with a token minted from the Portabase GitHub App (`APP_ID` repository variable, `APP_PRIVATE_KEY` secret), scoped to *Contents: write*. The app must be installed on this repository and allowed to push to `main`. A tag pushed with the default `GITHUB_TOKEN` would not trigger the release workflows.
58 changes: 58 additions & 0 deletions .github/workflows/beta.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
name: Beta release

on:
push:
branches: [dev]

permissions: {}

concurrency:
group: beta-${{ github.ref }}
cancel-in-progress: false

jobs:
version:
name: version
runs-on: ubuntu-latest
timeout-minutes: 5
permissions:
contents: read
outputs:
version: ${{ steps.compute.outputs.version }}
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4

- id: compute
env:
RUN_NUMBER: ${{ github.run_number }}
run: |
set -euo pipefail
CURRENT=$(sed -n 's/^version = "\(.*\)"/\1/p' pyproject.toml)
if [[ ! "$CURRENT" =~ ^([0-9]+)\.([0-9]+)\.([0-9]+)(.*)$ ]]; then
echo "::error::cannot parse version '$CURRENT' from pyproject.toml"
exit 1
fi
MAJOR=${BASH_REMATCH[1]} MINOR=${BASH_REMATCH[2]} PATCH=${BASH_REMATCH[3]}
PATCH=$((10#$PATCH + 1))
VERSION="$MAJOR.$MINOR.${PATCH}b$RUN_NUMBER"
echo "Beta version: $VERSION"
echo "version=$VERSION" >> "$GITHUB_OUTPUT"

build:
needs: version
permissions:
contents: read
id-token: write
attestations: write
uses: ./.github/workflows/build.yml
with:
version: ${{ needs.version.outputs.version }}

publish:
needs: [version, build]
permissions:
contents: write
uses: ./.github/workflows/publish.yml
with:
prerelease: true
tag: ${{ needs.version.outputs.version }}
13 changes: 13 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@ name: Build binaries

on:
workflow_call:
inputs:
version:
description: "Version baked into the binary. Default: the one in pyproject.toml."
required: false
type: string
default: ""

permissions: {}

Expand Down Expand Up @@ -44,6 +50,13 @@ jobs:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
- uses: ./.github/actions/setup

# perl rather than sed -i, which differs between GNU and BSD (macOS).
- name: Set version
if: inputs.version != ''
env:
VERSION: ${{ inputs.version }}
run: perl -pi -e 's/^version = ".*"/version = "$ENV{VERSION}"/' pyproject.toml

- name: Build
id: build
uses: ./.github/actions/build
Expand Down
16 changes: 16 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ on:
prerelease:
required: true
type: boolean
tag:
description: "Tag to create on the current commit. Default: the pushed tag."
required: false
type: string
default: ""

permissions: {}

Expand All @@ -21,6 +26,15 @@ jobs:
with:
fetch-depth: 0

- name: Create tag
if: inputs.tag != ''
env:
TAG: ${{ inputs.tag }}
run: |
set -euo pipefail
git tag "$TAG" "$GITHUB_SHA"
git push origin "refs/tags/$TAG"

- name: Download binaries
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
with:
Expand All @@ -37,6 +51,7 @@ jobs:
uses: mikepenz/release-changelog-builder-action@c9dc8369bccbc41e0ac887f8fd674f5925d315f7 # v5
with:
mode: COMMIT
toTag: ${{ inputs.tag }}
configurationJson: |
{
"template": "#{{CHANGELOG}}",
Expand All @@ -59,6 +74,7 @@ jobs:
- name: Create GitHub release
uses: softprops/action-gh-release@3bb12739c298aeb8a4eeaf626c5b8d85266b0e65 # v2
with:
tag_name: ${{ inputs.tag }}
files: dist/*
generate_release_notes: false
body: ${{ steps.changelog.outputs.changelog }}
Expand Down
8 changes: 8 additions & 0 deletions .plumber.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
extends: plumber:default
version: "2.0"

github:
controls:
workflowMustIncludeRequiredActions:
enabled: true
required: gitleaks/gitleaks-action AND aquasecurity/trivy-action AND getplumber/plumber
2 changes: 1 addition & 1 deletion uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading