Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 98 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ These badges show the status of workflows in dummy repositories that use (or sho
- [`pr_cleanup`](#pr_cleanup)
- [`code-signing`](#code-signing)
- [`check-sca`](#check-sca)
- [`update-release-channel`](#update-release-channel)

---

Expand Down Expand Up @@ -1447,6 +1448,103 @@ jobs:

---

## `update-release-channel`

Updates a per-channel JSON pointer file on `binaries.sonarsource.com` so consumers can discover the currently published
version for each release channel of a product. Writes one JSON file per channel at
`<prefix>/<product>/<channel>.json` (atomic, single S3 `PutObject`). The body follows the
[v1 schema](update-release-channel/schema/v1.json); see [schema/README.md](update-release-channel/schema/README.md) for the
field contract.

### Requirements

#### Required GitHub Permissions

- `id-token: write`
- `contents: read`

#### Required Vault Permissions

- `development/aws/sts/downloads`: STS credentials to write to `s3://downloads-cdn-eu-central-1-prod`. This is the same
preset already provisioned for `SonarSource/gh-action_release`.

#### Other Dependencies

The action installs the AWS CLI on demand via `mise` — no other tooling needs to be pre-installed on the runner.

### Usage

As a release-workflow follow-up job (automated `latest` promotion):

```yaml
jobs:
release:
uses: SonarSource/gh-action_release/.github/workflows/main.yaml@7.0.1
with: { ... }

update-channel:
needs: release
if: ${{ !inputs.dryRun }}
runs-on: sonar-xs
permissions:
id-token: write
contents: read
steps:
- uses: SonarSource/ci-github-actions/update-release-channel@v1
with:
version: ${{ inputs.version }}
```

As a standalone `workflow_dispatch` (manual ops — rollback, delayed promotion, backfill):

```yaml
on:
workflow_dispatch:
inputs:
version: { required: true, type: string }
channel: { required: true, type: choice, options: [latest, stable, beta, rc, dogfood] }

jobs:
update-channel:
runs-on: sonar-xs
environment: release-channel-admin # recommended; see note below
permissions:
id-token: write
contents: read
steps:
- uses: SonarSource/ci-github-actions/update-release-channel@v1
with:
version: ${{ inputs.version }}
channel: ${{ inputs.channel }}
```

Referencing a `release-channel-admin` GitHub Environment (configured with required reviewers) is recommended for
manual-ops workflows so every manual write requires an approver. The action runs without it — the gate is opt-in,
set up per consuming repo. Environments at SonarSource are managed in
[`re-service-config`](https://github.com/SonarSource/re-service-config) via the `github_repository_environment`
Terraform resource; add the environment for your repo there alongside the existing examples.

### Inputs

| Input | Description | Default |
|-----------|------------------------------------------------------------------------------------------------------------|---------------------------------------|
| `version` | Version the channel should point at (e.g. `0.9.0.977`). Required. | — |
| `channel` | Release channel name. One of `latest`, `stable`, `beta`, `rc`, `dogfood`. | `latest` |
| `prefix` | S3 key prefix under the bucket. Other values warn but are accepted. | `Distribution` |
| `product` | Product folder name on S3. Set explicitly when the S3 folder differs from the GitHub repo name. | `${{ github.event.repository.name }}` |
| `dryRun` | Resolve and validate inputs, print the planned `PutObject`, skip Vault + AWS calls. | `false` |

### Outputs

| Output | Description |
|----------|---------------------------------------------------------------------------------|
| `bucket` | S3 bucket of the JSON pointer file. |
| `key` | S3 key of the JSON pointer file (e.g. `Distribution/<product>/<channel>.json`). |
| `url` | Public URL of the JSON pointer file. |
| `body` | Content of the JSON pointer file. |

---

## Deployment Strategy

All build actions (`build-maven`, `build-gradle`, `build-npm`, `build-yarn`, `build-poetry`) share the same branch-based deployment and
Expand Down
2 changes: 1 addition & 1 deletion update-release-channel/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ inputs:
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`.
description: Release channel name. One of `latest`, `stable`, `beta`, `rc`, `dogfood`.
default: latest
prefix:
description: S3 key prefix under the bucket. Defaults to `Distribution` (existing layout convention).
Expand Down
6 changes: 3 additions & 3 deletions update-release-channel/update-release-channel.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#
# Required environment variables:
# VERSION - Version the channel should point at (e.g. "0.9.0.977")
# CHANNEL - Channel name (latest|stable|beta|rc)
# CHANNEL - Channel name (latest|stable|beta|rc|dogfood)
# PREFIX - S3 key prefix (default in action.yml: "Distribution")
# PRODUCT - Product folder on S3 (default in action.yml: GitHub repo name)
# DRY_RUN - "true" to skip the AWS call and just print the planned PutObject
Expand All @@ -21,8 +21,8 @@ set -euo pipefail
readonly BUCKET="downloads-cdn-eu-central-1-prod"
readonly PUBLIC_BASE_URL="https://binaries.sonarsource.com"

[[ "$CHANNEL" =~ ^(latest|stable|beta|rc)$ ]] \
|| { echo "::error::Invalid channel '$CHANNEL'. Must be one of: latest, stable, beta, rc." >&2; exit 1; }
[[ "$CHANNEL" =~ ^(latest|stable|beta|rc|dogfood)$ ]] \
|| { echo "::error::Invalid channel '$CHANNEL'. Must be one of: latest, stable, beta, rc, dogfood." >&2; exit 1; }
Comment thread
jayadeep-km-sonarsource marked this conversation as resolved.
Comment thread
jayadeep-km-sonarsource marked this conversation as resolved.
[[ "$PRODUCT" =~ ^[a-z0-9][a-z0-9._-]*$ ]] \
|| { echo "::error::Invalid product '$PRODUCT'. Must match ^[a-z0-9][a-z0-9._-]*\$." >&2; exit 1; }
[[ "$PREFIX" =~ ^[A-Za-z0-9][A-Za-z0-9._-]*$ ]] \
Expand Down
Loading