diff --git a/.cursor/cirrus-github-migration.md b/.cursor/cirrus-github-migration.md index 1b19a773..2f12f810 100644 --- a/.cursor/cirrus-github-migration.md +++ b/.cursor/cirrus-github-migration.md @@ -316,6 +316,8 @@ jobs: version: 2025.7.12 - uses: SonarSource/ci-github-actions/get-build-number@v1 - uses: SonarSource/ci-github-actions/promote@v1 + with: + promote-pull-request: true ``` ## SonarSource Custom Actions @@ -1193,6 +1195,8 @@ jobs: version: 2025.7.12 - uses: SonarSource/ci-github-actions/get-build-number@v1 - uses: SonarSource/ci-github-actions/promote@v1 + with: + promote-pull-request: true ``` ### Plus: `mise.toml` (3 lines) diff --git a/README.md b/README.md index 2d2dcac9..7f3f7cec 100644 --- a/README.md +++ b/README.md @@ -231,7 +231,8 @@ jobs: ⚠️ Required Vault permissions: -- `development/kv/data/next`, `development/kv/data/sonarcloud`, or `development/kv/data/sonarqube-us`: SonarQube credentials (based on sonar-platform) +- `development/kv/data/next`, `development/kv/data/sonarcloud`, or `development/kv/data/sonarqube-us`: SonarQube credentials (based on + sonar-platform) - `development/kv/data/sign`: Artifact signing credentials - `development/kv/data/develocity`: Develocity access token - `public-reader` or `private-reader` Artifactory roles for the build @@ -240,13 +241,13 @@ jobs: ### Inputs - `public`: Whether to build and deploy with/to public repositories - automatically detected -from repository visibility (optional) + from repository visibility (optional) - `artifactory-deploy-repo`: Name of deployment repository - defaults to `sonarsource-public-qa` -or `sonarsource-private-qa` based on repository visibility (optional) + or `sonarsource-private-qa` based on repository visibility (optional) - `artifactory-reader-role`: Suffix for the Artifactory reader role in Vault - defaults to `public-reader` -or `private-reader` based on repository visibility (optional) + or `private-reader` based on repository visibility (optional) - `artifactory-deployer-role`: Suffix for the Artifactory deployer role in Vault - -defaults to `public-deployer` or `qa-deployer` based on repository visibility (optional) + defaults to `public-deployer` or `qa-deployer` based on repository visibility (optional) - `deploy-pull-request`: Whether to deploy pull request artifacts (default: `false`) - `skip-tests`: Whether to skip running tests (default: `false`) - `gradle-args`: Additional arguments to pass to Gradle (optional) @@ -345,12 +346,30 @@ jobs: - Comprehensive build logging and error handling - Support for different branch types (main, maintenance, PR, dogfood, long-lived feature) +--- + ## `promote` This action promotes a build in JFrog Artifactory and updates the GitHub status check accordingly. The GitHub status check is named `repox-${GITHUB_REF_NAME}`. +### Requirements + +#### Required Vault Permissions + +- `promoter`: Artifactory role for the promotion. +- `promotion`: custom GitHub token for promotion. + +#### Other Dependencies + +Required properties in the build info: + +- `buildInfo.env.ARTIFACTORY_DEPLOY_REPO`: Repository to deploy to (e.g. `sonarsource-deploy-qa`). It can also be set as an input. +- `buildInfo.env.PROJECT_VERSION`: Version of the project (e.g. 1.2.3). + +No pre-installed tool is required. + ### Usage ```yaml @@ -358,7 +377,7 @@ The GitHub status check is named `repox-${GITHUB_REF_NAME}`. needs: - build concurrency: - group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + group: ${{ github.workflow }}-promote-${{ github.event.pull_request.number || github.ref }} cancel-in-progress: ${{ github.ref_name != github.event.repository.default_branch }} runs-on: ubuntu-24.04-large name: Promote @@ -370,15 +389,22 @@ The GitHub status check is named `repox-${GITHUB_REF_NAME}`. - uses: SonarSource/ci-github-actions/promote@v1 ``` -⚠️ Required GitHub permissions: +### Inputs -- `id-token: write` -- `contents: write` +- `promote-pull-request`: Whether to promote pull request artifacts. Default is `false`. Requires `deploy-pull-request` input to be set to + `true` in the build action. +- `multi-repo`: If true, promotes to public and private repositories. For projects with both public and private artifacts. +- `artifactory-deploy-repo`: Repository to deploy to. If not set, it will be retrieved from the build info. +- `artifactory-target-repo`: Target repository for the promotion. If not set, it will be determined based on the branch type and the + deployment repository. -⚠️ Required Vault permissions: +### Outputs + +No outputs are provided by this action. + +### Features -- `promoter` Artifactory role for the promotion. -- `promotion` GitHub token. +--- ## `pr-cleanup` @@ -464,7 +490,8 @@ jobs: ⚠️ Required Vault permissions: -- `development/kv/data/next`, `development/kv/data/sonarcloud`, or `development/kv/data/sonarqube-us`: SonarQube credentials (based on sonar-platform) +- `development/kv/data/next`, `development/kv/data/sonarcloud`, or `development/kv/data/sonarqube-us`: SonarQube credentials (based on + sonar-platform) - `public-reader` or `private-reader` Artifactory roles for the build - `public-deployer` or `qa-deployer` Artifactory roles for the deployment @@ -472,9 +499,9 @@ jobs: - `public`: Whether to build and deploy with/to public repositories - automatically detected from repository visibility (optional) - `artifactory-reader-role`: Suffix for the Artifactory reader role in Vault - -defaults to `public-reader` or `private-reader` based on repository visibility (optional) + defaults to `public-reader` or `private-reader` based on repository visibility (optional) - `artifactory-deployer-role`: Suffix for the Artifactory deployer role in Vault - -defaults to `public-deployer` or `qa-deployer` based on repository visibility (optional) + defaults to `public-deployer` or `qa-deployer` based on repository visibility (optional) - `artifactory-deploy-repo`: Name of deployment repository (required) - `deploy-pull-request`: Whether to deploy pull request artifacts (default: `false`) - `skip-tests`: Whether to skip running tests (default: `false`) @@ -564,5 +591,6 @@ The @ syntax above will automatically link the shared documentation from this re If you are not using Cursor, you can also directly provide the link to the documentation as below ```md -Refer @https://github.com/SonarSource/ci-github-actions/blob/master/.cursor/cirrus-github-migration.md and migrate @.cirrus.yml to Github Actions. +Refer @https://github.com/SonarSource/ci-github-actions/blob/master/.cursor/cirrus-github-migration.md and migrate @.cirrus.yml to Github +Actions. ``` diff --git a/build-gradle/action.yml b/build-gradle/action.yml index 8294c3c1..4002357d 100644 --- a/build-gradle/action.yml +++ b/build-gradle/action.yml @@ -25,8 +25,7 @@ inputs: required: false deploy-pull-request: description: Whether to deploy pull request artifacts - required: false - default: 'true' + default: 'false' skip-tests: description: Whether to skip running tests required: false diff --git a/build-maven/action.yml b/build-maven/action.yml index 80c63b2d..8e9cb08a 100644 --- a/build-maven/action.yml +++ b/build-maven/action.yml @@ -15,7 +15,7 @@ inputs: `public-deployer` for public repositories. default: '' deploy-pull-request: - description: Whether to deploy pull request artifacts. Set to `false` if not using the promote action. + description: Whether to deploy pull request artifacts. default: 'false' maven-local-repository-path: description: Path to the Maven cache directory, relative to the user home directory. diff --git a/promote/action.yml b/promote/action.yml index 24d8dd44..623d453e 100644 --- a/promote/action.yml +++ b/promote/action.yml @@ -2,18 +2,26 @@ name: Promote description: GitHub Action to promote a project inputs: - public: - description: Whether to build and deploy with/to public repositories. Set to `true` for public repositories (OSS), `false` for private. - default: ${{ github.event.repository.visibility == 'public' && 'true' || 'false' }} + promote-pull-request: + description: Whether to promote pull request artifacts. Requires `deploy-pull-request` input to be set to `true` in the build action. + default: 'false' + multi-repo: + description: If true, promotes to public and private repositories. For projects with both public and private artifacts. + artifactory-deploy-repo: + description: Repository to deploy to. If not set, it will be retrieved from the build info. + artifactory-target-repo: + description: Target repository for the promotion. If not set, it will be determined based on the branch type and the deploy repository. runs: using: composite steps: - name: Set build parameters + if: ${{ inputs.promote-pull-request == 'true' }} shell: bash run: | cp ${GITHUB_ACTION_PATH}/mise.local.toml mise.local.toml - name: Vault + if: ${{ inputs.promote-pull-request == 'true' }} id: secrets uses: SonarSource/vault-action-wrapper@d6d745ffdbc82b040df839b903bc33b5592cd6b0 # 3.0.2 with: @@ -21,13 +29,20 @@ runs: development/artifactory/token/{REPO_OWNER_NAME_DASH}-promoter access_token | ARTIFACTORY_PROMOTE_ACCESS_TOKEN; development/github/token/{REPO_OWNER_NAME_DASH}-promotion token | GITHUB_TOKEN; - uses: jdx/mise-action@bfb9fa0b029db830a8c570757cee683df207a6c5 # v2.4.0 + if: ${{ inputs.promote-pull-request == 'true' }} with: version: 2025.7.12 - name: Promote artifacts + if: ${{ inputs.promote-pull-request == 'true' }} shell: bash env: - ARTIFACTORY_PROMOTE_ACCESS_TOKEN: ${{ fromJSON(steps.secrets.outputs.vault).ARTIFACTORY_PROMOTE_ACCESS_TOKEN }} - GITHUB_TOKEN: ${{ fromJSON(steps.secrets.outputs.vault).GITHUB_TOKEN }} + ARTIFACTORY_PROMOTE_ACCESS_TOKEN: ${{ inputs.promote-pull-request == 'true' && + fromJSON(steps.secrets.outputs.vault).ARTIFACTORY_PROMOTE_ACCESS_TOKEN || '' }} + GITHUB_TOKEN: ${{ inputs.promote-pull-request == 'true' && + fromJSON(steps.secrets.outputs.vault).GITHUB_TOKEN || '' }} DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} + MULTI_REPO_PROMOTE: ${{ inputs.multi-repo }} + ARTIFACTORY_DEPLOY_REPO: ${{ inputs.artifactory-deploy-repo }} + ARTIFACTORY_TARGET_REPO: ${{ inputs.artifactory-target-repo }} run: | ${GITHUB_ACTION_PATH}/promote.sh diff --git a/promote/mise.local.toml b/promote/mise.local.toml index 2b1cde01..eff18d47 100644 --- a/promote/mise.local.toml +++ b/promote/mise.local.toml @@ -1,2 +1,4 @@ [tools] jfrog-cli = "2.77.0" +gh = "2.76.2" +jq = "1.8.1" diff --git a/promote/promote.sh b/promote/promote.sh index c4d832c7..118a5c52 100755 --- a/promote/promote.sh +++ b/promote/promote.sh @@ -11,7 +11,7 @@ # - GITHUB_EVENT_PATH: Path to the event webhook payload file. For example, /github/workflow/event.json. # - MULTI_REPO_PROMOTE: If true, promotes to multiple repositories (default: false) # - ARTIFACTORY_DEPLOY_REPO: Repository to deploy to. If not set, it will be retrieved from the build info. -# - ARTIFACTORY_TARGET: Target repository for the promotion. If not set, it will be determined based on the branch type. +# - ARTIFACTORY_TARGET_REPO: Target repository for the promotion. If not set, it will be determined based on the branch type. # Required properties in the build info: # - buildInfo.env.ARTIFACTORY_DEPLOY_REPO: Repository to deploy to (e.g. sonarsource-deploy-qa) # - buildInfo.env.PROJECT_VERSION: Version of the project (e.g. 1.2.3) @@ -27,7 +27,7 @@ GH_API_VERSION_HEADER="X-GitHub-Api-Version: 2022-11-28" BUILD_INFO_FILE=$(mktemp) rm -f "$BUILD_INFO_FILE" -: "${MULTI_REPO_PROMOTE:=false}" +: "${MULTI_REPO_PROMOTE:=false}" "${ARTIFACTORY_DEPLOY_REPO:=}" "${ARTIFACTORY_TARGET_REPO:=}" MULTI_REPO_SRC_PRIVATE=sonarsource-private-qa MULTI_REPO_SRC_PUBLIC=sonarsource-public-qa @@ -114,8 +114,8 @@ get_build_info_property() { get_target_repo() { # Set targetRepo based on the branch type and ARTIFACTORY_DEPLOY_REPO, if not already set - if [[ -n ${ARTIFACTORY_TARGET:-} ]]; then - targetRepo="$ARTIFACTORY_TARGET" + if [[ -n $ARTIFACTORY_TARGET_REPO ]]; then + targetRepo="$ARTIFACTORY_TARGET_REPO" return fi : "${ARTIFACTORY_DEPLOY_REPO:=$(get_build_info_property ARTIFACTORY_DEPLOY_REPO)}" diff --git a/spec/promote_spec.sh b/spec/promote_spec.sh index c217c313..d930e8d5 100644 --- a/spec/promote_spec.sh +++ b/spec/promote_spec.sh @@ -74,7 +74,7 @@ Describe 'promote/promote.sh' End It 'runs promote() on pull_request' - export ARTIFACTORY_TARGET="artifactory-target" + export ARTIFACTORY_TARGET_REPO="artifactory-target" export GITHUB_EVENT_NAME="pull_request" When run script promote/promote.sh The status should be success @@ -88,8 +88,8 @@ Describe 'promote/promote.sh' The line 7 should equal "PROJECT: $PROJECT" The line 8 should equal "jf config remove repox" The line 9 should equal "jf config add repox --artifactory-url https://dummy.repox --access-token dummy promote token" - The line 10 should equal "Promote $PROJECT/$BUILD_NUMBER build artifacts to $ARTIFACTORY_TARGET" - The line 11 should equal "jf rt bpr --status it-passed-pr $PROJECT $BUILD_NUMBER $ARTIFACTORY_TARGET" + The line 10 should equal "Promote $PROJECT/$BUILD_NUMBER build artifacts to $ARTIFACTORY_TARGET_REPO" + The line 11 should equal "jf rt bpr --status it-passed-pr $PROJECT $BUILD_NUMBER $ARTIFACTORY_TARGET_REPO" The line 12 should include "gh api -X POST" End End @@ -261,7 +261,7 @@ Describe 'jfrog_promote()' End It 'promotes the build artifacts to the specified target' - export ARTIFACTORY_TARGET="artifactory-target" + export ARTIFACTORY_TARGET_REPO="artifactory-target" When call jfrog_promote The line 1 should equal "Promote $PROJECT/$BUILD_NUMBER build artifacts to artifactory-target" The line 2 should equal "jf rt bpr --status it-passed $PROJECT $BUILD_NUMBER artifactory-target"