Release #134
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Copyright 2026 Goldman Sachs | |
| # | |
| # Licensed under the Apache License, Version 2.0 (the "License"); | |
| # you may not use this file except in compliance with the License. | |
| # You may obtain a copy of the License at | |
| # | |
| # http://www.apache.org/licenses/LICENSE-2.0 | |
| # | |
| # Unless required by applicable law or agreed to in writing, software | |
| # distributed under the License is distributed on an "AS IS" BASIS, | |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| # See the License for the specific language governing permissions and | |
| # limitations under the License. | |
| name: Release | |
| env: | |
| CI_DEPLOY_USERNAME: ${{ secrets.CI_DEPLOY_USERNAME }} | |
| CI_DEPLOY_PASSWORD: ${{ secrets.CI_DEPLOY_PASSWORD }} | |
| CI_GPG_PASSPHRASE: ${{ secrets.CI_GPG_PASSPHRASE }} | |
| DOCKER_USERNAME: finos | |
| DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} | |
| AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} | |
| AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| releaseVersion: | |
| description: "New release version" | |
| required: true | |
| jobs: | |
| build: | |
| name: Prepare Release Artifacts | |
| runs-on: ubuntu-latest-16-cores | |
| outputs: | |
| testMatrix: ${{ steps.testMatrix.outputs.testMatrix }} | |
| steps: | |
| - name: Checkout repo | |
| uses: actions/checkout@v6 | |
| with: | |
| token: ${{ secrets.FINOS_GITHUB_TOKEN }} | |
| - name: Configure git | |
| run: | | |
| git config --global user.email "37706051+finos-admin@users.noreply.github.com" | |
| git config --global user.name "FINOS Administrator" | |
| - name: Set up Maven Central | |
| uses: actions/setup-java@v5 | |
| with: | |
| distribution: "zulu" | |
| java-version: "11" | |
| server-id: central | |
| server-username: CI_DEPLOY_USERNAME | |
| server-password: CI_DEPLOY_PASSWORD | |
| gpg-private-key: ${{ secrets.CI_GPG_PRIVATE_KEY }} | |
| gpg-passphrase: CI_GPG_PASSPHRASE | |
| - name: Collect Workflow Telemetry | |
| uses: runforesight/workflow-telemetry-action@v1 | |
| with: | |
| theme: dark | |
| - name: Compute next development version | |
| run: | | |
| releaseVersion=${{ github.event.inputs.releaseVersion }} | |
| n=${releaseVersion//[!0-9]/ } | |
| a=(${n//\./ }) | |
| nextPatch=$((${a[2]} + 1)) | |
| developmentVersion="${a[0]}.${a[1]}.${nextPatch}-SNAPSHOT" | |
| echo "DEVELOPMENT_VERSION=${developmentVersion}" >> $GITHUB_ENV | |
| - name: Cache Maven dependencies | |
| uses: actions/cache@v5 | |
| env: | |
| cache-name: cache-mvn-deps | |
| with: | |
| path: ~/.m2/repository | |
| # Keep the restore-keys list narrow on purpose. | |
| key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/pom.xml') }} | |
| restore-keys: | | |
| ${{ runner.os }}-build-${{ env.cache-name }}- | |
| - name: Download deps and plugins | |
| run: mvn de.qaware.maven:go-offline-maven-plugin:resolve-dependencies | |
| - name: Prepare release | |
| run: mvn -B -e release:prepare -Darguments='-B -e' -DpreparationGoals=clean -DreleaseVersion=${{ github.event.inputs.releaseVersion }} -DdevelopmentVersion=${{ env.DEVELOPMENT_VERSION }} -P release | |
| - name: Checkout Release Tag | |
| uses: actions/checkout@v6 | |
| with: | |
| ref: ${{ github.event.repository.name }}-${{ github.event.inputs.releaseVersion }} | |
| token: ${{ secrets.FINOS_GITHUB_TOKEN }} | |
| fetch-depth: 1 | |
| persist-credentials: true | |
| - name: Purge stale legend-engine artifacts from local Maven repo | |
| run: rm -rf ~/.m2/repository/org/finos/legend/engine | |
| - name: Build Release Tag | |
| run: mvn -B -e -T5 -DskipTests -Dorg.slf4j.simpleLogger.showThreadName=true install -P release,docker,pct-cloud-test | |
| env: | |
| MAVEN_OPTS: -Xmx36g | |
| - name: Upload build output | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: build-output | |
| # Upload per-module target/ directories produced by the release-tag | |
| # build. Test jobs re-checkout the release tag from git. | |
| path: | | |
| ~/**/target/ | |
| !~/**/target/*.jar | |
| retention-days: 1 | |
| overwrite: true | |
| include-hidden-files: true | |
| if-no-files-found: error | |
| - name: Upload m2 repository | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: m2-repo | |
| path: ~/.m2/repository/org/finos/legend/engine/ | |
| retention-days: 1 | |
| overwrite: true | |
| if-no-files-found: error | |
| - name: Purge engine artifacts before cache save | |
| # actions/cache's post-job save snapshots ~/.m2/repository at the | |
| # end of the job. We don't want the just-built engine jars in that | |
| # snapshot. | |
| if: always() | |
| run: rm -rf ~/.m2/repository/org/finos/legend/engine | |
| - name: Set Test Matrix | |
| id: testMatrix | |
| run: echo "testMatrix=$(jq -c . < .github/workflows/resources/modulesToTest.json)" >> $GITHUB_OUTPUT | |
| - name: Upload CI Event | |
| if: always() | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: event-file | |
| path: ${{ github.event_path }} | |
| test: | |
| name: Run Unit Tests | |
| runs-on: ubuntu-latest | |
| needs: | |
| - build | |
| steps: | |
| - name: Checkout Release Tag | |
| uses: actions/checkout@v6 | |
| with: | |
| ref: ${{ github.event.repository.name }}-${{ github.event.inputs.releaseVersion }} | |
| fetch-depth: 1 | |
| persist-credentials: false | |
| - name: Before Test | |
| uses: ./.github/workflows/actions/before-test | |
| - name: Excluded Modules | |
| id: modulesToExclude | |
| run: echo EXCLUSION_MODULES=`jq -c '.include | map(.modules) | flatten | map("!org.finos.legend.engine:" + .) | join(",")' ./.github/workflows/resources/modulesToTest.json` >> $GITHUB_OUTPUT | |
| - name: Test | |
| env: | |
| MAVEN_OPTS: "-Xmx1g" | |
| AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} | |
| AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | |
| run: | | |
| mvn -B -e surefire:test -pl ${{ steps.modulesToExclude.outputs.EXCLUSION_MODULES }} -P release,docker,pct-cloud-test -T2 -DargLine="-Xmx6g" -Dsurefire.reports.directory=${GITHUB_WORKSPACE}/surefire-reports-aggregate | |
| - name: Upload Test Results | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: test-results | |
| path: ${{ github.workspace }}/surefire-reports-aggregate/*.xml | |
| test-modules: | |
| name: Test Module - ${{ matrix.name }} | |
| runs-on: ubuntu-latest | |
| needs: | |
| - build | |
| strategy: | |
| fail-fast: false | |
| matrix: ${{fromJson(needs.build.outputs.testMatrix)}} | |
| steps: | |
| - name: Checkout Release Tag | |
| uses: actions/checkout@v6 | |
| with: | |
| ref: ${{ github.event.repository.name }}-${{ github.event.inputs.releaseVersion }} | |
| fetch-depth: 1 | |
| persist-credentials: false | |
| - name: Before Test | |
| uses: ./.github/workflows/actions/before-test | |
| - name: Included Modules | |
| id: modulesToInclude | |
| env: | |
| MODULES: ${{ toJSON(matrix.modules) }} | |
| run: | | |
| echo INCLUSION_MODULES=`jq -c 'map("org.finos.legend.engine:" + .) | join(",")' <<< $MODULES` >> $GITHUB_OUTPUT | |
| - name: Test | |
| env: | |
| MAVEN_OPTS: "-Xmx1g" | |
| AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} | |
| AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | |
| run: | | |
| mvn -B -e surefire:test -pl ${{ steps.modulesToInclude.outputs.INCLUSION_MODULES }} -P release,docker,pct-cloud-test -T2 -DargLine="-Xmx6g" -Dsurefire.reports.directory=${GITHUB_WORKSPACE}/surefire-reports-aggregate | |
| - name: Upload Test Results | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: test-results-${{ matrix.name }} | |
| path: ${{ github.workspace }}/surefire-reports-aggregate/*.xml | |
| release: | |
| name: Create and Publish Release Bundle | |
| runs-on: ubuntu-latest | |
| needs: | |
| - build | |
| - test | |
| - test-modules | |
| steps: | |
| - name: Checkout Release Tag | |
| uses: actions/checkout@v4 | |
| with: | |
| ref: ${{ github.event.repository.name }}-${{ github.event.inputs.releaseVersion }} | |
| fetch-depth: 1 | |
| persist-credentials: false | |
| - name: Download m2 repository for publishing | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: m2-repo | |
| path: ~/.m2/repository/org/finos/legend/engine | |
| - name: Create bundle to publish | |
| env: | |
| RELEASE_VERSION: ${{ github.event.inputs.releaseVersion }} | |
| run: | | |
| # Defensive guard: keep only directories whose name is exactly the | |
| # release version under each artifact path. Should be a no-op when | |
| # the build job already purged stale artifacts, but protects the | |
| # publish step against any future regression that lets prior-release | |
| # jars slip into ~/.m2/repository/org/finos/legend/engine. | |
| find ~/.m2/repository/org/finos/legend/engine -mindepth 2 -type d \ | |
| -regextype posix-extended \ | |
| -regex '.*/[0-9]+\.[0-9]+\.[0-9]+(-[A-Za-z0-9.+-]+)?$' \ | |
| ! -name "$RELEASE_VERSION" -prune -exec rm -rf {} + | |
| mkdir -p central-staging/org/finos/legend | |
| cp -R ~/.m2/repository/org/finos/legend/engine central-staging/org/finos/legend | |
| find central-staging -type f \( -name "*.xml" -o -name "*.repositories" \) -delete | |
| find central-staging -type f ! -name "*.md5" ! -name "*.sha1" ! -name "*.sha256" ! -name "*.sha512" ! -name "*.asc" | while read -r file; do | |
| md5sum "$file" | awk '{print $1}' > "$file.md5" | |
| sha1sum "$file" | awk '{print $1}' > "$file.sha1" | |
| sha256sum "$file" | awk '{print $1}' > "$file.sha256" | |
| sha512sum "$file" | awk '{print $1}' > "$file.sha512" | |
| done | |
| mkdir central-publishing | |
| cd central-staging && zip -r ../central-publishing/central-bundle.zip org | |
| - name: Publish bundle | |
| working-directory: central-publishing | |
| run: | | |
| token=$(printf "$CI_DEPLOY_USERNAME:$CI_DEPLOY_PASSWORD" | base64) | |
| httpCode=$(curl -s -o response.json -w "%{http_code}" -X POST -H "Authorization: Bearer $token" --form bundle=@central-bundle.zip https://central.sonatype.com/api/v1/publisher/upload?publishingType=AUTOMATIC) | |
| if [[ "$httpCode" == 2* ]]; then | |
| deploymentId=$(cat response.json) | |
| echo "Uploaded bundle. Deployment id is: $deploymentId" | |
| echo "DEVELOPMENT_ID=${deploymentId}" >> $GITHUB_ENV | |
| else | |
| echo "Failed to upload bundle. Got status code $httpCode" | |
| echo "Got the following response body:" | |
| cat response.json | |
| exit 1 | |
| fi | |
| - name: Verify deployment status | |
| run: | | |
| token=$(printf "$CI_DEPLOY_USERNAME:$CI_DEPLOY_PASSWORD" | base64) | |
| deploymentId=${{ env.DEVELOPMENT_ID }} | |
| deploymentState="" | |
| while [ "$deploymentState" != "PUBLISHED" ]; do | |
| sleep 1m | |
| response=$(curl -s -X POST -H "Authorization: Bearer $token" https://central.sonatype.com/api/v1/publisher/status?id=$deploymentId) | |
| deploymentState=$(echo "$response" | jq -r '.deploymentState') | |
| echo "Deployment state for id $deploymentId is $deploymentState" | |
| if [[ "$deploymentState" == "FAILED" ]]; then | |
| echo "The deployment failed with the following response" | |
| echo "$response" | |
| exit 1 | |
| fi | |
| done |