From 80809bbc14ffe415d4c0faa95ade7a048212c329 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Nicoll?= Date: Fri, 15 Mar 2024 08:52:09 +0100 Subject: [PATCH] Move CI to GitHub Actions Closes gh-32447 --- .github/actions/send-notification/action.yml | 33 +++++++ .../workflows/build-and-deploy-snapshot.yml | 64 ++++++++++++++ .github/workflows/ci.yml | 80 +++++++++++++++++ .github/workflows/deploy-docs.yml | 10 ++- ci/README.adoc | 2 + ci/parameters.yml | 1 - ci/pipeline.yml | 87 +++---------------- ci/scripts/build-pr.sh | 8 -- ci/scripts/build-project.sh | 9 -- ci/scripts/check-project.sh | 9 -- ci/tasks/build-pr.yml | 19 ---- ci/tasks/build-project.yml | 22 ----- ci/tasks/check-project.yml | 24 ----- 13 files changed, 197 insertions(+), 171 deletions(-) create mode 100644 .github/actions/send-notification/action.yml create mode 100644 .github/workflows/build-and-deploy-snapshot.yml create mode 100644 .github/workflows/ci.yml delete mode 100755 ci/scripts/build-pr.sh delete mode 100755 ci/scripts/build-project.sh delete mode 100755 ci/scripts/check-project.sh delete mode 100644 ci/tasks/build-pr.yml delete mode 100644 ci/tasks/build-project.yml delete mode 100644 ci/tasks/check-project.yml diff --git a/.github/actions/send-notification/action.yml b/.github/actions/send-notification/action.yml new file mode 100644 index 00000000000..9582d44ed15 --- /dev/null +++ b/.github/actions/send-notification/action.yml @@ -0,0 +1,33 @@ +name: Send notification +description: Sends a Google Chat message as a notification of the job's outcome +inputs: + webhook-url: + description: 'Google Chat Webhook URL' + required: true + status: + description: 'Status of the job' + required: true + build-scan-url: + description: 'URL of the build scan to include in the notification' + run-name: + description: 'Name of the run to include in the notification' + default: ${{ format('{0} {1}', github.ref_name, github.job) }} +runs: + using: composite + steps: + - 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" + - shell: bash + if: ${{ inputs.status == 'success' }} + 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 + - shell: bash + if: ${{ inputs.status == 'failure' }} + 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 + - shell: bash + if: ${{ inputs.status == 'cancelled' }} + 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/workflows/build-and-deploy-snapshot.yml b/.github/workflows/build-and-deploy-snapshot.yml new file mode 100644 index 00000000000..3b15f3196b0 --- /dev/null +++ b/.github/workflows/build-and-deploy-snapshot.yml @@ -0,0 +1,64 @@ +name: Build and deploy snapshot +on: + push: + branches: + - 6.0.x +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} +jobs: + build-and-deploy-snapshot: + if: ${{ github.repository == 'spring-projects/spring-framework' }} + name: Build and deploy snapshot + runs-on: ubuntu-latest + steps: + - name: Set up Java + uses: actions/setup-java@v4 + with: + distribution: 'liberica' + java-version: 17 + - name: Check out code + uses: actions/checkout@v4 + - name: Set up Gradle + uses: gradle/actions/setup-gradle@417ae3ccd767c252f5661f1ace9f835f9654f2b5 + with: + cache-read-only: false + - name: Configure Gradle properties + shell: bash + run: | + mkdir -p $HOME/.gradle + echo 'systemProp.user.name=spring-builds+github' >> $HOME/.gradle/gradle.properties + echo 'systemProp.org.gradle.internal.launcher.welcomeMessageEnabled=false' >> $HOME/.gradle/gradle.properties + echo 'org.gradle.daemon=false' >> $HOME/.gradle/gradle.properties + echo 'org.gradle.daemon=4' >> $HOME/.gradle/gradle.properties + - name: Build and publish + id: build + env: + CI: 'true' + GRADLE_ENTERPRISE_URL: 'https://ge.spring.io' + GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_SECRET_ACCESS_KEY }} + GRADLE_ENTERPRISE_CACHE_USERNAME: ${{ secrets.GRADLE_ENTERPRISE_CACHE_USER }} + GRADLE_ENTERPRISE_CACHE_PASSWORD: ${{ secrets.GRADLE_ENTERPRISE_CACHE_PASSWORD }} + run: ./gradlew -PdeploymentRepository=$(pwd)/deployment-repository build publishAllPublicationsToDeploymentRepository + - name: Deploy + uses: spring-io/artifactory-deploy-action@v0.0.1 + with: + uri: 'https://repo.spring.io' + username: ${{ secrets.ARTIFACTORY_USERNAME }} + password: ${{ secrets.ARTIFACTORY_PASSWORD }} + build-name: ${{ format('spring-framework-{0}', github.ref_name)}} + repository: 'libs-snapshot-local' + folder: 'deployment-repository' + signing-key: ${{ secrets.GPG_PRIVATE_KEY }} + signing-passphrase: ${{ secrets.GPG_PASSPHRASE }} + artifact-properties: | + /**/framework-api-*.zip::zip.name=spring-framework,zip.deployed=false + /**/framework-api-*-docs.zip::zip.type=docs + /**/framework-api-*-schema.zip::zip.type=schema + - name: Send notification + uses: ./.github/actions/send-notification + if: always() + with: + webhook-url: ${{ secrets.GOOGLE_CHAT_WEBHOOK_URL }} + status: ${{ job.status }} + build-scan-url: ${{ steps.build.outputs.build-scan-url }} + run-name: ${{ format('{0} | Linux | Java 17', github.ref_name) }} \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000000..fcff95d00ca --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,80 @@ +name: CI +on: + push: + branches: + - 6.0.x +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} +jobs: + ci: + if: ${{ github.repository == 'spring-projects/spring-framework' }} + strategy: + matrix: + os: + - id: ubuntu-latest + name: Linux + java: + - version: 17 + toolchain: false + - version: 21 + toolchain: true + exclude: + - os: + name: Linux + java: + version: 17 + name: '${{ matrix.os.name}} | Java ${{ matrix.java.version}}' + runs-on: ${{ matrix.os.id }} + steps: + - name: Set up Java + uses: actions/setup-java@v4 + with: + distribution: 'liberica' + java-version: | + ${{ matrix.java.version }} + ${{ matrix.java.toolchain && '17' || '' }} + - 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@v4 + - name: Set up Gradle + uses: gradle/actions/setup-gradle@417ae3ccd767c252f5661f1ace9f835f9654f2b5 + with: + cache-read-only: false + - name: Configure Gradle properties + shell: bash + run: | + mkdir -p $HOME/.gradle + echo 'systemProp.user.name=spring-builds+github' >> $HOME/.gradle/gradle.properties + echo 'systemProp.org.gradle.internal.launcher.welcomeMessageEnabled=false' >> $HOME/.gradle/gradle.properties + echo 'org.gradle.daemon=false' >> $HOME/.gradle/gradle.properties + echo 'org.gradle.daemon=4' >> $HOME/.gradle/gradle.properties + - name: Configure toolchain properties + if: ${{ matrix.java.toolchain }} + shell: bash + run: | + echo toolchainVersion=${{ matrix.java.version }} >> $HOME/.gradle/gradle.properties + echo systemProp.org.gradle.java.installations.auto-detect=false >> $HOME/.gradle/gradle.properties + echo systemProp.org.gradle.java.installations.auto-download=false >> $HOME/.gradle/gradle.properties + echo systemProp.org.gradle.java.installations.paths=${{ format('$JAVA_HOME_{0}_X64', matrix.java.version) }} >> $HOME/.gradle/gradle.properties + - name: Build + id: build + env: + CI: 'true' + GRADLE_ENTERPRISE_URL: 'https://ge.spring.io' + GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_SECRET_ACCESS_KEY }} + GRADLE_ENTERPRISE_CACHE_USERNAME: ${{ secrets.GRADLE_ENTERPRISE_CACHE_USER }} + GRADLE_ENTERPRISE_CACHE_PASSWORD: ${{ secrets.GRADLE_ENTERPRISE_CACHE_PASSWORD }} + run: ./gradlew check antora + - name: Send notification + uses: ./.github/actions/send-notification + if: always() + with: + webhook-url: ${{ secrets.GOOGLE_CHAT_WEBHOOK_URL }} + status: ${{ job.status }} + 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) }} \ No newline at end of file diff --git a/.github/workflows/deploy-docs.yml b/.github/workflows/deploy-docs.yml index f3e899c4fe0..a6309a601bb 100644 --- a/.github/workflows/deploy-docs.yml +++ b/.github/workflows/deploy-docs.yml @@ -1,12 +1,14 @@ name: Deploy Docs on: push: - branches-ignore: [ gh-pages ] - tags: '**' + branches: + - 'main' + - '*.x' + - '!gh-pages' + tags: + - 'v*' repository_dispatch: types: request-build-reference # legacy - schedule: - - cron: '0 10 * * *' # Once per day at 10am UTC workflow_dispatch: permissions: actions: write diff --git a/ci/README.adoc b/ci/README.adoc index 9ff0d5b1e86..89780a0b944 100644 --- a/ci/README.adoc +++ b/ci/README.adoc @@ -1,5 +1,7 @@ == Spring Framework Concourse pipeline +NOTE: CI is being migrated to GitHub Actions. + The Spring Framework uses https://concourse-ci.org/[Concourse] for its CI build and other automated tasks. The Spring team has a dedicated Concourse instance available at https://ci.spring.io with a build pipeline for https://ci.spring.io/teams/spring-framework/pipelines/spring-framework-6.0.x[Spring Framework 6.0.x]. diff --git a/ci/parameters.yml b/ci/parameters.yml index 46e3e9b070b..32cf44f8d5c 100644 --- a/ci/parameters.yml +++ b/ci/parameters.yml @@ -8,4 +8,3 @@ milestone: "6.0.x" build-name: "spring-framework" pipeline-name: "spring-framework" concourse-url: "https://ci.spring.io" -task-timeout: 1h00m diff --git a/ci/pipeline.yml b/ci/pipeline.yml index ac164eba450..d0186c65c74 100644 --- a/ci/pipeline.yml +++ b/ci/pipeline.yml @@ -23,14 +23,6 @@ anchors: docker-resource-source: &docker-resource-source username: ((docker-hub-username)) password: ((docker-hub-password)) - slack-fail-params: &slack-fail-params - text: > - :concourse-failed: - [$TEXT_FILE_CONTENT] - text_file: git-repo/build/build-scan-uri.txt - silent: true - icon_emoji: ":concourse:" - username: concourse-ci changelog-task-params: &changelog-task-params name: generated-changelog/tag tag: generated-changelog/tag @@ -64,12 +56,6 @@ resource_types: <<: *docker-resource-source repository: dpb587/github-status-resource tag: master -- name: slack-notification - type: registry-image - source: - <<: *docker-resource-source - repository: cfcommunity/slack-notification-resource - tag: latest resources: - name: git-repo type: git @@ -98,19 +84,6 @@ resources: username: ((artifactory-username)) password: ((artifactory-password)) build_name: ((build-name)) -- name: repo-status-build - type: github-status-resource - icon: eye-check-outline - source: - repository: ((github-repo-name)) - access_token: ((github-ci-status-token)) - branch: ((branch)) - context: build -- name: slack-alert - type: slack-notification - icon: slack - source: - url: ((slack-webhook-url)) - name: github-pre-release type: github-release icon: briefcase-download-outline @@ -145,37 +118,23 @@ jobs: - put: ci-image params: image: ci-image/image.tar -- name: build +- name: stage-milestone serial: true - public: true plan: - get: ci-image - get: git-repo - trigger: true - - put: repo-status-build - params: { state: "pending", commit: "git-repo" } - - do: - - task: build-project - image: ci-image - file: git-repo/ci/tasks/build-project.yml - privileged: true - timeout: ((task-timeout)) - params: - <<: *build-project-task-params - on_failure: - do: - - put: repo-status-build - params: { state: "failure", commit: "git-repo" } - - put: slack-alert - params: - <<: *slack-fail-params - - put: repo-status-build - params: { state: "success", commit: "git-repo" } + trigger: false + - task: stage + image: ci-image + file: git-repo/ci/tasks/stage-version.yml + params: + RELEASE_TYPE: M + <<: *gradle-enterprise-task-params - put: artifactory-repo params: &artifactory-params signing_key: ((signing-key)) signing_passphrase: ((signing-passphrase)) - repo: libs-snapshot-local + repo: libs-staging-local folder: distribution-repository build_uri: "https://ci.spring.io/teams/${BUILD_TEAM_NAME}/pipelines/${BUILD_PIPELINE_NAME}/jobs/${BUILD_JOB_NAME}/builds/${BUILD_NAME}" build_number: "${BUILD_PIPELINE_NAME}-${BUILD_JOB_NAME}-${BUILD_NAME}" @@ -200,27 +159,9 @@ jobs: - "/**/framework-docs-*-schema.zip" properties: "zip.type": "schema" - get_params: - threads: 8 -- name: stage-milestone - serial: true - plan: - - get: ci-image - - get: git-repo - trigger: false - - task: stage - image: ci-image - file: git-repo/ci/tasks/stage-version.yml - params: - RELEASE_TYPE: M - <<: *gradle-enterprise-task-params - - put: artifactory-repo - params: - <<: *artifactory-params - repo: libs-staging-local - - put: git-repo - params: - repository: stage-git-repo + - put: git-repo + params: + repository: stage-git-repo - name: promote-milestone serial: true plan: @@ -262,7 +203,6 @@ jobs: - put: artifactory-repo params: <<: *artifactory-params - repo: libs-staging-local - put: git-repo params: repository: stage-git-repo @@ -307,7 +247,6 @@ jobs: - put: artifactory-repo params: <<: *artifactory-params - repo: libs-staging-local - put: git-repo params: repository: stage-git-repo @@ -352,8 +291,6 @@ jobs: <<: *changelog-task-params groups: -- name: "builds" - jobs: ["build"] - name: "releases" jobs: ["stage-milestone", "stage-rc", "stage-release", "promote-milestone", "promote-rc", "promote-release", "create-github-release"] - name: "ci-images" diff --git a/ci/scripts/build-pr.sh b/ci/scripts/build-pr.sh deleted file mode 100755 index 94c4e8df65b..00000000000 --- a/ci/scripts/build-pr.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash -set -e - -source $(dirname $0)/common.sh - -pushd git-repo > /dev/null -./gradlew -Dorg.gradle.internal.launcher.welcomeMessageEnabled=false --no-daemon --max-workers=4 check -popd > /dev/null diff --git a/ci/scripts/build-project.sh b/ci/scripts/build-project.sh deleted file mode 100755 index 3844d1a3ddb..00000000000 --- a/ci/scripts/build-project.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash -set -e - -source $(dirname $0)/common.sh -repository=$(pwd)/distribution-repository - -pushd git-repo > /dev/null -./gradlew -Dorg.gradle.internal.launcher.welcomeMessageEnabled=false --no-daemon --max-workers=4 -PdeploymentRepository=${repository} build publishAllPublicationsToDeploymentRepository -popd > /dev/null diff --git a/ci/scripts/check-project.sh b/ci/scripts/check-project.sh deleted file mode 100755 index a55cb51a5f4..00000000000 --- a/ci/scripts/check-project.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash -set -e - -source $(dirname $0)/common.sh - -pushd git-repo > /dev/null -./gradlew -Dorg.gradle.internal.launcher.welcomeMessageEnabled=false -Porg.gradle.java.installations.fromEnv=JDK17 \ - -PmainToolchain=${MAIN_TOOLCHAIN} -PtestToolchain=${TEST_TOOLCHAIN} --no-daemon --max-workers=4 check antora -popd > /dev/null diff --git a/ci/tasks/build-pr.yml b/ci/tasks/build-pr.yml deleted file mode 100644 index dbf6e9c0cf6..00000000000 --- a/ci/tasks/build-pr.yml +++ /dev/null @@ -1,19 +0,0 @@ ---- -platform: linux -inputs: -- name: git-repo -caches: -- path: gradle -params: - BRANCH: - CI: true - GRADLE_ENTERPRISE_ACCESS_KEY: - GRADLE_ENTERPRISE_CACHE_USERNAME: - GRADLE_ENTERPRISE_CACHE_PASSWORD: - GRADLE_ENTERPRISE_URL: https://ge.spring.io -run: - path: bash - args: - - -ec - - | - ${PWD}/git-repo/ci/scripts/build-pr.sh diff --git a/ci/tasks/build-project.yml b/ci/tasks/build-project.yml deleted file mode 100644 index 759749ef433..00000000000 --- a/ci/tasks/build-project.yml +++ /dev/null @@ -1,22 +0,0 @@ ---- -platform: linux -inputs: -- name: git-repo -outputs: -- name: distribution-repository -- name: git-repo -caches: -- path: gradle -params: - BRANCH: - CI: true - GRADLE_ENTERPRISE_ACCESS_KEY: - GRADLE_ENTERPRISE_CACHE_USERNAME: - GRADLE_ENTERPRISE_CACHE_PASSWORD: - GRADLE_ENTERPRISE_URL: https://ge.spring.io -run: - path: bash - args: - - -ec - - | - ${PWD}/git-repo/ci/scripts/build-project.sh diff --git a/ci/tasks/check-project.yml b/ci/tasks/check-project.yml deleted file mode 100644 index bea1185231b..00000000000 --- a/ci/tasks/check-project.yml +++ /dev/null @@ -1,24 +0,0 @@ ---- -platform: linux -inputs: -- name: git-repo -outputs: -- name: distribution-repository -- name: git-repo -caches: -- path: gradle -params: - BRANCH: - CI: true - MAIN_TOOLCHAIN: - TEST_TOOLCHAIN: - GRADLE_ENTERPRISE_ACCESS_KEY: - GRADLE_ENTERPRISE_CACHE_USERNAME: - GRADLE_ENTERPRISE_CACHE_PASSWORD: - GRADLE_ENTERPRISE_URL: https://ge.spring.io -run: - path: bash - args: - - -ec - - | - ${PWD}/git-repo/ci/scripts/check-project.sh