@@ -13,6 +13,11 @@ name: Release
1313on :
1414 workflow_dispatch :
1515 inputs :
16+ deploy-to-maven :
17+ description : ' Deploy artifacts to Maven Central?'
18+ type : boolean
19+ required : true
20+ default : false
1621 version :
1722 description : ' Release version (e.g. 2.0.0)'
1823 required : true
@@ -29,13 +34,18 @@ jobs:
2934 env :
3035 MAVEN_ARGS : " --no-transfer-progress --batch-mode"
3136 RELEASE_BRANCH_NAME : " __timefold_release_branch__"
37+ VERSION : ${{ github.event.inputs.version }}
38+ TAG_NAME : v${{ github.event.inputs.version }}
3239 runs-on : self-hosted
3340 permissions :
3441 contents : write # IMPORTANT: required for action to create release branch
3542 pull-requests : write # IMPORTANT: so release PR can be created
3643 id-token : write # IMPORTANT: mandatory for trusted publishing
3744 attestations : write # IMPORTANT: mandatory for attestations
3845 steps :
46+ - name : Print inputs to the release workflow
47+ run : echo "${{ toJSON(github.event.inputs) }}"
48+
3949 - name : Validate source branch and the version
4050 shell : bash
4151 env :
@@ -47,45 +57,113 @@ jobs:
4757 exit 1
4858 fi
4959
50- - name : Checkout timefold-solver
60+ # #####
61+ # 1 - Check out the tag when deploying in Maven or check out the source branch instead
62+ # #####
63+ - name : Checkout the timefold-solver v${{ github.event.inputs.version }} tag
64+ if : ${{ inputs.deploy-to-maven }}
5165 uses : actions/checkout@v6
5266 with :
5367 fetch-depth : 0
68+ # We fetch the tag when publishing artifacts to Maven
69+ ref : ${{ env.TAG_NAME }}
70+
71+ - name : Checkout timefold-solver ${{ github.event.inputs.sourceBranch }} branch
72+ if : ${{ !inputs.deploy-to-maven }}
73+ uses : actions/checkout@v6
74+ with :
75+ fetch-depth : 0
76+ # We always fetch the source branch when publishing artifacts to JFrog
5477 ref : ${{ github.event.inputs.sourceBranch }}
5578
56- - name : Delete release branch (if exists)
79+ # #####
80+ # 2 - Set up the JDK
81+ # #####
82+ - uses : actions/setup-java@v5
83+ with :
84+ java-version : ' 25'
85+ distribution : ' temurin'
86+ cache : ' maven'
87+
88+ # #####
89+ # 3 - Clean up the release branch when deploying in Maven or clean up the tag instead
90+ # #####
91+ - name : Delete release branch from timefold-solver (if exists)
92+ if : ${{ inputs.deploy-to-maven }}
5793 continue-on-error : true
5894 run : git push -d origin $RELEASE_BRANCH_NAME
5995
60- - name : Create release branch and switch to it
96+ - name : Delete tag from timefold-solver (if exists)
97+ if : ${{ !inputs.deploy-to-maven }}
98+ continue-on-error : true
99+ run : |
100+ git tag -d $TAG_NAME
101+ git push -d origin $TAG_NAME
102+
103+ # #####
104+ # 4 - Create the release branch from the tag when deploying in Maven
105+ # or create the artifact file and push the tag to the solver repository
106+ # #####
107+ - name : Create release branch for timefold-solver and switch to it
108+ if : ${{ inputs.deploy-to-maven }}
61109 run : |
62110 git config user.name "Timefold Release Bot"
63111 git config user.email "release@timefold.ai"
64112 git checkout -b $RELEASE_BRANCH_NAME
65113
66- - uses : actions/setup-java@v5
67- with :
68- java-version : ' 25'
69- distribution : ' temurin'
70- cache : ' maven'
71-
72- # We skip tests in dry run, to make the process faster.
73- # Technically, this goes against the main reason for doing a dry run; to eliminate potential problems.
74- # But unless something catastrophic happened, PR checks on source branch already ensured that all tests pass.
75- - name : Set release version and build release
114+ - name : Set release version and push tag to timefold-solver
115+ if : ${{ !inputs.deploy-to-maven }}
76116 env :
77- VERSION : ${{ github.event.inputs.version }}
78117 DRY_RUN : ${{ github.event.inputs.dryRun }}
79118 run : |
80- ./mvnw -Dfull versions:set -DnewVersion=$VERSION
81- ./mvnw -Dfull deploy -DskipTests=$DRY_RUN -DaltDeploymentRepository=local::default::file://`pwd`/target/staging-deploy
119+ ./mvnw -Dfull versions:set -DnewVersion=$VERSION -DgenerateBackupPoms=false
120+ # We skip tests in dry run, to make the process faster
121+ ./mvnw -Dfull clean deploy -DskipTests=$DRY_RUN -DaltDeploymentRepository=local::default::file://`pwd`/target/staging-deploy
122+ # Temporally disabled
123+ #./mvnw -Dfull verify --file model/test-model/pom.xml
82124 cp docs/target/antora.yml docs/src/antora.yml
83125 git add docs/src/antora.yml
84126 find . -name 'pom.xml' | xargs git add
127+ # Create a compressed file containing all the artifacts
128+ tar cvzf artifacts.tar.gz target/staging-deploy
129+ git add artifacts.tar.gz
85130 git commit -m "build: release version $VERSION"
131+ git tag $TAG_NAME
132+ git push origin $TAG_NAME
133+
134+ # #####
135+ # 5 - Restore the artifacts
136+ # #####
137+ - name : Restore the artifacts for deploying timefold-solver
138+ if : ${{ inputs.deploy-to-maven }}
139+ run : |
140+ # Restore all the artifacts
141+ tar xvzf artifacts.tar.gz
142+ # Remove the artifact file from the release branch
143+ rm artifacts.tar.gz
144+ git commit -m "chore: clean up"
86145 git push origin $RELEASE_BRANCH_NAME
87146
88- - name : Run JReleaser
147+ # #####
148+ # 6 - Publish the artifacts of the solver and enterprise repositories
149+ # #####
150+ - name : Publish timefold-solver to JFrog
151+ if : ${{ !inputs.deploy-to-maven }}
152+ uses : jreleaser/release-action@80ffb38fa759704eed4db5c7fcaae3ac1079473e # v2
153+ env :
154+ JRELEASER_DRY_RUN : ${{ github.event.inputs.dryRun }}
155+ JRELEASER_PROJECT_VERSION : ${{ github.event.inputs.version }}
156+ JRELEASER_GITHUB_TOKEN : ${{ secrets.JRELEASER_GITHUB_TOKEN }}
157+ JRELEASER_GPG_PASSPHRASE : ${{ secrets.JRELEASER_GPG_PASSPHRASE }}
158+ JRELEASER_GPG_PUBLIC_KEY : ${{ secrets.JRELEASER_GPG_PUBLIC_KEY }}
159+ JRELEASER_GPG_SECRET_KEY : ${{ secrets.JRELEASER_GPG_SECRET_KEY }}
160+ JRELEASER_ARTIFACTORY_USERNAME : ${{ secrets.JRELEASER_JFROG_USERNAME }}
161+ JRELEASER_ARTIFACTORY_TOKEN : ${{ secrets.JRELEASER_JFROG_TOKEN }}
162+ with :
163+ arguments : full-release --config-file jreleaser-jfrog.yml
164+
165+ - name : Publish timefold-solver to Maven Central
166+ if : ${{ inputs.deploy-to-maven }}
89167 uses : jreleaser/release-action@80ffb38fa759704eed4db5c7fcaae3ac1079473e # v2
90168 env :
91169 JRELEASER_DRY_RUN : ${{ github.event.inputs.dryRun }}
@@ -96,8 +174,17 @@ jobs:
96174 JRELEASER_GPG_SECRET_KEY : ${{ secrets.JRELEASER_GPG_SECRET_KEY }}
97175 JRELEASER_MAVENCENTRAL_USERNAME : ${{ secrets.JRELEASER_MAVEN_CENTRAL_TOKEN_USER }}
98176 JRELEASER_MAVENCENTRAL_PASSWORD : ${{ secrets.JRELEASER_MAVEN_CENTRAL_TOKEN }}
177+ # We do not publish artifacts without approval.
178+ # Manual approval is required to ensure that we are not publishing any source code,
179+ # which cannot be deleted after publishing.
180+ JRELEASER_MAVENCENTRAL_STAGE : UPLOAD
181+ with :
182+ arguments : full-release --config-file jreleaser-maven.yml
99183
100- - name : JReleaser release output
184+ # #####
185+ # 7 - Upload JReleaser artifacts
186+ # #####
187+ - name : Upload release output
101188 uses : actions/upload-artifact@v7
102189 if : always()
103190 with :
0 commit comments