From 824358b9cba9e55127a38e6c312794452ea214d7 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Fri, 1 May 2026 16:25:18 +0100 Subject: [PATCH 01/20] Prepare 4.0.x-internal branch --- .../workflows/build-and-deploy-snapshot.yml | 14 +- .github/workflows/build-pull-request.yml | 24 --- .github/workflows/ci.yml | 17 +- .github/workflows/distribute.yml | 45 ----- .github/workflows/release-milestone.yml | 131 ------------- .github/workflows/release.yml | 178 ------------------ .github/workflows/run-codeql-analysis.yml | 13 -- .github/workflows/run-system-tests.yml | 53 ------ .github/workflows/trigger-docs-build.yml | 35 ---- gradle.properties | 4 +- 10 files changed, 12 insertions(+), 502 deletions(-) delete mode 100644 .github/workflows/build-pull-request.yml delete mode 100644 .github/workflows/distribute.yml delete mode 100644 .github/workflows/release-milestone.yml delete mode 100644 .github/workflows/release.yml delete mode 100644 .github/workflows/run-codeql-analysis.yml delete mode 100644 .github/workflows/run-system-tests.yml delete mode 100644 .github/workflows/trigger-docs-build.yml diff --git a/.github/workflows/build-and-deploy-snapshot.yml b/.github/workflows/build-and-deploy-snapshot.yml index a59731f4ec9..24ca5e56ea4 100644 --- a/.github/workflows/build-and-deploy-snapshot.yml +++ b/.github/workflows/build-and-deploy-snapshot.yml @@ -3,7 +3,7 @@ on: workflow_dispatch: push: branches: - - '4.0.x' + - '4.0.x-internal' permissions: contents: read concurrency: @@ -24,7 +24,6 @@ jobs: commercial-repository-password: ${{ secrets.COMMERCIAL_ARTIFACTORY_PASSWORD }} commercial-repository-username: ${{ secrets.COMMERCIAL_ARTIFACTORY_USERNAME }} commercial-snapshot-repository-url: ${{ vars.COMMERCIAL_SNAPSHOT_REPO_URL }} - develocity-access-key: ${{ secrets.DEVELOCITY_ACCESS_KEY }} gradle-cache-read-only: false publish: true - name: Deploy @@ -50,17 +49,6 @@ jobs: webhook-url: ${{ secrets.GOOGLE_CHAT_WEBHOOK_URL }} outputs: version: ${{ steps.build-and-publish.outputs.version }} - trigger-docs-build: - name: Trigger Docs Build - needs: build-and-deploy-snapshot - permissions: - actions: write - runs-on: ${{ vars.UBUNTU_SMALL || 'ubuntu-latest' }} - steps: - - name: Run Deploy Docs Workflow - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: gh workflow run deploy-docs.yml --repo ${{ github.repository }} -r docs-build -f build-sha=${{ github.sha }} -f build-refname=${{ github.ref_name }} -f build-version=${{ needs.build-and-deploy-snapshot.outputs.version }} verify: name: Verify needs: build-and-deploy-snapshot diff --git a/.github/workflows/build-pull-request.yml b/.github/workflows/build-pull-request.yml deleted file mode 100644 index 95129fa18d7..00000000000 --- a/.github/workflows/build-pull-request.yml +++ /dev/null @@ -1,24 +0,0 @@ -name: Build Pull Request -on: pull_request -permissions: - contents: read -jobs: - build: - name: Build Pull Request - if: ${{ github.repository == 'spring-projects/spring-boot' }} - runs-on: ${{ vars.UBUNTU_MEDIUM || 'ubuntu-latest' }} - steps: - - name: Check Out Code - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - - name: Build - id: build - uses: ./.github/actions/build - - name: Print JVM Thread Dumps When Cancelled - if: cancelled() - uses: ./.github/actions/print-jvm-thread-dumps - - name: Upload Build Reports - if: failure() - uses: actions/upload-artifact@v7 - with: - name: build-reports - path: '**/build/reports/' diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0905e0790f7..13722cd74f2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,9 +2,13 @@ name: CI on: push: branches: - - '4.0.x' + - '4.0.x-internal' + schedule: + - cron: '30 05 * * *' permissions: contents: read +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} jobs: ci: name: '${{ matrix.os.name}} | Java ${{ matrix.java.version}}' @@ -32,8 +36,6 @@ jobs: name: Linux java: version: 25 - - os: - name: ${{ github.repository == 'spring-projects/spring-boot-commercial' && 'Windows' }} steps: - name: Prepare Windows runner if: ${{ runner.os == 'Windows' }} @@ -47,11 +49,10 @@ jobs: id: build uses: ./.github/actions/build with: - commercial-release-repository-url: ${{ vars.COMMERCIAL_RELEASE_REPO_URL }} - commercial-repository-password: ${{ secrets.COMMERCIAL_ARTIFACTORY_PASSWORD }} - commercial-repository-username: ${{ secrets.COMMERCIAL_ARTIFACTORY_USERNAME }} - commercial-snapshot-repository-url: ${{ vars.COMMERCIAL_SNAPSHOT_REPO_URL }} - develocity-access-key: ${{ secrets.DEVELOCITY_ACCESS_KEY }} + commercial-release-repository-url: 'https://repo.spring.io/artifactory/spring-commercial-release-remote' + commercial-repository-password: ${{ secrets.ARTIFACTORY_PASSWORD }} + commercial-repository-username: ${{ secrets.ARTIFACTORY_USERNAME }} + commercial-snapshot-repository-url: 'https://repo.spring.io/artifactory/spring-commercial-snapshot-remote' gradle-cache-read-only: false java-early-access: ${{ matrix.java.early-access || 'false' }} java-distribution: ${{ matrix.java.distribution }} diff --git a/.github/workflows/distribute.yml b/.github/workflows/distribute.yml deleted file mode 100644 index e8462178fe5..00000000000 --- a/.github/workflows/distribute.yml +++ /dev/null @@ -1,45 +0,0 @@ -name: Distribute -on: - workflow_dispatch: - inputs: - build-number: - description: 'Number of the build to use to create the bundle' - required: true - type: string - create-bundle: - description: 'Whether to create the bundle. If unchecked, only the bundle distribution is executed' - required: true - type: boolean - default: true - version: - description: 'Version to bundle and distribute' - required: true - type: string -permissions: - contents: read -jobs: - distribute-spring-enterprise-release-bundle: - runs-on: ${{ vars.UBUNTU_SMALL || 'ubuntu-latest' }} - steps: - - name: Create Bundle - if: ${{ vars.COMMERCIAL && inputs.create-bundle }} - shell: bash - run: | - curl -s -u "${{ secrets.COMMERCIAL_ARTIFACTORY_USERNAME }}:${{ secrets.COMMERCIAL_ARTIFACTORY_PASSWORD }}" \ - -X POST -H "X-JFrog-Signing-Key-Name: packagesKey" -H "Content-Type: application/json" \ - "https://usw1.packages.broadcom.com/lifecycle/api/v2/release_bundle?project=spring" \ - -d '{"release_bundle_name": "TNZ-spring-boot-commercial", "release_bundle_version": "${{ inputs.version }}", "skip_docker_manifest_resolution": true, "source_type": "builds", "source": {"builds": [ {"build_repository": "spring-build-info", "build_name": "spring-boot-commercial-${{ inputs.version }}", "build_number": "${{ inputs.build-number }}", "include_dependencies": false}]}}' | \ - jq -e 'if has("repository_key") then . else halt_error end' - - name: Sleep - if: ${{ vars.COMMERCIAL && inputs.create-bundle }} - shell: bash - run: sleep 30 - - name: Distribute Bundle - if: ${{ vars.COMMERCIAL }} - shell: bash - run: | - curl -s -u "${{ secrets.COMMERCIAL_ARTIFACTORY_USERNAME }}:${{ secrets.COMMERCIAL_ARTIFACTORY_PASSWORD }}" \ - -X POST -H "Content-Type: application/json" \ - "https://usw1.packages.broadcom.com/lifecycle/api/v2/distribution/distribute/TNZ-spring-boot-commercial/${{ inputs.version }}?project=spring" \ - -d '{"auto_create_missing_repositories": "false", "distribution_rules": [{"site_name": "JP-SaaS"}], "modifications": {"mappings": [{"input": "spring-enterprise-maven-prod-local/(.*)", "output": "spring-enterprise/$1"}]}}' | \ - jq -e 'if has("id") then . else halt_error end' diff --git a/.github/workflows/release-milestone.yml b/.github/workflows/release-milestone.yml deleted file mode 100644 index 03cfbf778e4..00000000000 --- a/.github/workflows/release-milestone.yml +++ /dev/null @@ -1,131 +0,0 @@ -name: Release Milestone -on: - push: - tags: - - v4.0.0-M[0-9] - - v4.0.0-RC[0-9] -permissions: - contents: read -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} -jobs: - build-and-stage-release: - name: Build and Stage Release - if: ${{ github.repository == 'spring-projects/spring-boot' }} - runs-on: ${{ vars.UBUNTU_MEDIUM || 'ubuntu-latest' }} - steps: - - name: Check Out Code - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - - name: Build and Publish - id: build-and-publish - uses: ./.github/actions/build - with: - develocity-access-key: ${{ secrets.DEVELOCITY_ACCESS_KEY }} - gradle-cache-read-only: false - publish: true - - name: Stage Release - uses: spring-io/artifactory-deploy-action@926d7f7cc810569395346bf3a4d91b380b3e355b # v0.0.4 - with: - build-name: ${{ format('spring-boot-{0}', steps.build-and-publish.outputs.version)}} - folder: 'deployment-repository' - password: ${{ secrets.ARTIFACTORY_PASSWORD }} - repository: 'libs-staging-local' - signing-key: ${{ secrets.GPG_PRIVATE_KEY }} - signing-passphrase: ${{ secrets.GPG_PASSPHRASE }} - threads: 8 - uri: 'https://repo.spring.io' - username: ${{ secrets.ARTIFACTORY_USERNAME }} - outputs: - version: ${{ steps.build-and-publish.outputs.version }} - verify: - name: Verify - needs: build-and-stage-release - uses: ./.github/workflows/verify.yml - secrets: - commercial-repository-password: ${{ secrets.COMMERCIAL_ARTIFACTORY_RO_PASSWORD }} - commercial-repository-username: ${{ secrets.COMMERCIAL_ARTIFACTORY_RO_USERNAME }} - google-chat-webhook-url: ${{ secrets.GOOGLE_CHAT_WEBHOOK_URL }} - opensource-repository-password: ${{ secrets.ARTIFACTORY_PASSWORD }} - opensource-repository-username: ${{ secrets.ARTIFACTORY_USERNAME }} - token: ${{ secrets.GH_ACTIONS_REPO_TOKEN }} - with: - staging: true - version: ${{ needs.build-and-stage-release.outputs.version }} - sync-to-maven-central: - name: Sync to Maven Central - if: ${{ !vars.COMMERCIAL }} - needs: - - build-and-stage-release - - verify - runs-on: ${{ vars.UBUNTU_SMALL || 'ubuntu-latest' }} - steps: - - name: Check Out Code - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - - name: Sync to Maven Central - uses: ./.github/actions/sync-to-maven-central - with: - central-token-password: ${{ secrets.CENTRAL_TOKEN_PASSWORD }} - central-token-username: ${{ secrets.CENTRAL_TOKEN_USERNAME }} - jfrog-cli-config-token: ${{ secrets.JF_ARTIFACTORY_SPRING }} - spring-boot-version: ${{ needs.build-and-stage-release.outputs.version }} - promote-release: - name: Promote Release - needs: - - build-and-stage-release - - sync-to-maven-central - runs-on: ${{ vars.UBUNTU_SMALL || 'ubuntu-latest' }} - steps: - - name: Set up JFrog CLI - uses: jfrog/setup-jfrog-cli@deda456d982fc5e9a7a020b63eb0d2968aedd33e # v5.1.0 - env: - JF_ENV_SPRING: ${{ secrets.JF_ARTIFACTORY_SPRING }} - - name: Promote build - run: jfrog rt build-promote ${{ format('spring-boot-{0}', needs.build-and-stage-release.outputs.version)}} ${{ github.run_number }} libs-milestone-local - publish-gradle-plugin: - name: Publish Gradle Plugin - if: ${{ !vars.COMMERCIAL }} - needs: - - build-and-stage-release - - sync-to-maven-central - runs-on: ${{ vars.UBUNTU_SMALL || 'ubuntu-latest' }} - steps: - - name: Check Out Code - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - - name: Publish - uses: ./.github/actions/publish-gradle-plugin - with: - gradle-plugin-publish-key: ${{ secrets.GRADLE_PLUGIN_PUBLISH_KEY }} - gradle-plugin-publish-secret: ${{ secrets.GRADLE_PLUGIN_PUBLISH_SECRET }} - jfrog-cli-config-token: ${{ secrets.JF_ARTIFACTORY_SPRING }} - plugin-version: ${{ needs.build-and-stage-release.outputs.version }} - trigger-docs-build: - name: Trigger Docs Build - needs: - - build-and-stage-release - - promote-release - permissions: - actions: write - runs-on: ubuntu-latest - steps: - - name: Run Deploy Docs Workflow - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: gh workflow run deploy-docs.yml --repo ${{ github.repository }} -r docs-build -f build-refname=${{ github.ref_name }} -f build-version=${{ needs.build-and-stage-release.outputs.version }} - create-github-release: - name: Create GitHub Release - needs: - - build-and-stage-release - - promote-release - - publish-gradle-plugin - - trigger-docs-build - runs-on: ${{ vars.UBUNTU_SMALL || 'ubuntu-latest' }} - steps: - - name: Check Out Code - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - - name: Create GitHub Release - uses: ./.github/actions/create-github-release - with: - commercial: ${{ vars.COMMERCIAL }} - milestone: ${{ needs.build-and-stage-release.outputs.version }} - pre-release: true - token: ${{ secrets.GH_ACTIONS_REPO_TOKEN }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml deleted file mode 100644 index d4288c5d85a..00000000000 --- a/.github/workflows/release.yml +++ /dev/null @@ -1,178 +0,0 @@ -name: Release -on: - push: - tags: - - v4.0.[0-9]+ -permissions: - contents: read -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} -jobs: - build-and-stage-release: - name: Build and Stage Release - if: ${{ github.repository == 'spring-projects/spring-boot' || github.repository == 'spring-projects/spring-boot-commercial' }} - runs-on: ${{ vars.UBUNTU_MEDIUM || 'ubuntu-latest' }} - steps: - - name: Check Out Code - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - - name: Build and Publish - id: build-and-publish - uses: ./.github/actions/build - with: - commercial-release-repository-url: ${{ vars.COMMERCIAL_RELEASE_REPO_URL }} - commercial-repository-password: ${{ secrets.COMMERCIAL_ARTIFACTORY_PASSWORD }} - commercial-repository-username: ${{ secrets.COMMERCIAL_ARTIFACTORY_USERNAME }} - commercial-snapshot-repository-url: ${{ vars.COMMERCIAL_SNAPSHOT_REPO_URL }} - develocity-access-key: ${{ secrets.DEVELOCITY_ACCESS_KEY }} - gradle-cache-read-only: false - publish: true - - name: Stage Release - uses: spring-io/artifactory-deploy-action@926d7f7cc810569395346bf3a4d91b380b3e355b # v0.0.4 - with: - build-name: ${{ vars.COMMERCIAL && format('spring-boot-commercial-{0}', steps.build-and-publish.outputs.version) || format('spring-boot-{0}', steps.build-and-publish.outputs.version) }} - folder: 'deployment-repository' - password: ${{ vars.COMMERCIAL && secrets.COMMERCIAL_ARTIFACTORY_PASSWORD || secrets.ARTIFACTORY_PASSWORD }} - project: ${{ vars.COMMERCIAL && 'spring' }} - repository: ${{ vars.COMMERCIAL && 'spring-enterprise-maven-stage-local' || 'libs-staging-local' }} - signing-key: ${{ secrets.GPG_PRIVATE_KEY }} - signing-passphrase: ${{ secrets.GPG_PASSPHRASE }} - threads: 8 - uri: ${{ vars.COMMERCIAL_DEPLOY_REPO_URL || 'https://repo.spring.io' }} - username: ${{ vars.COMMERCIAL && secrets.COMMERCIAL_ARTIFACTORY_USERNAME || secrets.ARTIFACTORY_USERNAME }} - - name: Send Notification - if: failure() - uses: ./.github/actions/send-notification - with: - run-name: ${{ format('{0} | Release Staging | {1}', github.ref_name, inputs.version) }} - status: ${{ job.status }} - webhook-url: ${{ secrets.GOOGLE_CHAT_WEBHOOK_URL }} - outputs: - version: ${{ steps.build-and-publish.outputs.version }} - verify: - name: Verify - needs: build-and-stage-release - uses: ./.github/workflows/verify.yml - secrets: - commercial-repository-password: ${{ secrets.COMMERCIAL_ARTIFACTORY_PASSWORD }} - commercial-repository-username: ${{ secrets.COMMERCIAL_ARTIFACTORY_USERNAME }} - google-chat-webhook-url: ${{ secrets.GOOGLE_CHAT_WEBHOOK_URL }} - opensource-repository-password: ${{ secrets.ARTIFACTORY_PASSWORD }} - opensource-repository-username: ${{ secrets.ARTIFACTORY_USERNAME }} - token: ${{ secrets.GH_ACTIONS_REPO_TOKEN }} - with: - staging: true - version: ${{ needs.build-and-stage-release.outputs.version }} - sync-to-maven-central: - name: Sync to Maven Central - if: ${{ !vars.COMMERCIAL }} - needs: - - build-and-stage-release - - verify - runs-on: ${{ vars.UBUNTU_SMALL || 'ubuntu-latest' }} - steps: - - name: Check Out Code - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - - name: Sync to Maven Central - uses: ./.github/actions/sync-to-maven-central - with: - central-token-password: ${{ secrets.CENTRAL_TOKEN_PASSWORD }} - central-token-username: ${{ secrets.CENTRAL_TOKEN_USERNAME }} - jfrog-cli-config-token: ${{ secrets.JF_ARTIFACTORY_SPRING }} - spring-boot-version: ${{ needs.build-and-stage-release.outputs.version }} - promote-release: - name: Promote Release - needs: - - build-and-stage-release - - sync-to-maven-central - runs-on: ${{ vars.UBUNTU_SMALL || 'ubuntu-latest' }} - steps: - - name: Set up JFrog CLI - uses: jfrog/setup-jfrog-cli@deda456d982fc5e9a7a020b63eb0d2968aedd33e # v5.1.0 - env: - JF_ENV_SPRING: ${{ vars.COMMERCIAL && secrets.COMMERCIAL_JF_ARTIFACTORY_SPRING || secrets.JF_ARTIFACTORY_SPRING }} - - name: Promote open source build - if: ${{ !vars.COMMERCIAL }} - run: jfrog rt build-promote ${{ format('spring-boot-{0}', needs.build-and-stage-release.outputs.version)}} ${{ github.run_number }} libs-release-local - - name: Promote commercial build - if: ${{ vars.COMMERCIAL }} - run: jfrog rt build-promote ${{ format('spring-boot-commercial-{0}', needs.build-and-stage-release.outputs.version)}} ${{ github.run_number }} spring-enterprise-maven-prod-local --project spring - publish-gradle-plugin: - name: Publish Gradle Plugin - if: ${{ !vars.COMMERCIAL }} - needs: - - build-and-stage-release - - sync-to-maven-central - runs-on: ${{ vars.UBUNTU_SMALL || 'ubuntu-latest' }} - steps: - - name: Check Out Code - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - - name: Publish - uses: ./.github/actions/publish-gradle-plugin - with: - gradle-plugin-publish-key: ${{ secrets.GRADLE_PLUGIN_PUBLISH_KEY }} - gradle-plugin-publish-secret: ${{ secrets.GRADLE_PLUGIN_PUBLISH_SECRET }} - jfrog-cli-config-token: ${{ secrets.JF_ARTIFACTORY_SPRING }} - plugin-version: ${{ needs.build-and-stage-release.outputs.version }} - publish-to-sdkman: - name: Publish to SDKMAN! - if: ${{ !vars.COMMERCIAL }} - needs: - - build-and-stage-release - - sync-to-maven-central - runs-on: ${{ vars.UBUNTU_SMALL || 'ubuntu-latest' }} - steps: - - name: Check Out Code - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - - name: Publish to SDKMAN! - uses: ./.github/actions/publish-to-sdkman - with: - make-default: false - sdkman-consumer-key: ${{ secrets.SDKMAN_CONSUMER_KEY }} - sdkman-consumer-token: ${{ secrets.SDKMAN_CONSUMER_TOKEN }} - spring-boot-version: ${{ needs.build-and-stage-release.outputs.version }} - update-homebrew-tap: - name: Update Homebrew Tap - needs: - - build-and-stage-release - - sync-to-maven-central - runs-on: ${{ vars.UBUNTU_SMALL || 'ubuntu-latest' }} - steps: - - name: Check Out Code - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - - name: Update Homebrew Tap - uses: ./.github/actions/update-homebrew-tap - with: - spring-boot-version: ${{ needs.build-and-stage-release.outputs.version }} - token: ${{ secrets.GH_ACTIONS_REPO_TOKEN }} - trigger-docs-build: - name: Trigger Docs Build - needs: - - build-and-stage-release - - promote-release - permissions: - actions: write - runs-on: ubuntu-latest - steps: - - name: Run Deploy Docs Workflow - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: gh workflow run deploy-docs.yml --repo ${{ github.repository }} -r docs-build -f build-refname=${{ github.ref_name }} -f build-version=${{ needs.build-and-stage-release.outputs.version }} - create-github-release: - name: Create GitHub Release - needs: - - build-and-stage-release - - promote-release - - publish-gradle-plugin - - publish-to-sdkman - - trigger-docs-build - - update-homebrew-tap - runs-on: ${{ vars.UBUNTU_SMALL || 'ubuntu-latest' }} - steps: - - name: Check Out Code - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - - name: Create GitHub Release - uses: ./.github/actions/create-github-release - with: - commercial: ${{ vars.COMMERCIAL }} - milestone: ${{ needs.build-and-stage-release.outputs.version }} - token: ${{ secrets.GH_ACTIONS_REPO_TOKEN }} diff --git a/.github/workflows/run-codeql-analysis.yml b/.github/workflows/run-codeql-analysis.yml deleted file mode 100644 index 0f823bafff2..00000000000 --- a/.github/workflows/run-codeql-analysis.yml +++ /dev/null @@ -1,13 +0,0 @@ -name: "Run CodeQL Analysis" -on: - push: - pull_request: - workflow_dispatch: -permissions: read-all -jobs: - run-analysis: - permissions: - actions: read - contents: read - security-events: write - uses: spring-io/github-actions/.github/workflows/codeql-analysis.yml@7dc305df87410aa851b873d2f1fd33ccbb7d0aa8 diff --git a/.github/workflows/run-system-tests.yml b/.github/workflows/run-system-tests.yml deleted file mode 100644 index 340080d3c73..00000000000 --- a/.github/workflows/run-system-tests.yml +++ /dev/null @@ -1,53 +0,0 @@ -name: Run System Tests -on: - push: - branches: - - '4.0.x' -permissions: - contents: read -jobs: - run-system-tests: - name: 'Java ${{ matrix.java.version}}' - if: ${{ github.repository == 'spring-projects/spring-boot' }} - runs-on: ${{ vars.UBUNTU_MEDIUM || 'ubuntu-latest' }} - strategy: - matrix: - java: - - version: 17 - toolchain: true - - version: 21 - toolchain: true - steps: - - name: Switch Docker to Overlay2 - shell: bash - run: | - echo '{"storage-driver":"overlay2"}' | sudo tee /etc/docker/daemon.json - sudo systemctl restart docker - - name: Check Out Code - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - - name: Prepare Gradle Build - uses: ./.github/actions/prepare-gradle-build - with: - develocity-access-key: ${{ secrets.DEVELOCITY_ACCESS_KEY }} - java-toolchain: ${{ matrix.java.toolchain }} - java-version: ${{ matrix.java.version }} - - name: Run System Tests - id: run-system-tests - shell: bash - run: ./gradlew systemTest - - name: Show docker info - if: always() - shell: bash - run: docker version ; docker info - - name: List docker images - if: always() - shell: bash - run: docker image ls --digests - - name: Send Notification - if: always() - uses: ./.github/actions/send-notification - with: - build-scan-url: ${{ steps.run-system-tests.outputs.build-scan-url }} - run-name: ${{ format('{0} | System Tests | Java {1}', github.ref_name, matrix.java.version) }} - status: ${{ job.status }} - webhook-url: ${{ secrets.GOOGLE_CHAT_WEBHOOK_URL }} diff --git a/.github/workflows/trigger-docs-build.yml b/.github/workflows/trigger-docs-build.yml deleted file mode 100644 index 600c97f834a..00000000000 --- a/.github/workflows/trigger-docs-build.yml +++ /dev/null @@ -1,35 +0,0 @@ -name: Trigger Docs Build -on: - push: - branches: '4.0.x' - paths: [ 'antora/*' ] - workflow_dispatch: - inputs: - build-version: - description: 'Version being build (e.g. 1.0.3-SNAPSHOT)' - required: false - build-sha: - description: Enter the SHA to build (e.g. 82c97891569821a7f91a77ca074232e0b54ca7a5) - required: false - build-refname: - description: 'Git refname to build (e.g., 1.0.x)' - required: false - -permissions: - contents: read -jobs: - trigger-docs-build: - name: Trigger Docs Build - if: github.repository_owner == 'spring-projects' - runs-on: ${{ vars.UBUNTU_SMALL || 'ubuntu-latest' }} - permissions: - actions: write - steps: - - name: Check Out - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - with: - ref: docs-build - - name: Trigger Workflow - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: gh workflow run deploy-docs.yml -r docs-build -f build-refname=${{ github.event.inputs.build-refname }} -f build-sha=${{ github.event.inputs.build-sha }} -f build-version=${{ github.event.inputs.build-version }} diff --git a/gradle.properties b/gradle.properties index 94db8de734f..8297bf9320f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,6 +1,6 @@ -version=4.0.8-SNAPSHOT +version=4.0.8-INTERNAL-SNAPSHOT latestVersion=false -spring.build-type=oss +spring.build-type=commercial org.gradle.caching=true org.gradle.parallel=true From 604fc38eb18223357e566a55aa20dd8dfc8d1c9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Nicoll?= Date: Tue, 4 Aug 2026 07:50:37 +0200 Subject: [PATCH 02/20] Switch to INTERNAL-SNAPSHOT --- gradle.properties | 2 +- .../spring-boot-dependencies/build.gradle | 28 +++++++++---------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/gradle.properties b/gradle.properties index 8297bf9320f..f528359c0ee 100644 --- a/gradle.properties +++ b/gradle.properties @@ -21,7 +21,7 @@ mockitoVersion=5.20.0 nativeBuildToolsVersion=0.11.5 nullabilityPluginVersion=0.0.14 snakeYamlVersion=2.5 -springFrameworkVersion=7.0.9-SNAPSHOT +springFrameworkVersion=7.0.9-INTERNAL-SNAPSHOT springFramework60xVersion=6.0.23 tomcatVersion=11.0.24 diff --git a/platform/spring-boot-dependencies/build.gradle b/platform/spring-boot-dependencies/build.gradle index 0772790d49b..b7abe9d97a5 100644 --- a/platform/spring-boot-dependencies/build.gradle +++ b/platform/spring-boot-dependencies/build.gradle @@ -1540,7 +1540,7 @@ bom { releaseNotes("https://github.com/apache/maven-war-plugin/releases/tag/maven-war-plugin-{version}") } } - library("Micrometer", "1.16.7-SNAPSHOT") { + library("Micrometer", "1.16.7-INTERNAL-SNAPSHOT") { firstParty() group("io.micrometer") { modules = [ @@ -1563,7 +1563,7 @@ bom { releaseNotes("https://github.com/micrometer-metrics/micrometer/releases/tag/v{version}") } } - library("Micrometer Tracing", "1.6.7-SNAPSHOT") { + library("Micrometer Tracing", "1.6.7-INTERNAL-SNAPSHOT") { firstParty() alignWith { dependencyManagementDeclaredIn("io.micrometer:micrometer-tracing-bom") { @@ -1973,7 +1973,7 @@ bom { ] } } - library("Reactor Bom", "2025.0.7-SNAPSHOT") { + library("Reactor Bom", "2025.0.7-INTERNAL-SNAPSHOT") { firstParty() calendarName = "Reactor" group("io.projectreactor") { @@ -2392,7 +2392,7 @@ bom { ] } } - library("Spring AMQP", "4.0.5-SNAPSHOT") { + library("Spring AMQP", "4.0.5-INTERNAL-SNAPSHOT") { firstParty() group("org.springframework.amqp") { bom("spring-amqp-bom") @@ -2407,7 +2407,7 @@ bom { releaseNotes("https://github.com/spring-projects/spring-amqp/releases/tag/v{version}") } } - library("Spring Batch", "6.0.5-SNAPSHOT") { + library("Spring Batch", "6.0.5-INTERNAL-SNAPSHOT") { firstParty() group("org.springframework.batch") { bom("spring-batch-bom") @@ -2422,7 +2422,7 @@ bom { releaseNotes("https://github.com/spring-projects/spring-batch/releases/tag/v{version}") } } - library("Spring Data Bom", "2025.1.7-SNAPSHOT") { + library("Spring Data Bom", "2025.1.7-INTERNAL-SNAPSHOT") { firstParty() calendarName = "Spring Data Release" group("org.springframework.data") { @@ -2452,7 +2452,7 @@ bom { releaseNotes("https://github.com/spring-projects/spring-framework/releases/tag/v{version}") } } - library("Spring GraphQL", "2.0.5-SNAPSHOT") { + library("Spring GraphQL", "2.0.5-INTERNAL-SNAPSHOT") { firstParty() group("org.springframework.graphql") { modules = [ @@ -2470,7 +2470,7 @@ bom { releaseNotes("https://github.com/spring-projects/spring-graphql/releases/tag/v{version}") } } - library("Spring HATEOAS", "3.0.5-SNAPSHOT") { + library("Spring HATEOAS", "3.0.5-INTERNAL-SNAPSHOT") { firstParty() group("org.springframework.hateoas") { modules = [ @@ -2487,7 +2487,7 @@ bom { releaseNotes("https://github.com/spring-projects/spring-hateoas/releases/tag/{version}") } } - library("Spring Integration", "7.0.6-SNAPSHOT") { + library("Spring Integration", "7.0.6-INTERNAL-SNAPSHOT") { firstParty() group("org.springframework.integration") { bom("spring-integration-bom") @@ -2502,7 +2502,7 @@ bom { releaseNotes("https://github.com/spring-projects/spring-integration/releases/tag/v{version}") } } - library("Spring Kafka", "4.0.7-SNAPSHOT") { + library("Spring Kafka", "4.0.7-INTERNAL-SNAPSHOT") { firstParty() group("org.springframework.kafka") { modules = [ @@ -2520,7 +2520,7 @@ bom { releaseNotes("https://github.com/spring-projects/spring-kafka/releases/tag/v{version}") } } - library("Spring LDAP", "4.0.5-SNAPSHOT") { + library("Spring LDAP", "4.0.5-INTERNAL-SNAPSHOT") { firstParty() group("org.springframework.ldap") { modules = [ @@ -2540,7 +2540,7 @@ bom { releaseNotes("https://github.com/spring-projects/spring-ldap/releases/tag/{version}") } } - library("Spring Pulsar", "2.0.7-SNAPSHOT") { + library("Spring Pulsar", "2.0.7-INTERNAL-SNAPSHOT") { firstParty() group("org.springframework.pulsar") { bom("spring-pulsar-bom") @@ -2570,7 +2570,7 @@ bom { releaseNotes("https://github.com/spring-projects/spring-restdocs/releases/tag/v{version}") } } - library("Spring Security", "7.0.7-SNAPSHOT") { + library("Spring Security", "7.0.7-INTERNAL-SNAPSHOT") { firstParty() group("org.springframework.security") { bom("spring-security-bom") @@ -2585,7 +2585,7 @@ bom { releaseNotes("https://github.com/spring-projects/spring-security/releases/tag/{version}") } } - library("Spring Session", "4.0.5-SNAPSHOT") { + library("Spring Session", "4.0.5-INTERNAL-SNAPSHOT") { firstParty() prohibit { startsWith(["Apple-", "Bean-", "Corn-", "Dragonfruit-"]) From 0ce829cbdb71596c1075cf1b1cb043bb2a24f10e Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Thu, 30 Jul 2026 13:03:08 +0100 Subject: [PATCH 03/20] Prepare release/4.0.8 branch --- .github/ISSUE_TEMPLATE/config.yml | 5 - .github/ISSUE_TEMPLATE/issue.md | 37 -------- .github/PULL_REQUEST_TEMPLATE.md | 29 ------ .../actions/await-http-resource/action.yml | 20 ---- .github/actions/build/action.yml | 88 ----------------- .../actions/create-github-release/action.yml | 34 ------- .../changelog-generator-commercial.yml | 30 ------ .../changelog-generator-oss.yml | 34 ------- .../actions/prepare-gradle-build/action.yml | 69 -------------- .../actions/print-jvm-thread-dumps/action.yml | 17 ---- .../actions/publish-gradle-plugin/action.yml | 38 -------- .../publish-gradle-plugin/artifacts.spec | 20 ---- .../publish-gradle-plugin/build.gradle | 30 ------ .../publish-gradle-plugin/settings.gradle | 16 ---- .github/actions/publish-to-sdkman/action.yml | 40 -------- .../actions/release-train-build/action.yml | 7 ++ .github/actions/release-train-test/action.yml | 7 ++ .github/actions/send-notification/action.yml | 39 -------- .../actions/sync-to-maven-central/action.yml | 36 ------- .../sync-to-maven-central/artifacts.spec | 20 ---- .../actions/update-homebrew-tap/action.yml | 36 ------- .github/dco.yml | 2 - .github/dependabot.yml | 16 ---- .github/scripts/reclaim-docker-diskspace.sh | 29 ------ .github/workflow-generator.yml | 20 ++++ .../workflows/build-and-deploy-snapshot.yml | 64 ------------- .github/workflows/ci.yml | 68 -------------- .github/workflows/release-train-build.yml | 93 ++++++++++++++++++ .github/workflows/release-train-join.yml | 55 +++++++++++ .github/workflows/release-train-leave.yml | 46 +++++++++ .github/workflows/release-train-ready.yml | 47 ++++++++++ .github/workflows/release-train-retry.yml | 34 +++++++ .github/workflows/release-train-test.yml | 91 ++++++++++++++++++ .github/workflows/verify.yml | 94 ------------------- gradle.properties | 2 +- 35 files changed, 401 insertions(+), 912 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE/config.yml delete mode 100644 .github/ISSUE_TEMPLATE/issue.md delete mode 100644 .github/PULL_REQUEST_TEMPLATE.md delete mode 100644 .github/actions/await-http-resource/action.yml delete mode 100644 .github/actions/build/action.yml delete mode 100644 .github/actions/create-github-release/action.yml delete mode 100644 .github/actions/create-github-release/changelog-generator-commercial.yml delete mode 100644 .github/actions/create-github-release/changelog-generator-oss.yml delete mode 100644 .github/actions/prepare-gradle-build/action.yml delete mode 100644 .github/actions/print-jvm-thread-dumps/action.yml delete mode 100644 .github/actions/publish-gradle-plugin/action.yml delete mode 100644 .github/actions/publish-gradle-plugin/artifacts.spec delete mode 100644 .github/actions/publish-gradle-plugin/build.gradle delete mode 100644 .github/actions/publish-gradle-plugin/settings.gradle delete mode 100644 .github/actions/publish-to-sdkman/action.yml create mode 100644 .github/actions/release-train-build/action.yml create mode 100644 .github/actions/release-train-test/action.yml delete mode 100644 .github/actions/send-notification/action.yml delete mode 100644 .github/actions/sync-to-maven-central/action.yml delete mode 100644 .github/actions/sync-to-maven-central/artifacts.spec delete mode 100644 .github/actions/update-homebrew-tap/action.yml delete mode 100644 .github/dco.yml delete mode 100644 .github/dependabot.yml delete mode 100755 .github/scripts/reclaim-docker-diskspace.sh create mode 100644 .github/workflow-generator.yml delete mode 100644 .github/workflows/build-and-deploy-snapshot.yml delete mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/release-train-build.yml create mode 100644 .github/workflows/release-train-join.yml create mode 100644 .github/workflows/release-train-leave.yml create mode 100644 .github/workflows/release-train-ready.yml create mode 100644 .github/workflows/release-train-retry.yml create mode 100644 .github/workflows/release-train-test.yml delete mode 100644 .github/workflows/verify.yml diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml deleted file mode 100644 index e12d999ad6d..00000000000 --- a/.github/ISSUE_TEMPLATE/config.yml +++ /dev/null @@ -1,5 +0,0 @@ -blank_issues_enabled: false -contact_links: - - name: Community Support - url: https://stackoverflow.com/tags/spring-boot - about: Please ask and answer questions on StackOverflow with the tag `spring-boot`. diff --git a/.github/ISSUE_TEMPLATE/issue.md b/.github/ISSUE_TEMPLATE/issue.md deleted file mode 100644 index e94a911d37c..00000000000 --- a/.github/ISSUE_TEMPLATE/issue.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -name: General -about: Bugs, enhancements, documentation, tasks. -title: '' -labels: '' -assignees: '' ---- - - diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md deleted file mode 100644 index 8ef2b756d14..00000000000 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ /dev/null @@ -1,29 +0,0 @@ - diff --git a/.github/actions/await-http-resource/action.yml b/.github/actions/await-http-resource/action.yml deleted file mode 100644 index ba177fb757b..00000000000 --- a/.github/actions/await-http-resource/action.yml +++ /dev/null @@ -1,20 +0,0 @@ -name: Await HTTP Resource -description: 'Waits for an HTTP resource to be available (a HEAD request succeeds)' -inputs: - url: - description: 'URL of the resource to await' - required: true -runs: - using: composite - steps: - - name: Await HTTP resource - shell: bash - run: | - url=${{ inputs.url }} - echo "Waiting for $url" - until curl --fail --head --silent ${{ inputs.url }} > /dev/null - do - echo "." - sleep 60 - done - echo "$url is available" diff --git a/.github/actions/build/action.yml b/.github/actions/build/action.yml deleted file mode 100644 index f1ac0393b98..00000000000 --- a/.github/actions/build/action.yml +++ /dev/null @@ -1,88 +0,0 @@ -name: Build -description: 'Builds the project, optionally publishing it to a local deployment repository' -inputs: - commercial-release-repository-url: - description: 'URL of the release repository' - required: false - commercial-repository-password: - description: 'Password for authentication with the commercial repository' - required: false - commercial-repository-username: - description: 'Username for authentication with the commercial repository' - required: false - commercial-snapshot-repository-url: - description: 'URL of the snapshot repository' - required: false - develocity-access-key: - description: 'Access key for authentication with ge.spring.io' - required: false - gradle-cache-read-only: - description: 'Whether Gradle''s cache should be read only' - required: false - default: 'true' - java-distribution: - description: 'Java distribution to use' - required: false - default: 'liberica' - java-early-access: - description: 'Whether the Java version is in early access' - required: false - default: 'false' - java-toolchain: - description: 'Whether a Java toolchain should be used' - required: false - default: 'false' - java-version: - description: 'Java version to compile and test with' - required: false - default: '25' - publish: - description: 'Whether to publish artifacts ready for deployment to Artifactory' - required: false - default: 'false' -outputs: - build-scan-url: - description: 'URL, if any, of the build scan produced by the build' - value: ${{ (inputs.publish == 'true' && steps.publish.outputs.build-scan-url) || steps.build.outputs.build-scan-url }} - version: - description: 'Version that was built' - value: ${{ steps.read-version.outputs.version }} -runs: - using: composite - steps: - - name: Prepare Gradle Build - uses: ./.github/actions/prepare-gradle-build - with: - cache-read-only: ${{ inputs.gradle-cache-read-only }} - develocity-access-key: ${{ inputs.develocity-access-key }} - java-distribution: ${{ inputs.java-distribution }} - java-early-access: ${{ inputs.java-early-access }} - java-toolchain: ${{ inputs.java-toolchain }} - java-version: ${{ inputs.java-version }} - - name: Build - id: build - if: ${{ inputs.publish == 'false' }} - shell: bash - env: - COMMERCIAL_RELEASE_REPO_URL: ${{ inputs.commercial-release-repository-url }} - COMMERCIAL_REPO_PASSWORD: ${{ inputs.commercial-repository-password }} - COMMERCIAL_REPO_USERNAME: ${{ inputs.commercial-repository-username }} - COMMERCIAL_SNAPSHOT_REPO_URL: ${{ inputs.commercial-snapshot-repository-url }} - run: ./gradlew build - - name: Publish - id: publish - if: ${{ inputs.publish == 'true' }} - shell: bash - env: - COMMERCIAL_RELEASE_REPO_URL: ${{ inputs.commercial-release-repository-url }} - COMMERCIAL_REPO_PASSWORD: ${{ inputs.commercial-repository-password }} - COMMERCIAL_REPO_USERNAME: ${{ inputs.commercial-repository-username }} - COMMERCIAL_SNAPSHOT_REPO_URL: ${{ inputs.commercial-snapshot-repository-url }} - run: ./gradlew -PdeploymentRepository=$(pwd)/deployment-repository ${{ !startsWith(github.event.head_commit.message, 'Next development version') && 'build' || '' }} publishAllPublicationsToDeploymentRepository - - name: Read Version From gradle.properties - id: read-version - shell: bash - run: | - version=$(sed -n 's/version=\(.*\)/\1/p' gradle.properties) - echo "Version is $version" - echo "version=$version" >> $GITHUB_OUTPUT diff --git a/.github/actions/create-github-release/action.yml b/.github/actions/create-github-release/action.yml deleted file mode 100644 index 275ff632f58..00000000000 --- a/.github/actions/create-github-release/action.yml +++ /dev/null @@ -1,34 +0,0 @@ -name: Create GitHub Release -description: 'Create the release on GitHub with a changelog' -inputs: - commercial: - description: 'Whether to generate the changelog for the commercial release' - required: true - latest: - description: 'Whether the release is the latest release' - required: false - default: 'false' - milestone: - description: 'Name of the GitHub milestone for which a release will be created' - required: true - pre-release: - description: 'Whether the release is a pre-release (a milestone or release candidate)' - required: false - default: 'false' - token: - description: 'Token to use for authentication with GitHub' - required: true -runs: - using: composite - steps: - - name: Generate Changelog - uses: spring-io/github-changelog-generator@f7d7a87a3e7c627ecb8c26cf086c38ac5a939721 #v0.0.14 - with: - config-file: ${{ inputs.commercial && '.github/actions/create-github-release/changelog-generator-commercial.yml' || '.github/actions/create-github-release/changelog-generator-oss.yml' }} - milestone: ${{ inputs.milestone }} - token: ${{ inputs.token }} - - name: Create GitHub Release - shell: bash - env: - GITHUB_TOKEN: ${{ inputs.token }} - run: gh release create ${{ format('v{0}', inputs.milestone) }} --notes-file changelog.md ${{ inputs.pre-release == 'true' && '--prerelease' || format('--latest={0}', inputs.latest) }} diff --git a/.github/actions/create-github-release/changelog-generator-commercial.yml b/.github/actions/create-github-release/changelog-generator-commercial.yml deleted file mode 100644 index e7ff74533e7..00000000000 --- a/.github/actions/create-github-release/changelog-generator-commercial.yml +++ /dev/null @@ -1,30 +0,0 @@ -changelog: - sections: - - title: ":warning: Attention Required" - labels: - - "for: upgrade-attention" - summary: - mode: "member-comment" - config: - prefix: "Attention required:" - - title: ":star: New Features" - labels: - - "type: enhancement" - - title: ":lady_beetle: Bug Fixes" - labels: - - "type: bug" - - "type: regression" - - title: ":notebook_with_decorative_cover: Documentation" - labels: - - "type: documentation" - - title: ":hammer: Dependency Upgrades" - sort: "title" - labels: - - "type: dependency-upgrade" - issues: - generate_links: false - ports: - - label: "status: forward-port" - bodyExpression: 'Forward port of issue #(\d+).*' - - label: "status: back-port" - bodyExpression: 'Back port of issue #(\d+).*' diff --git a/.github/actions/create-github-release/changelog-generator-oss.yml b/.github/actions/create-github-release/changelog-generator-oss.yml deleted file mode 100644 index 56f6608cd7a..00000000000 --- a/.github/actions/create-github-release/changelog-generator-oss.yml +++ /dev/null @@ -1,34 +0,0 @@ -changelog: - sections: - - title: ":warning: Attention Required" - labels: - - "for: upgrade-attention" - summary: - mode: "member-comment" - config: - prefix: "Attention required:" - - title: ":star: New Features" - labels: - - "type: enhancement" - - title: ":lady_beetle: Bug Fixes" - labels: - - "type: bug" - - "type: regression" - - title: ":notebook_with_decorative_cover: Documentation" - labels: - - "type: documentation" - - title: ":hammer: Dependency Upgrades" - sort: "title" - labels: - - "type: dependency-upgrade" - summary: - mode: "body-regex" - config: - expression: '(Upgrade to \[.*\]\(.*\)).*' - issues: - generate_links: true - ports: - - label: "status: forward-port" - bodyExpression: 'Forward port of issue #(\d+).*' - - label: "status: back-port" - bodyExpression: 'Back port of issue #(\d+).*' diff --git a/.github/actions/prepare-gradle-build/action.yml b/.github/actions/prepare-gradle-build/action.yml deleted file mode 100644 index 508c88ae787..00000000000 --- a/.github/actions/prepare-gradle-build/action.yml +++ /dev/null @@ -1,69 +0,0 @@ -name: Prepare Gradle Build -description: 'Prepares a Gradle build. Sets up Java and Gradle and configures Gradle properties' -inputs: - cache-read-only: - description: 'Whether Gradle''s cache should be read only' - required: false - default: 'true' - develocity-access-key: - description: 'Access key for authentication with ge.spring.io' - required: false - java-distribution: - description: 'Java distribution to use' - required: false - default: 'liberica' - java-early-access: - description: 'Whether the Java version is in early access. When true, forces java-distribution to temurin' - required: false - default: 'false' - java-toolchain: - description: 'Whether a Java toolchain should be used' - required: false - default: 'false' - java-version: - description: 'Java version to use for the build' - required: false - default: '25' -runs: - using: composite - steps: - - name: Free Disk Space - if: ${{ runner.os == 'Linux' }} - uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be # v1.3.1 - with: - tool-cache: true - docker-images: false - - name: Set Up Java - uses: actions/setup-java@v5 - with: - distribution: ${{ inputs.java-early-access == 'true' && 'temurin' || (inputs.java-distribution || 'liberica') }} - java-version: | - ${{ inputs.java-early-access == 'true' && format('{0}-ea', inputs.java-version) || inputs.java-version }} - ${{ inputs.java-toolchain == 'true' && '25' || '' }} - - name: Set Up Gradle With Read/Write Cache - if: ${{ inputs.cache-read-only == 'false' }} - uses: gradle/actions/setup-gradle@9c971963bec38e04b3d30dcc455b5382be2fdbfb # v6.3.0 - with: - cache-provider: basic - cache-read-only: false - develocity-access-key: ${{ inputs.develocity-access-key }} - - name: Set Up Gradle - uses: gradle/actions/setup-gradle@9c971963bec38e04b3d30dcc455b5382be2fdbfb # v6.3.0 - with: - cache-provider: basic - develocity-access-key: ${{ inputs.develocity-access-key }} - develocity-token-expiry: 4 - - name: Configure Gradle Properties - shell: bash - run: | - echo 'systemProp.user.name=spring-builds+github' >> $GRADLE_USER_HOME/gradle.properties - echo 'systemProp.org.gradle.internal.launcher.welcomeMessageEnabled=false' >> $GRADLE_USER_HOME/gradle.properties - echo 'org.gradle.daemon=false' >> $GRADLE_USER_HOME/gradle.properties - - name: Configure Toolchain Properties - if: ${{ inputs.java-toolchain == 'true' }} - shell: bash - run: | - echo toolchainVersion=${{ inputs.java-version }} >> $GRADLE_USER_HOME/gradle.properties - echo systemProp.org.gradle.java.installations.auto-detect=false >> $GRADLE_USER_HOME/gradle.properties - echo systemProp.org.gradle.java.installations.auto-download=false >> $GRADLE_USER_HOME/gradle.properties - echo systemProp.org.gradle.java.installations.paths=${{ format('$JAVA_HOME_{0}_X64', inputs.java-version) }} >> $GRADLE_USER_HOME/gradle.properties diff --git a/.github/actions/print-jvm-thread-dumps/action.yml b/.github/actions/print-jvm-thread-dumps/action.yml deleted file mode 100644 index bcaebf3676a..00000000000 --- a/.github/actions/print-jvm-thread-dumps/action.yml +++ /dev/null @@ -1,17 +0,0 @@ -name: Print JVM thread dumps -description: 'Prints a thread dump for all running JVMs' -runs: - using: composite - steps: - - if: ${{ runner.os == 'Linux' }} - shell: bash - run: | - for jvm_pid in $(jps -q -J-XX:+PerfDisableSharedMem); do - jcmd $jvm_pid Thread.print - done - - if: ${{ runner.os == 'Windows' }} - shell: powershell - run: | - foreach ($jvm_pid in $(jps -q -J-XX:+PerfDisableSharedMem)) { - jcmd $jvm_pid Thread.print - } diff --git a/.github/actions/publish-gradle-plugin/action.yml b/.github/actions/publish-gradle-plugin/action.yml deleted file mode 100644 index e01647c9efd..00000000000 --- a/.github/actions/publish-gradle-plugin/action.yml +++ /dev/null @@ -1,38 +0,0 @@ -name: Publish Gradle Plugin -description: 'Publishes Spring Boot''s Gradle plugin to the Plugin Portal' -inputs: - build-number: - description: 'Build number to use when downloading plugin artifacts' - required: false - default: ${{ github.run_number }} - gradle-plugin-publish-key: - description: 'Gradle publishing key' - required: true - gradle-plugin-publish-secret: - description: 'Gradle publishing secret' - required: true - jfrog-cli-config-token: - description: 'Config token for the JFrog CLI' - required: true - plugin-version: - description: 'Version of the plugin' - required: true -runs: - using: composite - steps: - - name: Set Up JFrog CLI - uses: jfrog/setup-jfrog-cli@deda456d982fc5e9a7a020b63eb0d2968aedd33e # v5.1.0 - env: - JF_ENV_SPRING: ${{ inputs.jfrog-cli-config-token }} - - name: Download Artifacts - shell: bash - run: jf rt download --spec ${{ format('{0}/artifacts.spec', github.action_path) }} --spec-vars 'buildName=${{ format('spring-boot-{0}', inputs.plugin-version) }};buildNumber=${{ inputs.build-number }}' - - name: Set Up Java - uses: actions/setup-java@v5 - with: - distribution: 'liberica' - java-version: '17' - - name: Publish - shell: bash - working-directory: ${{ github.action_path }} - run: ${{ github.workspace }}/gradlew publishExisting -Pgradle.publish.key=${{ inputs.gradle-plugin-publish-key }} -Pgradle.publish.secret=${{ inputs.gradle-plugin-publish-secret }} -PbootVersion=${{ inputs.plugin-version }} -PrepositoryRoot=${{ github.workspace }}/repository diff --git a/.github/actions/publish-gradle-plugin/artifacts.spec b/.github/actions/publish-gradle-plugin/artifacts.spec deleted file mode 100644 index f84a25bb9b1..00000000000 --- a/.github/actions/publish-gradle-plugin/artifacts.spec +++ /dev/null @@ -1,20 +0,0 @@ -{ - "files": [ - { - "aql": { - "items.find": { - "$and": [ - { - "@build.name": "${buildName}", - "@build.number": "${buildNumber}", - "path": { - "$match": "org/springframework/boot/spring-boot-gradle-plugin/*" - } - } - ] - } - }, - "target": "repository/" - } - ] -} diff --git a/.github/actions/publish-gradle-plugin/build.gradle b/.github/actions/publish-gradle-plugin/build.gradle deleted file mode 100644 index 0ce1e04d4b2..00000000000 --- a/.github/actions/publish-gradle-plugin/build.gradle +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * 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 - * - * https://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. - */ - -plugins { - id "com.gradle.plugin-publish" version "1.2.1" -} - -tasks.register("publishExisting", com.gradle.publish.PublishExistingTask) { - pluginId = "org.springframework.boot" - fileRepositoryRoot = new File("${repositoryRoot}") - pluginVersion = "${bootVersion}" - pluginCoordinates = "org.springframework.boot:spring-boot-gradle-plugin:${bootVersion}" - displayName = "Spring Boot Gradle Plugin" - pluginDescription = "Spring Boot Gradle Plugin" - website = "https://spring.io/projects/spring-boot" - vcsUrl = "https://github.com/spring-projects/spring-boot" -} diff --git a/.github/actions/publish-gradle-plugin/settings.gradle b/.github/actions/publish-gradle-plugin/settings.gradle deleted file mode 100644 index 1a5705e043c..00000000000 --- a/.github/actions/publish-gradle-plugin/settings.gradle +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright 2012-present the original author or authors. - * - * 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 - * - * https://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. - */ - diff --git a/.github/actions/publish-to-sdkman/action.yml b/.github/actions/publish-to-sdkman/action.yml deleted file mode 100644 index 3abdd67e27b..00000000000 --- a/.github/actions/publish-to-sdkman/action.yml +++ /dev/null @@ -1,40 +0,0 @@ -name: Publish to SDKMAN! -description: 'Publishes the release as a new candidate version on SDKMAN!' -inputs: - make-default: - description: 'Whether the release should be made the default version' - required: false - default: 'false' - sdkman-consumer-key: - description: 'Key for publishing to SDKMAN!' - required: true - sdkman-consumer-token: - description: 'Token for publishing to SDKMAN!' - required: true - spring-boot-version: - description: 'Version to publish' - required: true -runs: - using: composite - steps: - - name: Publish Release - shell: bash - run: > - curl -X POST \ - -H "Consumer-Key: ${{ inputs.sdkman-consumer-key }}" \ - -H "Consumer-Token: ${{ inputs.sdkman-consumer-token }}" \ - -H "Content-Type: application/json" \ - -H "Accept: application/json" \ - -d '{"candidate": "springboot", "version": "${{ inputs.spring-boot-version }}", "url": "${{ format('https://repo.maven.apache.org/maven2/org/springframework/boot/spring-boot-cli/{0}/spring-boot-cli-{0}-bin.zip', inputs.spring-boot-version) }}"}' \ - https://vendors.sdkman.io/release - - name: Flag Release as Default - if: ${{ inputs.make-default == 'true' }} - shell: bash - run: > - curl -X PUT \ - -H "Consumer-Key: ${{ inputs.sdkman-consumer-key }}" \ - -H "Consumer-Token: ${{ inputs.sdkman-consumer-token }}" \ - -H "Content-Type: application/json" \ - -H "Accept: application/json" \ - -d '{"candidate": "springboot", "version": "${{ inputs.spring-boot-version }}"}' \ - https://vendors.sdkman.io/default diff --git a/.github/actions/release-train-build/action.yml b/.github/actions/release-train-build/action.yml new file mode 100644 index 00000000000..c67b712cb7d --- /dev/null +++ b/.github/actions/release-train-build/action.yml @@ -0,0 +1,7 @@ +name: Build Release +runs: + using: composite + steps: + - name: Build Release + shell: bash + run: ./gradlew -PdeploymentRepository=$(pwd)/deployment-repository publishAllPublicationsToDeploymentRepository diff --git a/.github/actions/release-train-test/action.yml b/.github/actions/release-train-test/action.yml new file mode 100644 index 00000000000..8351f7635c5 --- /dev/null +++ b/.github/actions/release-train-test/action.yml @@ -0,0 +1,7 @@ +name: Test Release +runs: + using: composite + steps: + - name: Test Release + shell: bash + run: ./gradlew build -x dockerTest -x reclaimDockerSpace diff --git a/.github/actions/send-notification/action.yml b/.github/actions/send-notification/action.yml deleted file mode 100644 index b379e67897d..00000000000 --- a/.github/actions/send-notification/action.yml +++ /dev/null @@ -1,39 +0,0 @@ -name: Send Notification -description: 'Sends a Google Chat message as a notification of the job''s outcome' -inputs: - build-scan-url: - description: 'URL of the build scan to include in the notification' - required: false - run-name: - description: 'Name of the run to include in the notification' - required: false - default: ${{ format('{0} {1}', github.ref_name, github.job) }} - status: - description: 'Status of the job' - required: true - webhook-url: - description: 'Google Chat Webhook URL' - required: true -runs: - using: composite - steps: - - name: Prepare Variables - shell: bash - run: | - echo "BUILD_SCAN=${{ inputs.build-scan-url == '' && ' [build scan unavailable]' || format(' [<{0}|Build Scan>]', inputs.build-scan-url) }}" >> "$GITHUB_ENV" - echo "RUN_URL=${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" >> "$GITHUB_ENV" - - name: Success Notification - if: ${{ inputs.status == 'success' }} - shell: bash - run: | - curl -X POST '${{ inputs.webhook-url }}' -H 'Content-Type: application/json' -d '{ text: "<${{ env.RUN_URL }}|${{ inputs.run-name }}> was successful ${{ env.BUILD_SCAN }}"}' || true - - name: Failure Notification - if: ${{ inputs.status == 'failure' }} - shell: bash - run: | - curl -X POST '${{ inputs.webhook-url }}' -H 'Content-Type: application/json' -d '{ text: " *<${{ env.RUN_URL }}|${{ inputs.run-name }}> failed* ${{ env.BUILD_SCAN }}"}' || true - - name: Cancel Notification - if: ${{ inputs.status == 'cancelled' }} - shell: bash - run: | - curl -X POST '${{ inputs.webhook-url }}' -H 'Content-Type: application/json' -d '{ text: "<${{ env.RUN_URL }}|${{ inputs.run-name }}> was cancelled"}' || true diff --git a/.github/actions/sync-to-maven-central/action.yml b/.github/actions/sync-to-maven-central/action.yml deleted file mode 100644 index 02152b40647..00000000000 --- a/.github/actions/sync-to-maven-central/action.yml +++ /dev/null @@ -1,36 +0,0 @@ -name: Sync to Maven Central -description: 'Syncs a release to Maven Central and waits for it to be available for use' -inputs: - central-token-password: - description: 'Password for authentication with central.sonatype.com' - required: true - central-token-username: - description: 'Username for authentication with central.sonatype.com' - required: true - jfrog-cli-config-token: - description: 'Config token for the JFrog CLI' - required: true - spring-boot-version: - description: 'Version of Spring Boot that is being synced to Central' - required: true -runs: - using: composite - steps: - - name: Set Up JFrog CLI - uses: jfrog/setup-jfrog-cli@deda456d982fc5e9a7a020b63eb0d2968aedd33e # v5.1.0 - env: - JF_ENV_SPRING: ${{ inputs.jfrog-cli-config-token }} - - name: Download Release Artifacts - shell: bash - run: jf rt download --spec ${{ format('{0}/artifacts.spec', github.action_path) }} --spec-vars 'buildName=${{ format('spring-boot-{0}', inputs.spring-boot-version) }};buildNumber=${{ github.run_number }}' - - name: Sync - uses: spring-io/central-publish-action@0c03960e9b16fdfe70e2443e1d5393cbc3a35622 # v0.3.0 - with: - token: ${{ inputs.central-token-password }} - token-name: ${{ inputs.central-token-username }} - ignore-already-exists-error: true - timeout: "90m" - - name: Await - uses: ./.github/actions/await-http-resource - with: - url: ${{ format('https://repo.maven.apache.org/maven2/org/springframework/boot/spring-boot/{0}/spring-boot-{0}.jar', inputs.spring-boot-version) }} diff --git a/.github/actions/sync-to-maven-central/artifacts.spec b/.github/actions/sync-to-maven-central/artifacts.spec deleted file mode 100644 index ee3d451af33..00000000000 --- a/.github/actions/sync-to-maven-central/artifacts.spec +++ /dev/null @@ -1,20 +0,0 @@ -{ - "files": [ - { - "aql": { - "items.find": { - "$and": [ - { - "@build.name": "${buildName}", - "@build.number": "${buildNumber}", - "path": { - "$nmatch": "org/springframework/boot/spring-boot-docs/*" - } - } - ] - } - }, - "target": "nexus/" - } - ] -} diff --git a/.github/actions/update-homebrew-tap/action.yml b/.github/actions/update-homebrew-tap/action.yml deleted file mode 100644 index e240cb0b119..00000000000 --- a/.github/actions/update-homebrew-tap/action.yml +++ /dev/null @@ -1,36 +0,0 @@ -name: Update Homebrew Tap -description: Updates the Homebrew Tap for the Spring Boot CLI -inputs: - spring-boot-version: - description: 'The version to publish' - required: true - token: - description: 'Token to use for GitHub authentication' - required: true -runs: - using: composite - steps: - - name: Check Out Homebrew Tap Repo - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - with: - path: updated-homebrew-tap-repo - repository: spring-io/homebrew-tap - token: ${{ inputs.token }} - - name: Await Formula - uses: ./.github/actions/await-http-resource - with: - url: https://repo.maven.apache.org/maven2/org/springframework/boot/spring-boot-cli/${{ inputs.spring-boot-version }}/spring-boot-cli-${{ inputs.spring-boot-version }}-homebrew.rb - - name: Update Homebrew Tap - shell: bash - run: | - pushd updated-homebrew-tap-repo > /dev/null - curl https://repo.maven.apache.org/maven2/org/springframework/boot/spring-boot-cli/${{ inputs.spring-boot-version }}/spring-boot-cli-${{ inputs.spring-boot-version }}-homebrew.rb --output spring-boot-cli-${{ inputs.spring-boot-version }}-homebrew.rb - rm spring-boot.rb - mv spring-boot-cli-*.rb spring-boot.rb - git config user.name "Spring Builds" > /dev/null - git config user.email "spring-builds@users.noreply.github.com" > /dev/null - git add spring-boot.rb > /dev/null - git commit -m "Upgrade to Spring Boot ${{ inputs.spring-boot-version }}" > /dev/null - git push - echo "DONE" - popd > /dev/null diff --git a/.github/dco.yml b/.github/dco.yml deleted file mode 100644 index 0c4b142e9a7..00000000000 --- a/.github/dco.yml +++ /dev/null @@ -1,2 +0,0 @@ -require: - members: false diff --git a/.github/dependabot.yml b/.github/dependabot.yml deleted file mode 100644 index 9eab3b40a60..00000000000 --- a/.github/dependabot.yml +++ /dev/null @@ -1,16 +0,0 @@ -version: 2 -updates: - - package-ecosystem: "github-actions" - directory: "/" - schedule: - interval: "weekly" - labels: - - "type: task" - - "status: waiting-for-triage" - - package-ecosystem: "npm" - directory: "/antora" - schedule: - interval: "weekly" - labels: - - "type: task" - - "status: waiting-for-triage" diff --git a/.github/scripts/reclaim-docker-diskspace.sh b/.github/scripts/reclaim-docker-diskspace.sh deleted file mode 100755 index e32f3b1d8c8..00000000000 --- a/.github/scripts/reclaim-docker-diskspace.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/bin/bash - -echo "Reclaiming Docker Disk Space" -echo - -docker image ls --format "{{.Size}} {{.ID}} {{.Repository}} {{.Tag}}" | LANG=en_US sort -rh | while read line; do - size=$( echo "$line" | cut -d' ' -f1 | sed -e 's/\.[0-9]*//' | sed -e 's/MB/000000/' | sed -e 's/GB/000000000/' ) - image=$( echo "$line" | cut -d' ' -f2 ) - repository=$( echo "$line" | cut -d' ' -f3 ) - tag=$( echo "$line" | cut -d' ' -f4 ) - echo "Considering $image $repository:$tag $size" - if [[ "$tag" =~ ^[a-f0-9]{32}$ ]]; then - echo "Ignoring GitHub action image $image $repository:$tag" - elif [[ "$tag" == "" ]]; then - echo "Ignoring untagged image $image $repository:$tag" - elif [[ "$size" -lt 200000000 ]]; then - echo "Ignoring small image $image $repository:$tag" - else - echo "Cleaning $image $repository:$tag" - docker image rm $image - fi -done - -echo "Finished cleanup, leaving the following containers:" -echo -docker image ls --format "{{.Size}} {{.ID}} {{.Repository}}:{{.Tag}}" | LANG=en_US sort -rh -echo -df -h -echo diff --git a/.github/workflow-generator.yml b/.github/workflow-generator.yml new file mode 100644 index 00000000000..d5159bac482 --- /dev/null +++ b/.github/workflow-generator.yml @@ -0,0 +1,20 @@ +workflow: + generator: + project: + java: + versions: + primary: 25 + workflows: + release-train: + build: + env: + COMMERCIAL_RELEASE_REPO_URL: vars.COMMERCIAL_RELEASE_REPO_URL + COMMERCIAL_REPO_USERNAME: secrets.COMMERCIAL_ARTIFACTORY_USERNAME + COMMERCIAL_REPO_PASSWORD: secrets.COMMERCIAL_ARTIFACTORY_PASSWORD + test: + env: + COMMERCIAL_RELEASE_REPO_URL: vars.COMMERCIAL_RELEASE_REPO_URL + COMMERCIAL_REPO_USERNAME: secrets.COMMERCIAL_ARTIFACTORY_USERNAME + COMMERCIAL_REPO_PASSWORD: secrets.COMMERCIAL_ARTIFACTORY_PASSWORD + free-disk-space: true + runs-on: ubuntu22-4-16 diff --git a/.github/workflows/build-and-deploy-snapshot.yml b/.github/workflows/build-and-deploy-snapshot.yml deleted file mode 100644 index 24ca5e56ea4..00000000000 --- a/.github/workflows/build-and-deploy-snapshot.yml +++ /dev/null @@ -1,64 +0,0 @@ -name: Build and Deploy Snapshot -on: - workflow_dispatch: - push: - branches: - - '4.0.x-internal' -permissions: - contents: read -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} -jobs: - build-and-deploy-snapshot: - name: Build and Deploy Snapshot - if: ${{ github.repository == 'spring-projects/spring-boot' || github.repository == 'spring-projects/spring-boot-commercial' }} - runs-on: ${{ vars.UBUNTU_MEDIUM || 'ubuntu-latest' }} - steps: - - name: Check Out Code - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - - name: Build and Publish - id: build-and-publish - uses: ./.github/actions/build - with: - commercial-release-repository-url: ${{ vars.COMMERCIAL_RELEASE_REPO_URL }} - commercial-repository-password: ${{ secrets.COMMERCIAL_ARTIFACTORY_PASSWORD }} - commercial-repository-username: ${{ secrets.COMMERCIAL_ARTIFACTORY_USERNAME }} - commercial-snapshot-repository-url: ${{ vars.COMMERCIAL_SNAPSHOT_REPO_URL }} - gradle-cache-read-only: false - publish: true - - name: Deploy - uses: spring-io/artifactory-deploy-action@926d7f7cc810569395346bf3a4d91b380b3e355b # v0.0.4 - with: - build-name: ${{ vars.COMMERCIAL && format('spring-boot-commercial-{0}', '4.0.x') || format('spring-boot-{0}', '4.0.x') }} - folder: 'deployment-repository' - password: ${{ vars.COMMERCIAL && secrets.COMMERCIAL_ARTIFACTORY_PASSWORD || secrets.ARTIFACTORY_PASSWORD }} - project: ${{ vars.COMMERCIAL && 'spring' }} - repository: ${{ vars.COMMERCIAL && 'spring-enterprise-maven-dev-local' || 'libs-snapshot-local' }} - signing-key: ${{ secrets.GPG_PRIVATE_KEY }} - signing-passphrase: ${{ secrets.GPG_PASSPHRASE }} - threads: 8 - uri: ${{ vars.COMMERCIAL_DEPLOY_REPO_URL || 'https://repo.spring.io' }} - username: ${{ vars.COMMERCIAL && secrets.COMMERCIAL_ARTIFACTORY_USERNAME || secrets.ARTIFACTORY_USERNAME }} - - name: Send Notification - if: always() - uses: ./.github/actions/send-notification - with: - build-scan-url: ${{ steps.build-and-publish.outputs.build-scan-url }} - run-name: ${{ format('{0} | Linux | Java 25', github.ref_name) }} - status: ${{ job.status }} - webhook-url: ${{ secrets.GOOGLE_CHAT_WEBHOOK_URL }} - outputs: - version: ${{ steps.build-and-publish.outputs.version }} - verify: - name: Verify - needs: build-and-deploy-snapshot - uses: ./.github/workflows/verify.yml - secrets: - commercial-repository-password: ${{ secrets.COMMERCIAL_ARTIFACTORY_PASSWORD }} - commercial-repository-username: ${{ secrets.COMMERCIAL_ARTIFACTORY_USERNAME }} - google-chat-webhook-url: ${{ secrets.GOOGLE_CHAT_WEBHOOK_URL }} - opensource-repository-password: ${{ secrets.ARTIFACTORY_PASSWORD }} - opensource-repository-username: ${{ secrets.ARTIFACTORY_USERNAME }} - token: ${{ secrets.GH_ACTIONS_REPO_TOKEN }} - with: - version: ${{ needs.build-and-deploy-snapshot.outputs.version }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml deleted file mode 100644 index 13722cd74f2..00000000000 --- a/.github/workflows/ci.yml +++ /dev/null @@ -1,68 +0,0 @@ -name: CI -on: - push: - branches: - - '4.0.x-internal' - schedule: - - cron: '30 05 * * *' -permissions: - contents: read -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} -jobs: - ci: - name: '${{ matrix.os.name}} | Java ${{ matrix.java.version}}' - if: ${{ github.repository == 'spring-projects/spring-boot' || github.repository == 'spring-projects/spring-boot-commercial' }} - runs-on: ${{ matrix.os.id }} - strategy: - fail-fast: false - matrix: - os: - - id: ${{ vars.UBUNTU_MEDIUM || 'ubuntu-latest' }} - name: Linux - - id: windows-latest - name: Windows - java: - - version: 17 - toolchain: true - - version: 21 - toolchain: true - - version: 25 - toolchain: false - - version: 26 - toolchain: true - exclude: - - os: - name: Linux - java: - version: 25 - steps: - - name: Prepare Windows runner - if: ${{ runner.os == 'Windows' }} - run: | - git config --global core.autocrlf true - git config --global core.longPaths true - Stop-Service -name Docker - - name: Check Out Code - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - - name: Build - id: build - uses: ./.github/actions/build - with: - commercial-release-repository-url: 'https://repo.spring.io/artifactory/spring-commercial-release-remote' - commercial-repository-password: ${{ secrets.ARTIFACTORY_PASSWORD }} - commercial-repository-username: ${{ secrets.ARTIFACTORY_USERNAME }} - commercial-snapshot-repository-url: 'https://repo.spring.io/artifactory/spring-commercial-snapshot-remote' - gradle-cache-read-only: false - java-early-access: ${{ matrix.java.early-access || 'false' }} - java-distribution: ${{ matrix.java.distribution }} - java-toolchain: ${{ matrix.java.toolchain }} - java-version: ${{ matrix.java.version }} - - name: Send Notification - if: always() - uses: ./.github/actions/send-notification - with: - build-scan-url: ${{ steps.build.outputs.build-scan-url }} - run-name: ${{ format('{0} | {1} | Java {2}', github.ref_name, matrix.os.name, matrix.java.version) }} - status: ${{ job.status }} - webhook-url: ${{ secrets.GOOGLE_CHAT_WEBHOOK_URL }} diff --git a/.github/workflows/release-train-build.yml b/.github/workflows/release-train-build.yml new file mode 100644 index 00000000000..e2789a7dc1c --- /dev/null +++ b/.github/workflows/release-train-build.yml @@ -0,0 +1,93 @@ +# This file was auto-generated by github-actions-workflow-generator 0.0.6. Do not edit. +# To update it, modify .github/workflow-generator.yml as needed and re-run the generator. + +name: "Release Train – Build" +run-name: "${{ inputs.callback-ref }} – Build" +"on": + workflow_dispatch: + inputs: + callback: + description: "Repository to which a callback should be made upon completion" + required: true + type: "string" + callback-ref: + description: "Ref in the callback repository to which a callback should be made upon completion" + required: true + type: "string" + release-train-maven-repository-url: + description: "URL of a Maven repository to be used to resolve artifacts of projects earlier in the train" + required: true + type: "string" +permissions: + contents: "read" +concurrency: + group: "${{ github.workflow }}-${{ github.ref }}" +jobs: + build-release: + name: "Build Release" + runs-on: "ubuntu22-2-8" + steps: + - name: "Prevent Re-runs" + id: "prevent-re-runs" + run: |- + if [ "$GITHUB_RUN_ATTEMPT" -gt 1 ]; then + echo "Re-runs are prohibited. Use the 'Release Train – Retry' workflow to retry build failures" + exit 1 + fi + - name: "Set up Java" + id: "set-up-java" + uses: "actions/setup-java@03ad4de0992f5dab5e18fcb136590ce7c4a0ac95" # v5.6.0 + with: + distribution: "liberica" + java-version: "25" + - name: "Check Out Code" + id: "check-out-code" + uses: "actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0" # v7.0.0 + - name: "Build Release" + id: "build-release" + uses: "./.github/actions/release-train-build" + env: + COMMERCIAL_RELEASE_REPO_URL: "${{ vars.COMMERCIAL_RELEASE_REPO_URL }}" + COMMERCIAL_REPO_PASSWORD: "${{ secrets.COMMERCIAL_ARTIFACTORY_PASSWORD }}" + COMMERCIAL_REPO_USERNAME: "${{ secrets.COMMERCIAL_ARTIFACTORY_USERNAME }}" + RELEASE_TRAIN_MAVEN_REPOSITORY_PASSWORD: "${{ secrets.RELEASE_TRAIN_PARTICIPANT_MAVEN_REPOSITORY_PASSWORD }}" + RELEASE_TRAIN_MAVEN_REPOSITORY_URL: "${{ inputs.release-train-maven-repository-url }}" + RELEASE_TRAIN_MAVEN_REPOSITORY_USERNAME: "${{ secrets.RELEASE_TRAIN_PARTICIPANT_MAVEN_REPOSITORY_USERNAME }}" + - name: "Upload Deployment Repository" + id: "upload-deployment-repository" + uses: "actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a" # v7.0.1 + with: + name: "deployment-repository" + path: "deployment-repository/**" + - name: "Upload Deployment Spec" + id: "upload-deployment-spec" + uses: "actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a" # v7.0.1 + with: + archive: "false" + if-no-files-found: "ignore" + name: "deployment-spec" + path: ".github/actions/release-train-build/deployment-spec.yml" + - name: "Save Build System Caches" + id: "save-build-system-caches" + uses: "actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9" # v6.1.0 + with: + key: "release-train-${{ inputs.callback-ref }}-${{ github.ref_name }}" + path: |- + ~/.gradle/caches + ~/.gradle/wrapper + - name: "Send Callback" + id: "send-callback" + if: "${{ !cancelled() }}" + env: + GH_TOKEN: "${{ secrets.RELEASE_TRAIN_PARTICIPANT_GITHUB_TOKEN }}" + run: |- + gh workflow run callback \ + --repo ${{ inputs.callback }} \ + --ref ${{ inputs.callback-ref }} \ + --field commit-hash=${{ steps.check-out-code.outputs.commit }} \ + --field deployment-repository-artifact-identifier=${{ steps.upload-deployment-repository.outputs.artifact-id }} \ + --field deployment-spec-artifact-identifier=${{ steps.upload-deployment-spec.outputs.artifact-id }} \ + --field release-branch=${{ github.ref_name }} \ + --field release-repository=${{ github.repository }} \ + --field result=${{ job.status == 'success' && 'built' || 'build-failed' }} \ + --field workflow-run-url=${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} diff --git a/.github/workflows/release-train-join.yml b/.github/workflows/release-train-join.yml new file mode 100644 index 00000000000..729914b3f90 --- /dev/null +++ b/.github/workflows/release-train-join.yml @@ -0,0 +1,55 @@ +# This file was auto-generated by github-actions-workflow-generator 0.0.6. Do not edit. +# To update it, modify .github/workflow-generator.yml as needed and re-run the generator. + +name: "Release Train – Join" +run-name: "${{ inputs.release-train }} – Join" +"on": + workflow_dispatch: + inputs: + deployment-destination: + description: "Destination to which the release should be deployed" + options: + - "Maven Central" + - "Spring Enterprise" + required: true + type: "choice" + release-train: + description: "Release train" + required: true + type: "string" + release-train-repository: + default: "spring-io/release-train" + description: "Release train repository" + required: true + type: "string" +permissions: + contents: "none" +jobs: + join-release-train: + name: "Join Release Train" + runs-on: "ubuntu-latest" + steps: + - name: "Join Release Train" + id: "join-release-train" + env: + GH_TOKEN: "${{ secrets.RELEASE_TRAIN_PARTICIPANT_GITHUB_TOKEN }}" + run: |- + run_url=$( + gh workflow run join \ + --repo ${{ inputs.release-train-repository }} \ + --ref ${{ inputs.release-train }} \ + --field commit-hash=${{ github.sha }} \ + --field deployment-destination=${{ inputs.deployment-destination == 'Maven Central' && 'maven-central' || 'spring-enterprise' }} \ + --field release-branch=${{ github.ref_name }} \ + --field release-repository=${{ github.repository }} + ) + echo "Dispatched workflow run. Waiting for $run_url to complete." + run_id=${run_url##*/} + watch_exit_code=0 + gh run watch $run_id --repo ${{ inputs.release-train-repository }} --exit-status --interval=3 > /dev/null 2>&1 || watch_exit_code=$? + if [[ $watch_exit_code -eq 0 ]]; then + echo "Workflow run succeeded." + else + echo "Workflow run failed." + fi + exit $watch_exit_code diff --git a/.github/workflows/release-train-leave.yml b/.github/workflows/release-train-leave.yml new file mode 100644 index 00000000000..bc0be6711a7 --- /dev/null +++ b/.github/workflows/release-train-leave.yml @@ -0,0 +1,46 @@ +# This file was auto-generated by github-actions-workflow-generator 0.0.6. Do not edit. +# To update it, modify .github/workflow-generator.yml as needed and re-run the generator. + +name: "Release Train – Leave" +run-name: "${{ inputs.release-train }} – Leave" +"on": + workflow_dispatch: + inputs: + release-train: + description: "Release train" + required: true + type: "string" + release-train-repository: + default: "spring-io/release-train" + description: "Release train repository" + required: true + type: "string" +permissions: + contents: "none" +jobs: + leave: + name: "Leave" + runs-on: "ubuntu-latest" + steps: + - name: "Leave" + id: "leave" + env: + GH_TOKEN: "${{ secrets.RELEASE_TRAIN_PARTICIPANT_GITHUB_TOKEN }}" + run: |- + run_url=$( + gh workflow run leave \ + --repo ${{ inputs.release-train-repository }} \ + --ref ${{ inputs.release-train }} \ + --field release-branch=${{ github.ref_name }} \ + --field release-repository=${{ github.repository }} + ) + echo "Dispatched workflow run. Waiting for $run_url to complete." + run_id=${run_url##*/} + watch_exit_code=0 + gh run watch $run_id --repo ${{ inputs.release-train-repository }} --exit-status --interval=3 > /dev/null 2>&1 || watch_exit_code=$? + if [[ $watch_exit_code -eq 0 ]]; then + echo "Workflow run succeeded." + else + echo "Workflow run failed." + fi + exit $watch_exit_code diff --git a/.github/workflows/release-train-ready.yml b/.github/workflows/release-train-ready.yml new file mode 100644 index 00000000000..794a29a6292 --- /dev/null +++ b/.github/workflows/release-train-ready.yml @@ -0,0 +1,47 @@ +# This file was auto-generated by github-actions-workflow-generator 0.0.6. Do not edit. +# To update it, modify .github/workflow-generator.yml as needed and re-run the generator. + +name: "Release Train – Ready" +run-name: "${{ inputs.release-train }} – Ready" +"on": + workflow_dispatch: + inputs: + release-train: + description: "Release train" + required: true + type: "string" + release-train-repository: + default: "spring-io/release-train" + description: "Release train repository" + required: true + type: "string" +permissions: + contents: "none" +jobs: + ready: + name: "Ready" + runs-on: "ubuntu-latest" + steps: + - name: "Ready" + id: "ready" + env: + GH_TOKEN: "${{ secrets.RELEASE_TRAIN_PARTICIPANT_GITHUB_TOKEN }}" + run: |- + run_url=$( + gh workflow run ready \ + --repo ${{ inputs.release-train-repository }} \ + --ref ${{ inputs.release-train }} \ + --field commit-hash=${{ github.sha }} \ + --field release-branch=${{ github.ref_name }} \ + --field release-repository=${{ github.repository }} + ) + echo "Dispatched workflow run. Waiting for $run_url to complete." + run_id=${run_url##*/} + watch_exit_code=0 + gh run watch $run_id --repo ${{ inputs.release-train-repository }} --exit-status --interval=3 > /dev/null 2>&1 || watch_exit_code=$? + if [[ $watch_exit_code -eq 0 ]]; then + echo "Workflow run succeeded." + else + echo "Workflow run failed." + fi + exit $watch_exit_code diff --git a/.github/workflows/release-train-retry.yml b/.github/workflows/release-train-retry.yml new file mode 100644 index 00000000000..539ccfd2504 --- /dev/null +++ b/.github/workflows/release-train-retry.yml @@ -0,0 +1,34 @@ +# This file was auto-generated by github-actions-workflow-generator 0.0.6. Do not edit. +# To update it, modify .github/workflow-generator.yml as needed and re-run the generator. + +name: "Release Train – Retry" +run-name: "${{ inputs.release-train }} – Retry" +"on": + workflow_dispatch: + inputs: + release-train: + description: "Release train" + required: true + type: "string" + release-train-repository: + default: "spring-io/release-train" + description: "Release train repository" + required: true + type: "string" +permissions: + contents: "none" +jobs: + trigger-retry: + name: "Trigger Retry" + runs-on: "ubuntu-latest" + steps: + - name: "Trigger Retry" + id: "trigger-retry" + env: + GH_TOKEN: "${{ secrets.RELEASE_TRAIN_PARTICIPANT_GITHUB_TOKEN }}" + run: |- + gh workflow run retry \ + --repo ${{ inputs.release-train-repository }} \ + --ref ${{ inputs.release-train }} \ + --field release-branch=${{ github.ref_name }} \ + --field release-repository=${{ github.repository }} diff --git a/.github/workflows/release-train-test.yml b/.github/workflows/release-train-test.yml new file mode 100644 index 00000000000..b10767ae6e2 --- /dev/null +++ b/.github/workflows/release-train-test.yml @@ -0,0 +1,91 @@ +# This file was auto-generated by github-actions-workflow-generator 0.0.6. Do not edit. +# To update it, modify .github/workflow-generator.yml as needed and re-run the generator. + +name: "Release Train – Test" +run-name: "${{ inputs.callback-ref }} – Test" +"on": + workflow_dispatch: + inputs: + callback: + description: "Repository to which a callback should be made upon completion" + required: true + type: "string" + callback-ref: + description: "Ref in the callback repository to which a callback should be made upon completion" + required: true + type: "string" + release-train-maven-repository-url: + description: "URL of a Maven repository to be used to resolve artifacts of projects earlier in the train" + required: true + type: "string" +permissions: + contents: "read" +concurrency: + group: "${{ github.workflow }}-${{ github.ref }}" +jobs: + test-release: + name: "Test Release" + runs-on: "ubuntu22-4-16" + steps: + - name: "Prevent Re-runs" + id: "prevent-re-runs" + run: |- + if [ "$GITHUB_RUN_ATTEMPT" -gt 1 ]; then + echo "Re-runs are prohibited. Use the 'Release Train – Retry' workflow to retry test failures" + exit 1 + fi + - name: "Free Disk Space" + id: "free-disk-space" + if: "${{ runner.os == 'Linux' }}" + uses: "jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be" # v1.3.1 + with: + docker-images: "false" + tool-cache: "true" + - name: "Set up Java" + id: "set-up-java" + uses: "actions/setup-java@03ad4de0992f5dab5e18fcb136590ce7c4a0ac95" # v5.6.0 + with: + distribution: "liberica" + java-version: "25" + - name: "Check Out Code" + id: "check-out-code" + uses: "actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0" # v7.0.0 + - name: "Restore Build System Caches" + id: "restore-build-system-caches" + uses: "actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9" # v6.1.0 + with: + key: "release-train-${{ inputs.callback-ref }}-${{ github.ref_name }}" + path: |- + ~/.gradle/caches + ~/.gradle/wrapper + - name: "Test Release" + id: "test-release" + uses: "./.github/actions/release-train-test" + env: + COMMERCIAL_RELEASE_REPO_URL: "${{ vars.COMMERCIAL_RELEASE_REPO_URL }}" + COMMERCIAL_REPO_PASSWORD: "${{ secrets.COMMERCIAL_ARTIFACTORY_PASSWORD }}" + COMMERCIAL_REPO_USERNAME: "${{ secrets.COMMERCIAL_ARTIFACTORY_USERNAME }}" + RELEASE_TRAIN_MAVEN_REPOSITORY_PASSWORD: "${{ secrets.RELEASE_TRAIN_PARTICIPANT_MAVEN_REPOSITORY_PASSWORD }}" + RELEASE_TRAIN_MAVEN_REPOSITORY_URL: "${{ inputs.release-train-maven-repository-url }}" + RELEASE_TRAIN_MAVEN_REPOSITORY_USERNAME: "${{ secrets.RELEASE_TRAIN_PARTICIPANT_MAVEN_REPOSITORY_USERNAME }}" + - name: "Send Callback" + id: "send-callback" + if: "${{ !cancelled() }}" + env: + GH_TOKEN: "${{ secrets.RELEASE_TRAIN_PARTICIPANT_GITHUB_TOKEN }}" + run: |- + gh workflow run callback \ + --repo ${{ inputs.callback }} \ + --ref ${{ inputs.callback-ref }} \ + --field commit-hash=${{ steps.check-out-code.outputs.commit }} \ + --field release-branch=${{ github.ref_name }} \ + --field release-repository=${{ github.repository }} \ + --field result=${{ job.status == 'success' && 'tested' || 'test-failed' }} \ + --field workflow-run-url=${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + - name: "Upload Build System Reports" + id: "upload-build-system-reports" + if: "${{ failure() }}" + uses: "actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a" # v7.0.1 + with: + name: "build-system-reports" + path: "**/build/reports" diff --git a/.github/workflows/verify.yml b/.github/workflows/verify.yml deleted file mode 100644 index a3b956570d3..00000000000 --- a/.github/workflows/verify.yml +++ /dev/null @@ -1,94 +0,0 @@ -name: Verify -on: - workflow_call: - inputs: - staging: - description: 'Whether the release to verify is in the staging repository' - required: false - default: false - type: boolean - version: - description: 'Version to verify' - required: true - type: string - secrets: - commercial-repository-password: - description: 'Password for authentication with the commercial repository' - required: false - commercial-repository-username: - description: 'Username for authentication with the commercial repository' - required: false - google-chat-webhook-url: - description: 'Google Chat Webhook URL' - required: true - opensource-repository-password: - description: 'Password for authentication with the open-source repository' - required: false - opensource-repository-username: - description: 'Username for authentication with the open-source repository' - required: false - token: - description: 'Token to use for authentication with GitHub' - required: true -permissions: - contents: read -jobs: - verify: - name: Verify - runs-on: ${{ vars.UBUNTU_SMALL || 'ubuntu-latest' }} - steps: - - name: Check Out Release Verification Tests - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - with: - ref: 'v0.0.15' - repository: spring-projects/spring-boot-release-verification - token: ${{ secrets.token }} - - name: Check Out Send Notification Action - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - with: - path: send-notification - sparse-checkout: .github/actions/send-notification - - name: Set Up Java - uses: actions/setup-java@v5 - with: - distribution: 'liberica' - java-version: 17 - - name: Set Up Homebrew - if: ${{ !vars.COMMERCIAL }} - uses: Homebrew/actions/setup-homebrew@c8707045ccae42888fe98e86f2ee8938bc7cc193 - with: - stable: true - - name: Set Up Gradle - uses: gradle/actions/setup-gradle@9c971963bec38e04b3d30dcc455b5382be2fdbfb # v6.3.0 - with: - cache-provider: basic - cache-read-only: false - - name: Configure Gradle Properties - shell: bash - run: | - mkdir -p $HOME/.gradle - echo 'org.gradle.daemon=false' >> $HOME/.gradle/gradle.properties - - name: Run Release Verification Tests - env: - RVT_COMMERCIAL_REPOSITORY_PASSWORD: ${{ secrets.commercial-repository-password }} - RVT_COMMERCIAL_REPOSITORY_USERNAME: ${{ secrets.commercial-repository-username }} - RVT_OSS_REPOSITORY_PASSWORD: ${{ secrets.opensource-repository-password }} - RVT_OSS_REPOSITORY_USERNAME: ${{ secrets.opensource-repository-username }} - RVT_RELEASE_TYPE: ${{ vars.COMMERCIAL && 'commercial' || 'oss' }} - RVT_STAGING: ${{ inputs.staging }} - RVT_VERSION: ${{ inputs.version }} - HOMEBREW_NO_SANDBOX_LINUX: "1" - run: ./gradlew spring-boot-release-verification-tests:test - - name: Upload Build Reports on Failure - if: failure() - uses: actions/upload-artifact@v7 - with: - name: build-reports - path: '**/build/reports/' - - name: Send Notification - if: always() - uses: ./send-notification/.github/actions/send-notification - with: - run-name: ${{ format('{0} | Verification | {1}', github.ref_name, inputs.version) }} - status: ${{ job.status }} - webhook-url: ${{ secrets.google-chat-webhook-url }} diff --git a/gradle.properties b/gradle.properties index f528359c0ee..79dc6e4f0a0 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,6 +1,6 @@ version=4.0.8-INTERNAL-SNAPSHOT latestVersion=false -spring.build-type=commercial +spring.build-type=oss org.gradle.caching=true org.gradle.parallel=true From 90d20347b8a9e3a9f3ace57a7d5d584e0afc817c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Nicoll?= Date: Tue, 4 Aug 2026 10:43:13 +0200 Subject: [PATCH 04/20] Upgrade to Micrometer 1.16.7 Closes gh-51235 --- platform/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/spring-boot-dependencies/build.gradle b/platform/spring-boot-dependencies/build.gradle index b7abe9d97a5..5246ea1b8ed 100644 --- a/platform/spring-boot-dependencies/build.gradle +++ b/platform/spring-boot-dependencies/build.gradle @@ -1540,7 +1540,7 @@ bom { releaseNotes("https://github.com/apache/maven-war-plugin/releases/tag/maven-war-plugin-{version}") } } - library("Micrometer", "1.16.7-INTERNAL-SNAPSHOT") { + library("Micrometer", "1.16.7") { firstParty() group("io.micrometer") { modules = [ From 96954d335e5a4041ec77def9446d8454b4d40d8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Nicoll?= Date: Tue, 4 Aug 2026 10:43:45 +0200 Subject: [PATCH 05/20] Upgrade to Micrometer Tracing 1.6.7 Closes gh-51236 --- platform/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/spring-boot-dependencies/build.gradle b/platform/spring-boot-dependencies/build.gradle index 5246ea1b8ed..106f9fa826b 100644 --- a/platform/spring-boot-dependencies/build.gradle +++ b/platform/spring-boot-dependencies/build.gradle @@ -1563,7 +1563,7 @@ bom { releaseNotes("https://github.com/micrometer-metrics/micrometer/releases/tag/v{version}") } } - library("Micrometer Tracing", "1.6.7-INTERNAL-SNAPSHOT") { + library("Micrometer Tracing", "1.6.7") { firstParty() alignWith { dependencyManagementDeclaredIn("io.micrometer:micrometer-tracing-bom") { From 6648344fcc7117cf1b7363b7b05bd1c793e4ef15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Nicoll?= Date: Tue, 4 Aug 2026 10:44:11 +0200 Subject: [PATCH 06/20] Upgrade to Reactor Bom 2025.0.7 Closes gh-51237 --- platform/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/spring-boot-dependencies/build.gradle b/platform/spring-boot-dependencies/build.gradle index 106f9fa826b..f63515ffb23 100644 --- a/platform/spring-boot-dependencies/build.gradle +++ b/platform/spring-boot-dependencies/build.gradle @@ -1973,7 +1973,7 @@ bom { ] } } - library("Reactor Bom", "2025.0.7-INTERNAL-SNAPSHOT") { + library("Reactor Bom", "2025.0.7") { firstParty() calendarName = "Reactor" group("io.projectreactor") { From 555460a0b81842a92977f17c17221c8f4d4f4cd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Nicoll?= Date: Tue, 4 Aug 2026 10:44:40 +0200 Subject: [PATCH 07/20] Upgrade to Spring AMQP 4.0.5 Closes gh-51238 --- platform/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/spring-boot-dependencies/build.gradle b/platform/spring-boot-dependencies/build.gradle index f63515ffb23..53533cc76db 100644 --- a/platform/spring-boot-dependencies/build.gradle +++ b/platform/spring-boot-dependencies/build.gradle @@ -2392,7 +2392,7 @@ bom { ] } } - library("Spring AMQP", "4.0.5-INTERNAL-SNAPSHOT") { + library("Spring AMQP", "4.0.5") { firstParty() group("org.springframework.amqp") { bom("spring-amqp-bom") From 7781b19f5fc39d385a46d6dec93dec87f08eb91e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Nicoll?= Date: Tue, 4 Aug 2026 10:45:06 +0200 Subject: [PATCH 08/20] Upgrade to Spring Batch 6.0.5 Closes gh-51239 --- platform/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/spring-boot-dependencies/build.gradle b/platform/spring-boot-dependencies/build.gradle index 53533cc76db..2af52cdbfe9 100644 --- a/platform/spring-boot-dependencies/build.gradle +++ b/platform/spring-boot-dependencies/build.gradle @@ -2407,7 +2407,7 @@ bom { releaseNotes("https://github.com/spring-projects/spring-amqp/releases/tag/v{version}") } } - library("Spring Batch", "6.0.5-INTERNAL-SNAPSHOT") { + library("Spring Batch", "6.0.5") { firstParty() group("org.springframework.batch") { bom("spring-batch-bom") From 117621b0a353900139cb965b9b44bb9c13add8f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Nicoll?= Date: Tue, 4 Aug 2026 10:45:33 +0200 Subject: [PATCH 09/20] Upgrade to Spring Framework 7.0.9 Closes gh-51240 --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 79dc6e4f0a0..0d5ad67fdab 100644 --- a/gradle.properties +++ b/gradle.properties @@ -21,7 +21,7 @@ mockitoVersion=5.20.0 nativeBuildToolsVersion=0.11.5 nullabilityPluginVersion=0.0.14 snakeYamlVersion=2.5 -springFrameworkVersion=7.0.9-INTERNAL-SNAPSHOT +springFrameworkVersion=7.0.9 springFramework60xVersion=6.0.23 tomcatVersion=11.0.24 From b90a00f71774857b070ad5d4ccc3d1476a80ebb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Nicoll?= Date: Tue, 4 Aug 2026 10:46:03 +0200 Subject: [PATCH 10/20] Upgrade to Spring GraphQL 2.0.5 Closes gh-51241 --- platform/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/spring-boot-dependencies/build.gradle b/platform/spring-boot-dependencies/build.gradle index 2af52cdbfe9..04b56cc0c8c 100644 --- a/platform/spring-boot-dependencies/build.gradle +++ b/platform/spring-boot-dependencies/build.gradle @@ -2452,7 +2452,7 @@ bom { releaseNotes("https://github.com/spring-projects/spring-framework/releases/tag/v{version}") } } - library("Spring GraphQL", "2.0.5-INTERNAL-SNAPSHOT") { + library("Spring GraphQL", "2.0.5") { firstParty() group("org.springframework.graphql") { modules = [ From b70535bc18a13f34d4238c9d6b05ccc9aadbc9c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Nicoll?= Date: Tue, 4 Aug 2026 10:46:42 +0200 Subject: [PATCH 11/20] Upgrade to Spring Integration 7.0.6 Closes gh-51242 --- platform/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/spring-boot-dependencies/build.gradle b/platform/spring-boot-dependencies/build.gradle index 04b56cc0c8c..850771cfbfa 100644 --- a/platform/spring-boot-dependencies/build.gradle +++ b/platform/spring-boot-dependencies/build.gradle @@ -2487,7 +2487,7 @@ bom { releaseNotes("https://github.com/spring-projects/spring-hateoas/releases/tag/{version}") } } - library("Spring Integration", "7.0.6-INTERNAL-SNAPSHOT") { + library("Spring Integration", "7.0.6") { firstParty() group("org.springframework.integration") { bom("spring-integration-bom") From 19139ac9b3b32713a2a553a34b5fbc080bcc981b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Nicoll?= Date: Tue, 4 Aug 2026 10:47:05 +0200 Subject: [PATCH 12/20] Upgrade to Spring Kafka 4.0.7 Closes gh-51243 --- platform/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/spring-boot-dependencies/build.gradle b/platform/spring-boot-dependencies/build.gradle index 850771cfbfa..fdf9eb286a6 100644 --- a/platform/spring-boot-dependencies/build.gradle +++ b/platform/spring-boot-dependencies/build.gradle @@ -2502,7 +2502,7 @@ bom { releaseNotes("https://github.com/spring-projects/spring-integration/releases/tag/v{version}") } } - library("Spring Kafka", "4.0.7-INTERNAL-SNAPSHOT") { + library("Spring Kafka", "4.0.7") { firstParty() group("org.springframework.kafka") { modules = [ From 3f1c4ac2d1cc02ea19cb97a762c811b4fda07786 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Nicoll?= Date: Tue, 4 Aug 2026 10:47:27 +0200 Subject: [PATCH 13/20] Upgrade to Spring LDAP 4.0.5 Closes gh-51244 --- platform/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/spring-boot-dependencies/build.gradle b/platform/spring-boot-dependencies/build.gradle index fdf9eb286a6..8985038c849 100644 --- a/platform/spring-boot-dependencies/build.gradle +++ b/platform/spring-boot-dependencies/build.gradle @@ -2520,7 +2520,7 @@ bom { releaseNotes("https://github.com/spring-projects/spring-kafka/releases/tag/v{version}") } } - library("Spring LDAP", "4.0.5-INTERNAL-SNAPSHOT") { + library("Spring LDAP", "4.0.5") { firstParty() group("org.springframework.ldap") { modules = [ From bb99ddab0c3091bc78ed6640f5e75b98025573d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Nicoll?= Date: Tue, 4 Aug 2026 10:48:02 +0200 Subject: [PATCH 14/20] Upgrade to Spring Security 7.0.7 Closes gh-51245 --- platform/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/spring-boot-dependencies/build.gradle b/platform/spring-boot-dependencies/build.gradle index 8985038c849..10f93a8b201 100644 --- a/platform/spring-boot-dependencies/build.gradle +++ b/platform/spring-boot-dependencies/build.gradle @@ -2570,7 +2570,7 @@ bom { releaseNotes("https://github.com/spring-projects/spring-restdocs/releases/tag/v{version}") } } - library("Spring Security", "7.0.7-INTERNAL-SNAPSHOT") { + library("Spring Security", "7.0.7") { firstParty() group("org.springframework.security") { bom("spring-security-bom") From 3a096d58d42232136557f7c60d9c57fea09e2267 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Nicoll?= Date: Tue, 4 Aug 2026 10:48:28 +0200 Subject: [PATCH 15/20] Upgrade to Spring Session 4.0.5 Closes gh-51246 --- platform/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/spring-boot-dependencies/build.gradle b/platform/spring-boot-dependencies/build.gradle index 10f93a8b201..97adacb6317 100644 --- a/platform/spring-boot-dependencies/build.gradle +++ b/platform/spring-boot-dependencies/build.gradle @@ -2585,7 +2585,7 @@ bom { releaseNotes("https://github.com/spring-projects/spring-security/releases/tag/{version}") } } - library("Spring Session", "4.0.5-INTERNAL-SNAPSHOT") { + library("Spring Session", "4.0.5") { firstParty() prohibit { startsWith(["Apple-", "Bean-", "Corn-", "Dragonfruit-"]) From aab9b6b3c74eb6c322239863fab360c0a98069c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Nicoll?= Date: Tue, 11 Aug 2026 14:07:43 +0200 Subject: [PATCH 16/20] Upgrade to Spring Data Bom 2025.1.7 Close gh-51355 --- platform/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/spring-boot-dependencies/build.gradle b/platform/spring-boot-dependencies/build.gradle index 97adacb6317..f58cd9dce7a 100644 --- a/platform/spring-boot-dependencies/build.gradle +++ b/platform/spring-boot-dependencies/build.gradle @@ -2422,7 +2422,7 @@ bom { releaseNotes("https://github.com/spring-projects/spring-batch/releases/tag/v{version}") } } - library("Spring Data Bom", "2025.1.7-INTERNAL-SNAPSHOT") { + library("Spring Data Bom", "2025.1.7") { firstParty() calendarName = "Spring Data Release" group("org.springframework.data") { From 365e687312f92669fa7165844508a04bd5f14a27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Nicoll?= Date: Tue, 11 Aug 2026 14:08:04 +0200 Subject: [PATCH 17/20] Upgrade to Spring HATEOAS 3.0.5 Closes gh-51356 --- platform/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/spring-boot-dependencies/build.gradle b/platform/spring-boot-dependencies/build.gradle index f58cd9dce7a..d9e7e007d24 100644 --- a/platform/spring-boot-dependencies/build.gradle +++ b/platform/spring-boot-dependencies/build.gradle @@ -2470,7 +2470,7 @@ bom { releaseNotes("https://github.com/spring-projects/spring-graphql/releases/tag/v{version}") } } - library("Spring HATEOAS", "3.0.5-INTERNAL-SNAPSHOT") { + library("Spring HATEOAS", "3.0.5") { firstParty() group("org.springframework.hateoas") { modules = [ From 2c92717f55321e3e9ef48f56b8c01bce07358a47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Nicoll?= Date: Tue, 11 Aug 2026 14:08:29 +0200 Subject: [PATCH 18/20] Upgrade to Spring Pulsar 2.0.7 Closes gh-51327 --- platform/spring-boot-dependencies/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/spring-boot-dependencies/build.gradle b/platform/spring-boot-dependencies/build.gradle index d9e7e007d24..587f4467d05 100644 --- a/platform/spring-boot-dependencies/build.gradle +++ b/platform/spring-boot-dependencies/build.gradle @@ -2540,7 +2540,7 @@ bom { releaseNotes("https://github.com/spring-projects/spring-ldap/releases/tag/{version}") } } - library("Spring Pulsar", "2.0.7-INTERNAL-SNAPSHOT") { + library("Spring Pulsar", "2.0.7") { firstParty() group("org.springframework.pulsar") { bom("spring-pulsar-bom") From 2e501907392cd8755ae9587dd2bd7b50171566ac Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Thu, 20 Aug 2026 15:10:30 -0700 Subject: [PATCH 19/20] Next development version (v4.0.9-SNAPSHOT) --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 0d5ad67fdab..e75ee94c8d7 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ -version=4.0.8-INTERNAL-SNAPSHOT +version=4.0.9-SNAPSHOT latestVersion=false spring.build-type=oss From e3b1cff986e9606de7c82023b8f8c1195db14bf6 Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Thu, 20 Aug 2026 15:07:01 -0700 Subject: [PATCH 20/20] Restore GitHub workflows --- .../workflows/build-and-deploy-snapshot.yml | 76 ++++++++ .github/workflows/build-pull-request.yml | 24 +++ .github/workflows/ci.yml | 67 +++++++ .github/workflows/distribute.yml | 45 +++++ .github/workflows/release-milestone.yml | 131 +++++++++++++ .github/workflows/release.yml | 178 ++++++++++++++++++ .github/workflows/run-codeql-analysis.yml | 13 ++ .github/workflows/run-system-tests.yml | 53 ++++++ .github/workflows/trigger-docs-build.yml | 35 ++++ 9 files changed, 622 insertions(+) create mode 100644 .github/workflows/build-and-deploy-snapshot.yml create mode 100644 .github/workflows/build-pull-request.yml create mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/distribute.yml create mode 100644 .github/workflows/release-milestone.yml create mode 100644 .github/workflows/release.yml create mode 100644 .github/workflows/run-codeql-analysis.yml create mode 100644 .github/workflows/run-system-tests.yml create mode 100644 .github/workflows/trigger-docs-build.yml diff --git a/.github/workflows/build-and-deploy-snapshot.yml b/.github/workflows/build-and-deploy-snapshot.yml new file mode 100644 index 00000000000..a59731f4ec9 --- /dev/null +++ b/.github/workflows/build-and-deploy-snapshot.yml @@ -0,0 +1,76 @@ +name: Build and Deploy Snapshot +on: + workflow_dispatch: + push: + branches: + - '4.0.x' +permissions: + contents: read +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} +jobs: + build-and-deploy-snapshot: + name: Build and Deploy Snapshot + if: ${{ github.repository == 'spring-projects/spring-boot' || github.repository == 'spring-projects/spring-boot-commercial' }} + runs-on: ${{ vars.UBUNTU_MEDIUM || 'ubuntu-latest' }} + steps: + - name: Check Out Code + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - name: Build and Publish + id: build-and-publish + uses: ./.github/actions/build + with: + commercial-release-repository-url: ${{ vars.COMMERCIAL_RELEASE_REPO_URL }} + commercial-repository-password: ${{ secrets.COMMERCIAL_ARTIFACTORY_PASSWORD }} + commercial-repository-username: ${{ secrets.COMMERCIAL_ARTIFACTORY_USERNAME }} + commercial-snapshot-repository-url: ${{ vars.COMMERCIAL_SNAPSHOT_REPO_URL }} + develocity-access-key: ${{ secrets.DEVELOCITY_ACCESS_KEY }} + gradle-cache-read-only: false + publish: true + - name: Deploy + uses: spring-io/artifactory-deploy-action@926d7f7cc810569395346bf3a4d91b380b3e355b # v0.0.4 + with: + build-name: ${{ vars.COMMERCIAL && format('spring-boot-commercial-{0}', '4.0.x') || format('spring-boot-{0}', '4.0.x') }} + folder: 'deployment-repository' + password: ${{ vars.COMMERCIAL && secrets.COMMERCIAL_ARTIFACTORY_PASSWORD || secrets.ARTIFACTORY_PASSWORD }} + project: ${{ vars.COMMERCIAL && 'spring' }} + repository: ${{ vars.COMMERCIAL && 'spring-enterprise-maven-dev-local' || 'libs-snapshot-local' }} + signing-key: ${{ secrets.GPG_PRIVATE_KEY }} + signing-passphrase: ${{ secrets.GPG_PASSPHRASE }} + threads: 8 + uri: ${{ vars.COMMERCIAL_DEPLOY_REPO_URL || 'https://repo.spring.io' }} + username: ${{ vars.COMMERCIAL && secrets.COMMERCIAL_ARTIFACTORY_USERNAME || secrets.ARTIFACTORY_USERNAME }} + - name: Send Notification + if: always() + uses: ./.github/actions/send-notification + with: + build-scan-url: ${{ steps.build-and-publish.outputs.build-scan-url }} + run-name: ${{ format('{0} | Linux | Java 25', github.ref_name) }} + status: ${{ job.status }} + webhook-url: ${{ secrets.GOOGLE_CHAT_WEBHOOK_URL }} + outputs: + version: ${{ steps.build-and-publish.outputs.version }} + trigger-docs-build: + name: Trigger Docs Build + needs: build-and-deploy-snapshot + permissions: + actions: write + runs-on: ${{ vars.UBUNTU_SMALL || 'ubuntu-latest' }} + steps: + - name: Run Deploy Docs Workflow + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: gh workflow run deploy-docs.yml --repo ${{ github.repository }} -r docs-build -f build-sha=${{ github.sha }} -f build-refname=${{ github.ref_name }} -f build-version=${{ needs.build-and-deploy-snapshot.outputs.version }} + verify: + name: Verify + needs: build-and-deploy-snapshot + uses: ./.github/workflows/verify.yml + secrets: + commercial-repository-password: ${{ secrets.COMMERCIAL_ARTIFACTORY_PASSWORD }} + commercial-repository-username: ${{ secrets.COMMERCIAL_ARTIFACTORY_USERNAME }} + google-chat-webhook-url: ${{ secrets.GOOGLE_CHAT_WEBHOOK_URL }} + opensource-repository-password: ${{ secrets.ARTIFACTORY_PASSWORD }} + opensource-repository-username: ${{ secrets.ARTIFACTORY_USERNAME }} + token: ${{ secrets.GH_ACTIONS_REPO_TOKEN }} + with: + version: ${{ needs.build-and-deploy-snapshot.outputs.version }} diff --git a/.github/workflows/build-pull-request.yml b/.github/workflows/build-pull-request.yml new file mode 100644 index 00000000000..95129fa18d7 --- /dev/null +++ b/.github/workflows/build-pull-request.yml @@ -0,0 +1,24 @@ +name: Build Pull Request +on: pull_request +permissions: + contents: read +jobs: + build: + name: Build Pull Request + if: ${{ github.repository == 'spring-projects/spring-boot' }} + runs-on: ${{ vars.UBUNTU_MEDIUM || 'ubuntu-latest' }} + steps: + - name: Check Out Code + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - name: Build + id: build + uses: ./.github/actions/build + - name: Print JVM Thread Dumps When Cancelled + if: cancelled() + uses: ./.github/actions/print-jvm-thread-dumps + - name: Upload Build Reports + if: failure() + uses: actions/upload-artifact@v7 + with: + name: build-reports + path: '**/build/reports/' diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000000..0905e0790f7 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,67 @@ +name: CI +on: + push: + branches: + - '4.0.x' +permissions: + contents: read +jobs: + ci: + name: '${{ matrix.os.name}} | Java ${{ matrix.java.version}}' + if: ${{ github.repository == 'spring-projects/spring-boot' || github.repository == 'spring-projects/spring-boot-commercial' }} + runs-on: ${{ matrix.os.id }} + strategy: + fail-fast: false + matrix: + os: + - id: ${{ vars.UBUNTU_MEDIUM || 'ubuntu-latest' }} + name: Linux + - id: windows-latest + name: Windows + java: + - version: 17 + toolchain: true + - version: 21 + toolchain: true + - version: 25 + toolchain: false + - version: 26 + toolchain: true + exclude: + - os: + name: Linux + java: + version: 25 + - os: + name: ${{ github.repository == 'spring-projects/spring-boot-commercial' && 'Windows' }} + steps: + - name: Prepare Windows runner + if: ${{ runner.os == 'Windows' }} + run: | + git config --global core.autocrlf true + git config --global core.longPaths true + Stop-Service -name Docker + - name: Check Out Code + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - name: Build + id: build + uses: ./.github/actions/build + with: + commercial-release-repository-url: ${{ vars.COMMERCIAL_RELEASE_REPO_URL }} + commercial-repository-password: ${{ secrets.COMMERCIAL_ARTIFACTORY_PASSWORD }} + commercial-repository-username: ${{ secrets.COMMERCIAL_ARTIFACTORY_USERNAME }} + commercial-snapshot-repository-url: ${{ vars.COMMERCIAL_SNAPSHOT_REPO_URL }} + develocity-access-key: ${{ secrets.DEVELOCITY_ACCESS_KEY }} + gradle-cache-read-only: false + java-early-access: ${{ matrix.java.early-access || 'false' }} + java-distribution: ${{ matrix.java.distribution }} + java-toolchain: ${{ matrix.java.toolchain }} + java-version: ${{ matrix.java.version }} + - name: Send Notification + if: always() + uses: ./.github/actions/send-notification + with: + build-scan-url: ${{ steps.build.outputs.build-scan-url }} + run-name: ${{ format('{0} | {1} | Java {2}', github.ref_name, matrix.os.name, matrix.java.version) }} + status: ${{ job.status }} + webhook-url: ${{ secrets.GOOGLE_CHAT_WEBHOOK_URL }} diff --git a/.github/workflows/distribute.yml b/.github/workflows/distribute.yml new file mode 100644 index 00000000000..e8462178fe5 --- /dev/null +++ b/.github/workflows/distribute.yml @@ -0,0 +1,45 @@ +name: Distribute +on: + workflow_dispatch: + inputs: + build-number: + description: 'Number of the build to use to create the bundle' + required: true + type: string + create-bundle: + description: 'Whether to create the bundle. If unchecked, only the bundle distribution is executed' + required: true + type: boolean + default: true + version: + description: 'Version to bundle and distribute' + required: true + type: string +permissions: + contents: read +jobs: + distribute-spring-enterprise-release-bundle: + runs-on: ${{ vars.UBUNTU_SMALL || 'ubuntu-latest' }} + steps: + - name: Create Bundle + if: ${{ vars.COMMERCIAL && inputs.create-bundle }} + shell: bash + run: | + curl -s -u "${{ secrets.COMMERCIAL_ARTIFACTORY_USERNAME }}:${{ secrets.COMMERCIAL_ARTIFACTORY_PASSWORD }}" \ + -X POST -H "X-JFrog-Signing-Key-Name: packagesKey" -H "Content-Type: application/json" \ + "https://usw1.packages.broadcom.com/lifecycle/api/v2/release_bundle?project=spring" \ + -d '{"release_bundle_name": "TNZ-spring-boot-commercial", "release_bundle_version": "${{ inputs.version }}", "skip_docker_manifest_resolution": true, "source_type": "builds", "source": {"builds": [ {"build_repository": "spring-build-info", "build_name": "spring-boot-commercial-${{ inputs.version }}", "build_number": "${{ inputs.build-number }}", "include_dependencies": false}]}}' | \ + jq -e 'if has("repository_key") then . else halt_error end' + - name: Sleep + if: ${{ vars.COMMERCIAL && inputs.create-bundle }} + shell: bash + run: sleep 30 + - name: Distribute Bundle + if: ${{ vars.COMMERCIAL }} + shell: bash + run: | + curl -s -u "${{ secrets.COMMERCIAL_ARTIFACTORY_USERNAME }}:${{ secrets.COMMERCIAL_ARTIFACTORY_PASSWORD }}" \ + -X POST -H "Content-Type: application/json" \ + "https://usw1.packages.broadcom.com/lifecycle/api/v2/distribution/distribute/TNZ-spring-boot-commercial/${{ inputs.version }}?project=spring" \ + -d '{"auto_create_missing_repositories": "false", "distribution_rules": [{"site_name": "JP-SaaS"}], "modifications": {"mappings": [{"input": "spring-enterprise-maven-prod-local/(.*)", "output": "spring-enterprise/$1"}]}}' | \ + jq -e 'if has("id") then . else halt_error end' diff --git a/.github/workflows/release-milestone.yml b/.github/workflows/release-milestone.yml new file mode 100644 index 00000000000..03cfbf778e4 --- /dev/null +++ b/.github/workflows/release-milestone.yml @@ -0,0 +1,131 @@ +name: Release Milestone +on: + push: + tags: + - v4.0.0-M[0-9] + - v4.0.0-RC[0-9] +permissions: + contents: read +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} +jobs: + build-and-stage-release: + name: Build and Stage Release + if: ${{ github.repository == 'spring-projects/spring-boot' }} + runs-on: ${{ vars.UBUNTU_MEDIUM || 'ubuntu-latest' }} + steps: + - name: Check Out Code + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - name: Build and Publish + id: build-and-publish + uses: ./.github/actions/build + with: + develocity-access-key: ${{ secrets.DEVELOCITY_ACCESS_KEY }} + gradle-cache-read-only: false + publish: true + - name: Stage Release + uses: spring-io/artifactory-deploy-action@926d7f7cc810569395346bf3a4d91b380b3e355b # v0.0.4 + with: + build-name: ${{ format('spring-boot-{0}', steps.build-and-publish.outputs.version)}} + folder: 'deployment-repository' + password: ${{ secrets.ARTIFACTORY_PASSWORD }} + repository: 'libs-staging-local' + signing-key: ${{ secrets.GPG_PRIVATE_KEY }} + signing-passphrase: ${{ secrets.GPG_PASSPHRASE }} + threads: 8 + uri: 'https://repo.spring.io' + username: ${{ secrets.ARTIFACTORY_USERNAME }} + outputs: + version: ${{ steps.build-and-publish.outputs.version }} + verify: + name: Verify + needs: build-and-stage-release + uses: ./.github/workflows/verify.yml + secrets: + commercial-repository-password: ${{ secrets.COMMERCIAL_ARTIFACTORY_RO_PASSWORD }} + commercial-repository-username: ${{ secrets.COMMERCIAL_ARTIFACTORY_RO_USERNAME }} + google-chat-webhook-url: ${{ secrets.GOOGLE_CHAT_WEBHOOK_URL }} + opensource-repository-password: ${{ secrets.ARTIFACTORY_PASSWORD }} + opensource-repository-username: ${{ secrets.ARTIFACTORY_USERNAME }} + token: ${{ secrets.GH_ACTIONS_REPO_TOKEN }} + with: + staging: true + version: ${{ needs.build-and-stage-release.outputs.version }} + sync-to-maven-central: + name: Sync to Maven Central + if: ${{ !vars.COMMERCIAL }} + needs: + - build-and-stage-release + - verify + runs-on: ${{ vars.UBUNTU_SMALL || 'ubuntu-latest' }} + steps: + - name: Check Out Code + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - name: Sync to Maven Central + uses: ./.github/actions/sync-to-maven-central + with: + central-token-password: ${{ secrets.CENTRAL_TOKEN_PASSWORD }} + central-token-username: ${{ secrets.CENTRAL_TOKEN_USERNAME }} + jfrog-cli-config-token: ${{ secrets.JF_ARTIFACTORY_SPRING }} + spring-boot-version: ${{ needs.build-and-stage-release.outputs.version }} + promote-release: + name: Promote Release + needs: + - build-and-stage-release + - sync-to-maven-central + runs-on: ${{ vars.UBUNTU_SMALL || 'ubuntu-latest' }} + steps: + - name: Set up JFrog CLI + uses: jfrog/setup-jfrog-cli@deda456d982fc5e9a7a020b63eb0d2968aedd33e # v5.1.0 + env: + JF_ENV_SPRING: ${{ secrets.JF_ARTIFACTORY_SPRING }} + - name: Promote build + run: jfrog rt build-promote ${{ format('spring-boot-{0}', needs.build-and-stage-release.outputs.version)}} ${{ github.run_number }} libs-milestone-local + publish-gradle-plugin: + name: Publish Gradle Plugin + if: ${{ !vars.COMMERCIAL }} + needs: + - build-and-stage-release + - sync-to-maven-central + runs-on: ${{ vars.UBUNTU_SMALL || 'ubuntu-latest' }} + steps: + - name: Check Out Code + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - name: Publish + uses: ./.github/actions/publish-gradle-plugin + with: + gradle-plugin-publish-key: ${{ secrets.GRADLE_PLUGIN_PUBLISH_KEY }} + gradle-plugin-publish-secret: ${{ secrets.GRADLE_PLUGIN_PUBLISH_SECRET }} + jfrog-cli-config-token: ${{ secrets.JF_ARTIFACTORY_SPRING }} + plugin-version: ${{ needs.build-and-stage-release.outputs.version }} + trigger-docs-build: + name: Trigger Docs Build + needs: + - build-and-stage-release + - promote-release + permissions: + actions: write + runs-on: ubuntu-latest + steps: + - name: Run Deploy Docs Workflow + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: gh workflow run deploy-docs.yml --repo ${{ github.repository }} -r docs-build -f build-refname=${{ github.ref_name }} -f build-version=${{ needs.build-and-stage-release.outputs.version }} + create-github-release: + name: Create GitHub Release + needs: + - build-and-stage-release + - promote-release + - publish-gradle-plugin + - trigger-docs-build + runs-on: ${{ vars.UBUNTU_SMALL || 'ubuntu-latest' }} + steps: + - name: Check Out Code + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - name: Create GitHub Release + uses: ./.github/actions/create-github-release + with: + commercial: ${{ vars.COMMERCIAL }} + milestone: ${{ needs.build-and-stage-release.outputs.version }} + pre-release: true + token: ${{ secrets.GH_ACTIONS_REPO_TOKEN }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000000..d4288c5d85a --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,178 @@ +name: Release +on: + push: + tags: + - v4.0.[0-9]+ +permissions: + contents: read +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} +jobs: + build-and-stage-release: + name: Build and Stage Release + if: ${{ github.repository == 'spring-projects/spring-boot' || github.repository == 'spring-projects/spring-boot-commercial' }} + runs-on: ${{ vars.UBUNTU_MEDIUM || 'ubuntu-latest' }} + steps: + - name: Check Out Code + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - name: Build and Publish + id: build-and-publish + uses: ./.github/actions/build + with: + commercial-release-repository-url: ${{ vars.COMMERCIAL_RELEASE_REPO_URL }} + commercial-repository-password: ${{ secrets.COMMERCIAL_ARTIFACTORY_PASSWORD }} + commercial-repository-username: ${{ secrets.COMMERCIAL_ARTIFACTORY_USERNAME }} + commercial-snapshot-repository-url: ${{ vars.COMMERCIAL_SNAPSHOT_REPO_URL }} + develocity-access-key: ${{ secrets.DEVELOCITY_ACCESS_KEY }} + gradle-cache-read-only: false + publish: true + - name: Stage Release + uses: spring-io/artifactory-deploy-action@926d7f7cc810569395346bf3a4d91b380b3e355b # v0.0.4 + with: + build-name: ${{ vars.COMMERCIAL && format('spring-boot-commercial-{0}', steps.build-and-publish.outputs.version) || format('spring-boot-{0}', steps.build-and-publish.outputs.version) }} + folder: 'deployment-repository' + password: ${{ vars.COMMERCIAL && secrets.COMMERCIAL_ARTIFACTORY_PASSWORD || secrets.ARTIFACTORY_PASSWORD }} + project: ${{ vars.COMMERCIAL && 'spring' }} + repository: ${{ vars.COMMERCIAL && 'spring-enterprise-maven-stage-local' || 'libs-staging-local' }} + signing-key: ${{ secrets.GPG_PRIVATE_KEY }} + signing-passphrase: ${{ secrets.GPG_PASSPHRASE }} + threads: 8 + uri: ${{ vars.COMMERCIAL_DEPLOY_REPO_URL || 'https://repo.spring.io' }} + username: ${{ vars.COMMERCIAL && secrets.COMMERCIAL_ARTIFACTORY_USERNAME || secrets.ARTIFACTORY_USERNAME }} + - name: Send Notification + if: failure() + uses: ./.github/actions/send-notification + with: + run-name: ${{ format('{0} | Release Staging | {1}', github.ref_name, inputs.version) }} + status: ${{ job.status }} + webhook-url: ${{ secrets.GOOGLE_CHAT_WEBHOOK_URL }} + outputs: + version: ${{ steps.build-and-publish.outputs.version }} + verify: + name: Verify + needs: build-and-stage-release + uses: ./.github/workflows/verify.yml + secrets: + commercial-repository-password: ${{ secrets.COMMERCIAL_ARTIFACTORY_PASSWORD }} + commercial-repository-username: ${{ secrets.COMMERCIAL_ARTIFACTORY_USERNAME }} + google-chat-webhook-url: ${{ secrets.GOOGLE_CHAT_WEBHOOK_URL }} + opensource-repository-password: ${{ secrets.ARTIFACTORY_PASSWORD }} + opensource-repository-username: ${{ secrets.ARTIFACTORY_USERNAME }} + token: ${{ secrets.GH_ACTIONS_REPO_TOKEN }} + with: + staging: true + version: ${{ needs.build-and-stage-release.outputs.version }} + sync-to-maven-central: + name: Sync to Maven Central + if: ${{ !vars.COMMERCIAL }} + needs: + - build-and-stage-release + - verify + runs-on: ${{ vars.UBUNTU_SMALL || 'ubuntu-latest' }} + steps: + - name: Check Out Code + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - name: Sync to Maven Central + uses: ./.github/actions/sync-to-maven-central + with: + central-token-password: ${{ secrets.CENTRAL_TOKEN_PASSWORD }} + central-token-username: ${{ secrets.CENTRAL_TOKEN_USERNAME }} + jfrog-cli-config-token: ${{ secrets.JF_ARTIFACTORY_SPRING }} + spring-boot-version: ${{ needs.build-and-stage-release.outputs.version }} + promote-release: + name: Promote Release + needs: + - build-and-stage-release + - sync-to-maven-central + runs-on: ${{ vars.UBUNTU_SMALL || 'ubuntu-latest' }} + steps: + - name: Set up JFrog CLI + uses: jfrog/setup-jfrog-cli@deda456d982fc5e9a7a020b63eb0d2968aedd33e # v5.1.0 + env: + JF_ENV_SPRING: ${{ vars.COMMERCIAL && secrets.COMMERCIAL_JF_ARTIFACTORY_SPRING || secrets.JF_ARTIFACTORY_SPRING }} + - name: Promote open source build + if: ${{ !vars.COMMERCIAL }} + run: jfrog rt build-promote ${{ format('spring-boot-{0}', needs.build-and-stage-release.outputs.version)}} ${{ github.run_number }} libs-release-local + - name: Promote commercial build + if: ${{ vars.COMMERCIAL }} + run: jfrog rt build-promote ${{ format('spring-boot-commercial-{0}', needs.build-and-stage-release.outputs.version)}} ${{ github.run_number }} spring-enterprise-maven-prod-local --project spring + publish-gradle-plugin: + name: Publish Gradle Plugin + if: ${{ !vars.COMMERCIAL }} + needs: + - build-and-stage-release + - sync-to-maven-central + runs-on: ${{ vars.UBUNTU_SMALL || 'ubuntu-latest' }} + steps: + - name: Check Out Code + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - name: Publish + uses: ./.github/actions/publish-gradle-plugin + with: + gradle-plugin-publish-key: ${{ secrets.GRADLE_PLUGIN_PUBLISH_KEY }} + gradle-plugin-publish-secret: ${{ secrets.GRADLE_PLUGIN_PUBLISH_SECRET }} + jfrog-cli-config-token: ${{ secrets.JF_ARTIFACTORY_SPRING }} + plugin-version: ${{ needs.build-and-stage-release.outputs.version }} + publish-to-sdkman: + name: Publish to SDKMAN! + if: ${{ !vars.COMMERCIAL }} + needs: + - build-and-stage-release + - sync-to-maven-central + runs-on: ${{ vars.UBUNTU_SMALL || 'ubuntu-latest' }} + steps: + - name: Check Out Code + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - name: Publish to SDKMAN! + uses: ./.github/actions/publish-to-sdkman + with: + make-default: false + sdkman-consumer-key: ${{ secrets.SDKMAN_CONSUMER_KEY }} + sdkman-consumer-token: ${{ secrets.SDKMAN_CONSUMER_TOKEN }} + spring-boot-version: ${{ needs.build-and-stage-release.outputs.version }} + update-homebrew-tap: + name: Update Homebrew Tap + needs: + - build-and-stage-release + - sync-to-maven-central + runs-on: ${{ vars.UBUNTU_SMALL || 'ubuntu-latest' }} + steps: + - name: Check Out Code + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - name: Update Homebrew Tap + uses: ./.github/actions/update-homebrew-tap + with: + spring-boot-version: ${{ needs.build-and-stage-release.outputs.version }} + token: ${{ secrets.GH_ACTIONS_REPO_TOKEN }} + trigger-docs-build: + name: Trigger Docs Build + needs: + - build-and-stage-release + - promote-release + permissions: + actions: write + runs-on: ubuntu-latest + steps: + - name: Run Deploy Docs Workflow + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: gh workflow run deploy-docs.yml --repo ${{ github.repository }} -r docs-build -f build-refname=${{ github.ref_name }} -f build-version=${{ needs.build-and-stage-release.outputs.version }} + create-github-release: + name: Create GitHub Release + needs: + - build-and-stage-release + - promote-release + - publish-gradle-plugin + - publish-to-sdkman + - trigger-docs-build + - update-homebrew-tap + runs-on: ${{ vars.UBUNTU_SMALL || 'ubuntu-latest' }} + steps: + - name: Check Out Code + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - name: Create GitHub Release + uses: ./.github/actions/create-github-release + with: + commercial: ${{ vars.COMMERCIAL }} + milestone: ${{ needs.build-and-stage-release.outputs.version }} + token: ${{ secrets.GH_ACTIONS_REPO_TOKEN }} diff --git a/.github/workflows/run-codeql-analysis.yml b/.github/workflows/run-codeql-analysis.yml new file mode 100644 index 00000000000..0f823bafff2 --- /dev/null +++ b/.github/workflows/run-codeql-analysis.yml @@ -0,0 +1,13 @@ +name: "Run CodeQL Analysis" +on: + push: + pull_request: + workflow_dispatch: +permissions: read-all +jobs: + run-analysis: + permissions: + actions: read + contents: read + security-events: write + uses: spring-io/github-actions/.github/workflows/codeql-analysis.yml@7dc305df87410aa851b873d2f1fd33ccbb7d0aa8 diff --git a/.github/workflows/run-system-tests.yml b/.github/workflows/run-system-tests.yml new file mode 100644 index 00000000000..340080d3c73 --- /dev/null +++ b/.github/workflows/run-system-tests.yml @@ -0,0 +1,53 @@ +name: Run System Tests +on: + push: + branches: + - '4.0.x' +permissions: + contents: read +jobs: + run-system-tests: + name: 'Java ${{ matrix.java.version}}' + if: ${{ github.repository == 'spring-projects/spring-boot' }} + runs-on: ${{ vars.UBUNTU_MEDIUM || 'ubuntu-latest' }} + strategy: + matrix: + java: + - version: 17 + toolchain: true + - version: 21 + toolchain: true + steps: + - name: Switch Docker to Overlay2 + shell: bash + run: | + echo '{"storage-driver":"overlay2"}' | sudo tee /etc/docker/daemon.json + sudo systemctl restart docker + - name: Check Out Code + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - name: Prepare Gradle Build + uses: ./.github/actions/prepare-gradle-build + with: + develocity-access-key: ${{ secrets.DEVELOCITY_ACCESS_KEY }} + java-toolchain: ${{ matrix.java.toolchain }} + java-version: ${{ matrix.java.version }} + - name: Run System Tests + id: run-system-tests + shell: bash + run: ./gradlew systemTest + - name: Show docker info + if: always() + shell: bash + run: docker version ; docker info + - name: List docker images + if: always() + shell: bash + run: docker image ls --digests + - name: Send Notification + if: always() + uses: ./.github/actions/send-notification + with: + build-scan-url: ${{ steps.run-system-tests.outputs.build-scan-url }} + run-name: ${{ format('{0} | System Tests | Java {1}', github.ref_name, matrix.java.version) }} + status: ${{ job.status }} + webhook-url: ${{ secrets.GOOGLE_CHAT_WEBHOOK_URL }} diff --git a/.github/workflows/trigger-docs-build.yml b/.github/workflows/trigger-docs-build.yml new file mode 100644 index 00000000000..600c97f834a --- /dev/null +++ b/.github/workflows/trigger-docs-build.yml @@ -0,0 +1,35 @@ +name: Trigger Docs Build +on: + push: + branches: '4.0.x' + paths: [ 'antora/*' ] + workflow_dispatch: + inputs: + build-version: + description: 'Version being build (e.g. 1.0.3-SNAPSHOT)' + required: false + build-sha: + description: Enter the SHA to build (e.g. 82c97891569821a7f91a77ca074232e0b54ca7a5) + required: false + build-refname: + description: 'Git refname to build (e.g., 1.0.x)' + required: false + +permissions: + contents: read +jobs: + trigger-docs-build: + name: Trigger Docs Build + if: github.repository_owner == 'spring-projects' + runs-on: ${{ vars.UBUNTU_SMALL || 'ubuntu-latest' }} + permissions: + actions: write + steps: + - name: Check Out + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + ref: docs-build + - name: Trigger Workflow + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: gh workflow run deploy-docs.yml -r docs-build -f build-refname=${{ github.event.inputs.build-refname }} -f build-sha=${{ github.event.inputs.build-sha }} -f build-version=${{ github.event.inputs.build-version }}