Skip to content
Open
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
21 changes: 21 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
on:
workflow_call:
inputs:
ref:
description: "Branch, tag or SHA to build. Empty = the caller's ref."
required: false
type: string
default: ""
artifact-name:
description: >
Name to upload the build output under. The release flow runs this
workflow twice in one run -- once on the branch, once on the tag -- and
upload-artifact rejects a duplicate name.
required: false
type: string
default: "dist"
workflow_dispatch:
push:
branches:
Expand All @@ -21,7 +35,14 @@ jobs:
matrix:
reqstool-source: [pypi, main]
steps:
# Full history and tags: git-dyn-semver derives the version from git state, so a
# shallow clone would build the wrong number rather than fail.
- uses: actions/checkout@v7
with:
persist-credentials: false
fetch-depth: 0
fetch-tags: true
ref: ${{ inputs.ref || github.ref }}
- name: Set up Java
uses: actions/setup-java@v5
with:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/check-semantic-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ permissions:

jobs:
check:
uses: reqstool/.github/.github/workflows/common-check-semantic-pr.yml@e1d67194373e4da7ccfdf400f46201f18ca14f23 # main 2026-03-07
uses: reqstool/.github/.github/workflows/common-check-semantic-pr.yml@main
11 changes: 0 additions & 11 deletions .github/workflows/check_release.yml

This file was deleted.

30 changes: 0 additions & 30 deletions .github/workflows/publish_plugin_portal.yml

This file was deleted.

114 changes: 114 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
name: Release

# The whole release, start to finish. See RELEASING.md in reqstool/.github for
# what each step does, and for why the release is created as a prerelease rather
# than a draft.

on:
workflow_dispatch:
inputs:
version:
description: "Version to release (Maven, no v prefix), e.g. 1.1.0. Leave empty to auto-detect from Conventional Commits."
required: false
type: string
prerelease:
description: "Publish as a release candidate instead of a release: verified like any release, but never promoted to latest. The number is chosen for you (1.1.0 -> 1.1.0-rc1, then the next)."
required: false
type: choice
options: [none, rc, b, a]
default: none
ref:
description: "Branch to release from. Leave empty for the branch this workflow was dispatched on."
required: false
type: string
force:
description: "Allow a version that disagrees with the auto-detected one."
required: false
type: boolean
default: false
dry-run:
description: "Validate and preview only -- nothing tagged, nothing published."
required: false
type: boolean
default: true

concurrency:
group: release
cancel-in-progress: false

permissions:
contents: read

jobs:
prepare:
uses: reqstool/.github/.github/workflows/common-release-prepare.yml@main
permissions:
contents: read
with:
version-format: maven
version: ${{ inputs.version }}
prerelease: ${{ inputs.prerelease }}
ref: ${{ inputs.ref }}
force: ${{ inputs.force }}
dry-run: ${{ inputs.dry-run }}

# The same checks that guard main, called rather than reimplemented, and run
# before the approval gate so the reviewer approves something already green
# rather than a version string.
checks:
needs: prepare
if: ${{ !inputs.dry-run }}
uses: ./.github/workflows/build.yml
permissions:
contents: read

# THE APPROVAL GATE -- bound to the `stable` environment, so it sits pending
# until a required reviewer approves it on the run page.
tag:
needs: [prepare, checks]
if: ${{ !inputs.dry-run }}
uses: reqstool/.github/.github/workflows/common-release-tag.yml@main
permissions:
contents: write
with:
version: ${{ needs.prepare.outputs.version }}
version-format: maven
ref: ${{ inputs.ref }}

# `./gradlew publishPlugins` builds from the tag itself, so there is no
# separate build step. `version` makes a disagreement a hard stop before
# anything reaches the portal.
publish-to-plugin-portal:
needs: [prepare, tag]
uses: reqstool/.github/.github/workflows/java-publish-to-gradle.yml@main
permissions:
contents: read
secrets: inherit
with:
target: portal
ref: ${{ needs.prepare.outputs.version }}
version: ${{ needs.prepare.outputs.version }}
environment: stable

# Last, deliberately. Everything above can fail, and until this runs nothing
# resolving "the latest release" can see what was built -- the release is still
# a prerelease. Promotion itself is one API call against a release that already
# has its artifacts.
#
# The guard is `no job failed`, not the default `every job succeeded`: a release
# candidate deliberately skips the publish jobs that a real release runs, and a
# skipped dependency would otherwise cascade and skip this too -- leaving the
# candidate unpromoted, which is right, and every *real* release unpromoted the
# moment any optional job is skipped, which is not.
#
# `!inputs.dry-run` has to be spelled out for the same reason: on a dry run
# every job above is skipped, and "nothing failed" would otherwise be true.
promote:
needs: [prepare, publish-to-plugin-portal]
if: ${{ !inputs.dry-run && !cancelled() && !contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled') }}
uses: reqstool/.github/.github/workflows/common-release-promote.yml@main
permissions:
contents: write
with:
version: ${{ needs.prepare.outputs.version }}
prerelease: ${{ needs.prepare.outputs.prerelease == 'true' }}
13 changes: 4 additions & 9 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,13 @@ plugins {
id 'maven-publish'
id 'io.spring.javaformat' version '0.0.47'
id 'com.gradle.plugin-publish' version '2.1.1'
id 'pl.allegro.tech.build.axion-release' version '1.21.3'
}

scmVersion {
tag {
prefix = ''
}
versionCreator 'simple'
// Sets the project version from git tags using Conventional Commits bump
// logic -- the Gradle counterpart to Nisse on the Maven side, so the tag is
// the only version across the org. See RELEASING.md in reqstool/.github.
id 'io.github.jimisola.git-dyn-semver' version '0.1.2'
}

group = 'io.github.reqstool'
version = scmVersion.version

java {
sourceCompatibility = JavaVersion.VERSION_21
Expand Down