Skip to content

Release

Release #74

Workflow file for this run

# Axioms of the release pipeline:
# - Each release starts from timefold-solver by running this Github Action.
# - Each individual repository can only start its own release when its dependencies are fully released.
# timefold-solver-enterprise depends on timefold-solver
# timefold-quickstarts depends on timefold-solver
# timefold-website releases last
# - Each individual repository uses 999-SNAPSHOT as its development version, even on micro branches.
#
# Should any of these axioms change, the release pipeline will need to be (significantly) refactored.
# 0.8.x releases existed before this pipeline; they are done differently, similarities are coincidental.
name: Release
on:
workflow_dispatch:
inputs:
version:
description: 'Release version (e.g. 1.0.0)'
required: true
pythonVersionSuffix:
description: 'What suffix to append to the Python version (ex: b0 for beta release)'
required: true
default: b0
sourceBranch:
description: 'Branch to cut the release from'
default: main
required: true
dryRun:
description: 'Do a dry run? (true or false)'
default: true
required: true
jobs:
build:
env:
MAVEN_ARGS: "--no-transfer-progress --batch-mode"
RELEASE_BRANCH_NAME: "__timefold_release_branch__"
runs-on: ubuntu-latest
environment:
name: pypi
url: https://pypi.org/p/timefold
permissions:
contents: write # IMPORTANT: required for action to create release branch
pull-requests: write # IMPORTANT: so release PR can be created
id-token: write # IMPORTANT: mandatory for trusted publishing
steps:
- name: Checkout timefold-solver
uses: actions/checkout@v4
with:
fetch-depth: 0
ref: ${{ github.event.inputs.sourceBranch }}
- name: Delete release branch (if exists)
continue-on-error: true
run: git push -d origin $RELEASE_BRANCH_NAME
- name: Create release branch and switch to it
run: |
git config --global user.name "Timefold Release Bot"
git config --global user.email "[email protected]"
git checkout -b $RELEASE_BRANCH_NAME
- uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
cache: 'maven'
# Need Maven 3.9.0+ to recognize MAVEN_ARGS.
- name: Set up Maven
uses: stCarolas/setup-maven@v5
with:
maven-version: 3.9.3
- name: Python 3.12 Setup
uses: actions/setup-python@v5
with:
python-version: 3.12
- name: Install Pip and build
run: |
python -m pip install --upgrade pip
pip install build
# We skip tests in dry run, to make the process faster.
# Technically, this goes against the main reason for doing a dry run; to eliminate potential problems.
# But unless something catastrophic happened, PR checks on source branch already ensured that all tests pass.
- name: Set release version and build release
run: |
mvn -Dfull versions:set -DnewVersion=${{ github.event.inputs.version }}
sed -i "s/^timefold_solver_python_version.*=.*/timefold_solver_python_version = '${{ github.event.inputs.version }}${{ github.event.inputs.pythonVersionSuffix }}'/" setup.py
mvn -Dfull deploy -DskipTests=${{ github.event.inputs.dryRun }} -DaltDeploymentRepository=local::default::file://`pwd`/target/staging-deploy
python -m build
cp docs/target/antora-template.yml docs/src/antora.yml
git add docs/src/antora.yml
find . -name 'pom.xml' | xargs git add
git config --global user.name "Timefold Release Bot"
git config --global user.email "[email protected]"
git commit -m "build: release version ${{ github.event.inputs.version }}"
git push origin $RELEASE_BRANCH_NAME
- name: Run JReleaser
uses: jreleaser/release-action@v2
env:
JRELEASER_DRY_RUN: ${{ github.event.inputs.dryRun }}
JRELEASER_PROJECT_VERSION: ${{ github.event.inputs.version }}
JRELEASER_GITHUB_TOKEN: ${{ secrets.JRELEASER_GITHUB_TOKEN }}
JRELEASER_GPG_PASSPHRASE: ${{ secrets.JRELEASER_GPG_PASSPHRASE }}
JRELEASER_GPG_PUBLIC_KEY: ${{ secrets.JRELEASER_GPG_PUBLIC_KEY }}
JRELEASER_GPG_SECRET_KEY: ${{ secrets.JRELEASER_GPG_SECRET_KEY }}
JRELEASER_MAVENCENTRAL_USERNAME: ${{ secrets.JRELEASER_MAVEN_CENTRAL_TOKEN_USER }}
JRELEASER_MAVENCENTRAL_PASSWORD: ${{ secrets.JRELEASER_MAVEN_CENTRAL_TOKEN }}
- name: JReleaser release output
uses: actions/upload-artifact@v4
if: always()
with:
name: jreleaser-release
path: |
out/jreleaser/trace.log
out/jreleaser/output.properties
- name: Publish distribution to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
if: ${{ github.event.inputs.dryRun == 'false' }}