From 51de70d999daba529e6fedacf62076dc276e17a2 Mon Sep 17 00:00:00 2001 From: Jayadeep Kinavoor Madam Date: Thu, 28 May 2026 11:44:35 +0200 Subject: [PATCH] BUILD-11459: Add update-release-channel composite action skeleton Adds the action.yml + write_channel.sh stub at update-release-channel/. Dry-run mode skips the Vault step and writes placeholder bucket/key/etag to GITHUB_OUTPUT so the action is invokable end-to-end before the real S3 write logic lands. --- update-release-channel/action.yml | 67 +++++++++++++++++++++++++ update-release-channel/write_channel.sh | 33 ++++++++++++ 2 files changed, 100 insertions(+) create mode 100644 update-release-channel/action.yml create mode 100755 update-release-channel/write_channel.sh diff --git a/update-release-channel/action.yml b/update-release-channel/action.yml new file mode 100644 index 00000000..28dd1b35 --- /dev/null +++ b/update-release-channel/action.yml @@ -0,0 +1,67 @@ +--- +name: Update release channel +description: | + Update a release channel pointer (e.g. `Distribution//latest.json`) on + `binaries.sonarsource.com` so consumers can discover the currently published version. +inputs: + version: + description: Version that the channel should be updated to point at (e.g. `0.9.0.977`). + required: true + channel: + description: Release channel name. One of `latest`, `stable`, `beta`, `rc`. + default: latest + prefix: + description: S3 key prefix under the bucket. Defaults to `Distribution` (existing layout convention). + default: Distribution + product: + description: Product folder name on S3. Defaults to the GitHub repository name. + default: ${{ github.event.repository.name }} + dryRun: + description: | + When `true`, resolve and validate inputs and print the planned `PutObject` without fetching + Vault credentials or writing to S3. + default: 'false' +outputs: + bucket: + description: S3 bucket the channel pointer was (or would be) written to. + value: ${{ steps.write.outputs.bucket }} + key: + description: S3 key of the channel pointer (e.g. `Distribution//.json`). + value: ${{ steps.write.outputs.key }} + etag: + description: ETag returned by S3 after `PutObject`. Empty in dry-run. + value: ${{ steps.write.outputs.etag }} + +runs: + using: composite + steps: + - name: Resolve action path + shell: bash + run: | + ACTION_PATH_URC="${{ github.action_path }}" + echo "ACTION_PATH_URC=$ACTION_PATH_URC" >> "$GITHUB_ENV" + + - name: Fetch AWS credentials from Vault + id: secrets + if: inputs.dryRun != 'true' + uses: SonarSource/vault-action-wrapper@c154b4a417b51cb98dd71137f49bf20e77c56820 # 3.4.0 + with: + secrets: | + development/aws/sts/downloads access_key | AWS_ACCESS_KEY_ID; + development/aws/sts/downloads secret_key | AWS_SECRET_ACCESS_KEY; + development/aws/sts/downloads security_token | AWS_SESSION_TOKEN; + + - name: Write channel pointer + id: write + shell: bash + env: + VERSION: ${{ inputs.version }} + CHANNEL: ${{ inputs.channel }} + PREFIX: ${{ inputs.prefix }} + PRODUCT: ${{ inputs.product }} + DRY_RUN: ${{ inputs.dryRun }} + AWS_DEFAULT_REGION: eu-central-1 + AWS_ACCESS_KEY_ID: ${{ inputs.dryRun != 'true' && fromJSON(steps.secrets.outputs.vault).AWS_ACCESS_KEY_ID || '' }} + AWS_SECRET_ACCESS_KEY: ${{ inputs.dryRun != 'true' && fromJSON(steps.secrets.outputs.vault).AWS_SECRET_ACCESS_KEY || '' }} + AWS_SESSION_TOKEN: ${{ inputs.dryRun != 'true' && fromJSON(steps.secrets.outputs.vault).AWS_SESSION_TOKEN || '' }} + run: ${ACTION_PATH_URC}/write_channel.sh diff --git a/update-release-channel/write_channel.sh b/update-release-channel/write_channel.sh new file mode 100755 index 00000000..f73637e8 --- /dev/null +++ b/update-release-channel/write_channel.sh @@ -0,0 +1,33 @@ +#!/bin/bash +# Resolve inputs for the update-release-channel action and write the channel pointer to S3. +# +# Required environment variables (provided by action.yml): +# - VERSION: Version the channel should point at. +# - CHANNEL: Channel name (`latest`, `stable`, `beta`, `rc`). +# - PREFIX: S3 key prefix (e.g. `Distribution`). +# - PRODUCT: Product folder name on S3 (defaults to the GitHub repository name). +# - DRY_RUN: `true` to skip any real AWS call. + +set -euo pipefail + +: "${VERSION:?}" "${CHANNEL:?}" "${PREFIX:?}" "${PRODUCT:?}" +: "${DRY_RUN:=false}" + +BUCKET="downloads-cdn-eu-central-1-prod" +KEY="${PREFIX}/${PRODUCT}/${CHANNEL}.json" + +echo "::group::Resolved inputs" +echo "version: ${VERSION}" +echo "channel: ${CHANNEL}" +echo "prefix: ${PREFIX}" +echo "product: ${PRODUCT}" +echo "dryRun: ${DRY_RUN}" +echo "bucket: ${BUCKET}" +echo "key: ${KEY}" +echo "::endgroup::" + +{ + echo "bucket=${BUCKET}" + echo "key=${KEY}" + echo "etag=" +} >> "${GITHUB_OUTPUT:?}"