name: CI on: push: branches-ignore: - "dependabot/**" schedule: - cron: '0 10 * * *' # Once per day at 10am UTC workflow_dispatch: # Manual trigger env: SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} GRADLE_ENTERPRISE_CACHE_USER: ${{ secrets.GRADLE_ENTERPRISE_CACHE_USER }} GRADLE_ENTERPRISE_CACHE_PASSWORD: ${{ secrets.GRADLE_ENTERPRISE_CACHE_PASSWORD }} GRADLE_ENTERPRISE_SECRET_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_SECRET_ACCESS_KEY }} COMMIT_OWNER: ${{ github.event.pusher.name }} COMMIT_SHA: ${{ github.sha }} STRUCTURE101_LICENSEID: ${{ secrets.STRUCTURE101_LICENSEID }} ARTIFACTORY_USERNAME: ${{ secrets.ARTIFACTORY_USERNAME }} ARTIFACTORY_PASSWORD: ${{ secrets.ARTIFACTORY_PASSWORD }} permissions: contents: read jobs: prerequisites: name: Pre-requisites for building runs-on: ubuntu-latest if: ${{ github.repository == 'spring-projects/spring-security' }} outputs: runjobs: ${{ steps.continue.outputs.runjobs }} project_version: ${{ steps.continue.outputs.project_version }} steps: - uses: actions/checkout@v3 - id: continue name: Determine if should continue run: | # Run jobs if in upstream repository echo "runjobs=true" >>$GITHUB_OUTPUT # Extract version from gradle.properties version=$(cat gradle.properties | grep "version=" | awk -F'=' '{print $2}') echo "project_version=$version" >>$GITHUB_OUTPUT build_jdk_17: name: Build JDK 17 needs: [prerequisites] strategy: matrix: os: [ubuntu-latest, windows-latest] runs-on: ${{ matrix.os }} if: needs.prerequisites.outputs.runjobs steps: - uses: actions/checkout@v3 - name: Set up JDK 17 uses: actions/setup-java@v3 with: java-version: '17' distribution: 'temurin' cache: 'gradle' - name: Set up Gradle uses: gradle/gradle-build-action@v2 - name: Set up gradle user name run: echo 'systemProp.user.name=spring-builds+github' >> gradle.properties - name: Build with Gradle env: GRADLE_ENTERPRISE_CACHE_USERNAME: ${{ secrets.GRADLE_ENTERPRISE_CACHE_USER }} GRADLE_ENTERPRISE_CACHE_PASSWORD: ${{ secrets.GRADLE_ENTERPRISE_CACHE_PASSWORD }} GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_SECRET_ACCESS_KEY }} run: ./gradlew clean build --continue -PartifactoryUsername="$ARTIFACTORY_USERNAME" -PartifactoryPassword="$ARTIFACTORY_PASSWORD" snapshot_tests: name: Test against snapshots needs: [prerequisites] strategy: matrix: include: - java-version: '21-ea' toolchain: '21' - java-version: '17' toolchain: '17' runs-on: ubuntu-latest if: needs.prerequisites.outputs.runjobs steps: - uses: actions/checkout@v3 - name: Set up gradle uses: spring-io/spring-gradle-build-action@v1 with: java-version: ${{ matrix.java-version }} distribution: 'temurin' - name: Snapshot Tests run: | export GRADLE_ENTERPRISE_CACHE_USERNAME="$GRADLE_ENTERPRISE_CACHE_USER" export GRADLE_ENTERPRISE_CACHE_PASSWORD="$GRADLE_ENTERPRISE_CACHE_PASSWORD" export GRADLE_ENTERPRISE_ACCESS_KEY="$GRADLE_ENTERPRISE_SECRET_ACCESS_KEY" ./gradlew test --refresh-dependencies -PartifactoryUsername="$ARTIFACTORY_USERNAME" -PartifactoryPassword="$ARTIFACTORY_PASSWORD" -PforceMavenRepositories=snapshot -PisOverrideVersionCatalog -PtestToolchain=${{ matrix.toolchain }} -PspringFrameworkVersion='6.1.+' -PreactorVersion='2023.0.+' -PspringDataVersion='2023.1.+' -PlocksDisabled --stacktrace check_samples: name: Check Samples project needs: [prerequisites] runs-on: ubuntu-latest if: needs.prerequisites.outputs.runjobs steps: - uses: actions/checkout@v3 - name: Set up gradle uses: spring-io/spring-gradle-build-action@v1 with: java-version: '17' distribution: 'temurin' - name: Check samples project env: LOCAL_REPOSITORY_PATH: ${{ github.workspace }}/build/publications/repos SAMPLES_DIR: ../spring-security-samples VERSION: ${{ needs.prerequisites.outputs.project_version }} run: | export GRADLE_ENTERPRISE_CACHE_USERNAME="$GRADLE_ENTERPRISE_CACHE_USER" export GRADLE_ENTERPRISE_CACHE_PASSWORD="$GRADLE_ENTERPRISE_CACHE_PASSWORD" export GRADLE_ENTERPRISE_ACCESS_KEY="$GRADLE_ENTERPRISE_SECRET_ACCESS_KEY" ./gradlew publishMavenJavaPublicationToLocalRepository ./gradlew cloneSamples -PcloneOutputDirectory="$SAMPLES_DIR" ./gradlew --project-dir "$SAMPLES_DIR" --init-script spring-security-ci.gradle -PlocalRepositoryPath="$LOCAL_REPOSITORY_PATH" -PspringSecurityVersion="$VERSION" :runAllTests check_tangles: name: Check for Package Tangles needs: [ prerequisites ] runs-on: ubuntu-latest if: needs.prerequisites.outputs.runjobs steps: - uses: actions/checkout@v3 - name: Set up gradle uses: spring-io/spring-gradle-build-action@v1 with: java-version: '17' distribution: 'temurin' - name: Check for package tangles run: | export GRADLE_ENTERPRISE_CACHE_USERNAME="$GRADLE_ENTERPRISE_CACHE_USER" export GRADLE_ENTERPRISE_CACHE_PASSWORD="$GRADLE_ENTERPRISE_CACHE_PASSWORD" export GRADLE_ENTERPRISE_ACCESS_KEY="$GRADLE_ENTERPRISE_SECRET_ACCESS_KEY" ./gradlew check s101 -Ps101.licenseId="$STRUCTURE101_LICENSEID" --stacktrace deploy_artifacts: name: Deploy Artifacts needs: [build_jdk_17, snapshot_tests, check_samples, check_tangles] runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Set up gradle uses: spring-io/spring-gradle-build-action@v1 with: java-version: '17' distribution: 'temurin' - name: Deploy artifacts run: | export GRADLE_ENTERPRISE_CACHE_USERNAME="$GRADLE_ENTERPRISE_CACHE_USER" export GRADLE_ENTERPRISE_CACHE_PASSWORD="$GRADLE_ENTERPRISE_CACHE_PASSWORD" export GRADLE_ENTERPRISE_ACCESS_KEY="$GRADLE_ENTERPRISE_SECRET_ACCESS_KEY" ./gradlew publishArtifacts finalizeDeployArtifacts -PossrhUsername="$OSSRH_TOKEN_USERNAME" -PossrhPassword="$OSSRH_TOKEN_PASSWORD" -PartifactoryUsername="$ARTIFACTORY_USERNAME" -PartifactoryPassword="$ARTIFACTORY_PASSWORD" --stacktrace env: ORG_GRADLE_PROJECT_signingKey: ${{ secrets.GPG_PRIVATE_KEY }} ORG_GRADLE_PROJECT_signingPassword: ${{ secrets.GPG_PASSPHRASE }} OSSRH_TOKEN_USERNAME: ${{ secrets.OSSRH_S01_TOKEN_USERNAME }} OSSRH_TOKEN_PASSWORD: ${{ secrets.OSSRH_S01_TOKEN_PASSWORD }} ARTIFACTORY_USERNAME: ${{ secrets.ARTIFACTORY_USERNAME }} ARTIFACTORY_PASSWORD: ${{ secrets.ARTIFACTORY_PASSWORD }} deploy_docs: name: Deploy Docs needs: [build_jdk_17, snapshot_tests, check_samples, check_tangles] runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Set up gradle uses: spring-io/spring-gradle-build-action@v1 with: java-version: '17' distribution: 'temurin' - name: Deploy Docs run: | export GRADLE_ENTERPRISE_CACHE_USERNAME="$GRADLE_ENTERPRISE_CACHE_USER" export GRADLE_ENTERPRISE_CACHE_PASSWORD="$GRADLE_ENTERPRISE_CACHE_PASSWORD" export GRADLE_ENTERPRISE_ACCESS_KEY="$GRADLE_ENTERPRISE_SECRET_ACCESS_KEY" ./gradlew deployDocs -PdeployDocsSshKey="$DOCS_SSH_KEY" -PdeployDocsSshUsername="$DOCS_USERNAME" -PdeployDocsHost="$DOCS_HOST" --stacktrace env: DOCS_USERNAME: ${{ secrets.DOCS_USERNAME }} DOCS_SSH_KEY: ${{ secrets.DOCS_SSH_KEY }} DOCS_HOST: ${{ secrets.DOCS_HOST }} deploy_schema: name: Deploy Schema needs: [build_jdk_17, snapshot_tests, check_samples, check_tangles] runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Set up gradle uses: spring-io/spring-gradle-build-action@v1 with: java-version: '17' distribution: 'temurin' - name: Deploy Schema run: | export GRADLE_ENTERPRISE_CACHE_USERNAME="$GRADLE_ENTERPRISE_CACHE_USER" export GRADLE_ENTERPRISE_CACHE_PASSWORD="$GRADLE_ENTERPRISE_CACHE_PASSWORD" export GRADLE_ENTERPRISE_ACCESS_KEY="$GRADLE_ENTERPRISE_SECRET_ACCESS_KEY" ./gradlew deploySchema -PdeployDocsSshKey="$DOCS_SSH_KEY" -PdeployDocsSshUsername="$DOCS_USERNAME" -PdeployDocsHost="$DOCS_HOST" --stacktrace --info env: DOCS_USERNAME: ${{ secrets.DOCS_USERNAME }} DOCS_SSH_KEY: ${{ secrets.DOCS_SSH_KEY }} DOCS_HOST: ${{ secrets.DOCS_HOST }} perform_release: name: Perform release needs: [prerequisites, deploy_artifacts, deploy_docs, deploy_schema] runs-on: ubuntu-latest permissions: contents: write timeout-minutes: 90 if: ${{ !endsWith(needs.prerequisites.outputs.project_version, '-SNAPSHOT') }} env: REPO: ${{ github.repository }} BRANCH: ${{ github.ref_name }} TOKEN: ${{ github.token }} VERSION: ${{ needs.prerequisites.outputs.project_version }} steps: - uses: actions/checkout@v3 with: token: ${{ secrets.GH_ACTIONS_REPO_TOKEN }} - name: Set up gradle uses: spring-io/spring-gradle-build-action@v1 with: java-version: '17' distribution: 'temurin' - name: Wait for Artifactory Artifacts if: ${{ contains(needs.prerequisites.outputs.project_version, '-RC') || contains(needs.prerequisites.outputs.project_version, '-M') }} run: | echo "Wait for artifacts of $REPO@$VERSION to appear on Artifactory." until curl -f -s https://repo.spring.io/artifactory/milestone/org/springframework/security/spring-security-core/$VERSION/ > /dev/null do sleep 30 echo "." done echo "Artifacts for $REPO@$VERSION have been released to Artifactory." - name: Wait for Maven Central Artifacts if: ${{ !contains(needs.prerequisites.outputs.project_version, '-RC') && !contains(needs.prerequisites.outputs.project_version, '-M') }} run: | echo "Wait for artifacts of $REPO@$VERSION to appear on Maven Central." until curl -f -s https://repo1.maven.org/maven2/org/springframework/security/spring-security-core/$VERSION/ > /dev/null do sleep 30 echo "." done echo "Artifacts for $REPO@$VERSION have been released to Maven Central." - name: Create GitHub Release run: | export GRADLE_ENTERPRISE_CACHE_USERNAME="$GRADLE_ENTERPRISE_CACHE_USER" export GRADLE_ENTERPRISE_CACHE_PASSWORD="$GRADLE_ENTERPRISE_CACHE_PASSWORD" export GRADLE_ENTERPRISE_ACCESS_KEY="$GRADLE_ENTERPRISE_SECRET_ACCESS_KEY" echo "Tagging and publishing $REPO@$VERSION release on GitHub." ./gradlew createGitHubRelease -PnextVersion=$VERSION -Pbranch=$BRANCH -PcreateRelease=true -PgitHubAccessToken=$TOKEN - name: Announce Release on Slack id: spring-security-announcing uses: slackapi/slack-github-action@v1.19.0 with: payload: | { "text": "spring-security-announcing `${{ env.VERSION }}` is available now", "blocks": [ { "type": "section", "text": { "type": "mrkdwn", "text": "spring-security-announcing `${{ env.VERSION }}` is available now" } } ] } env: SLACK_WEBHOOK_URL: ${{ secrets.SPRING_RELEASE_SLACK_WEBHOOK_URL }} SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK - name: Setup git config run: | git config user.name 'github-actions[bot]' git config user.email 'github-actions[bot]@users.noreply.github.com' - name: Update to next Snapshot Version run: | export GRADLE_ENTERPRISE_CACHE_USERNAME="$GRADLE_ENTERPRISE_CACHE_USER" export GRADLE_ENTERPRISE_CACHE_PASSWORD="$GRADLE_ENTERPRISE_CACHE_PASSWORD" export GRADLE_ENTERPRISE_ACCESS_KEY="$GRADLE_ENTERPRISE_SECRET_ACCESS_KEY" echo "Updating $REPO@$VERSION to next snapshot version." ./gradlew :updateToSnapshotVersion git commit -am "Next development version" git push perform_post_release: name: Perform post-release needs: [prerequisites, deploy_artifacts, deploy_docs, deploy_schema] runs-on: ubuntu-latest permissions: contents: read issues: write timeout-minutes: 90 if: ${{ endsWith(needs.prerequisites.outputs.project_version, '-SNAPSHOT') }} env: TOKEN: ${{ github.token }} VERSION: ${{ needs.prerequisites.outputs.project_version }} steps: - uses: actions/checkout@v3 - name: Set up gradle uses: spring-io/spring-gradle-build-action@v1 with: java-version: '17' distribution: 'temurin' - name: Schedule next release (if not already scheduled) run: ./gradlew scheduleNextRelease -PnextVersion=$VERSION -PgitHubAccessToken=$TOKEN notify_result: name: Check for failures needs: [perform_release, perform_post_release] if: failure() runs-on: ubuntu-latest permissions: actions: read steps: - name: Send Slack message # Workaround while waiting for Gamesight/slack-workflow-status#38 to be fixed # See https://github.com/Gamesight/slack-workflow-status/issues/38 uses: sjohnr/slack-workflow-status@v1-beta with: repo_token: ${{ secrets.GITHUB_TOKEN }} slack_webhook_url: ${{ secrets.SLACK_WEBHOOK_URL }} channel: '#spring-security-ci' name: 'CI Notifier'