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
33 changes: 29 additions & 4 deletions .github/workflows/go-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,14 @@ on:
description: 'Name of a GitHub Environment to scope the manifest publish job to. Empty (default) keeps the job unscoped, exactly as before. Set it to put the AWS_INIT_DATA_ROLE_ARN assume-role behind the environment''s protection rules — deployment tag policies (only protected tags may publish) and, optionally, required reviewers.'
type: string
default: ''
manifest_go_mod_path:
description: 'Path to the go.mod used by the manifest publish scope gate (direct lib-auth dependency check), relative to the repo root. Default is the root go.mod, exactly as before. A monorepo with per-service modules and no root go.mod points this at one module that has the direct dependency — manifest discovery stays repo-wide either way.'
type: string
default: 'go.mod'
manifest_component_tags:
description: 'Accept per-component release tags (<component>-vX.Y.Z, -beta.N, -rc.N) in the manifest publish environment gate, on top of plain vX.Y.Z tags. Default false keeps the gate plain-semver-only, exactly as before. The semver core stays strict either way — only an optional lowercase component prefix is allowed.'
type: boolean
default: false
# ----------------- API Dog E2E (api-dog-e2e-tests.yml) -----------------
enable_apidog_e2e:
description: 'Run the ApiDog E2E test job on tag push after a successful gitops-update'
Expand Down Expand Up @@ -877,6 +885,9 @@ jobs:

- name: Determine environment folder from tag
id: env
env:
# A workflow_call boolean reaches the shell as the string true/false.
MANIFEST_COMPONENT_TAGS: ${{ inputs.manifest_component_tags }}
run: |
set -euo pipefail
TAG="${GITHUB_REF#refs/tags/}"
Expand All @@ -889,17 +900,29 @@ jobs:
# otherwise let `v01.2.3` slip past the gate as a production tag.
NUM='(0|[1-9][0-9]*)'
CORE="v${NUM}\.${NUM}\.${NUM}"
if [[ "$TAG" =~ ^${CORE}-beta\.${NUM}$ ]]; then
# manifest_component_tags widens the gate by ONE optional prefix — a
# monorepo cutting `<service>-vX.Y.Z` per rail. It is a prefix on the
# same anchored patterns, never a replacement: the semver core, the
# anchors and the three-way order below are untouched, so `v01.2.3`
# and `spi-v1.2.3-hotfix` keep falling through to the empty folder.
PREFIX=''
if [[ "${MANIFEST_COMPONENT_TAGS}" == 'true' ]]; then
PREFIX='([a-z][a-z0-9-]*-)?'
SHAPES='vX.Y.Z, vX.Y.Z-beta.N, vX.Y.Z-rc.N, optionally prefixed with <component>-'
else
SHAPES='vX.Y.Z, vX.Y.Z-beta.N, vX.Y.Z-rc.N'
fi
if [[ "$TAG" =~ ^${PREFIX}${CORE}-beta\.${NUM}$ ]]; then
FOLDER="development"
elif [[ "$TAG" =~ ^${CORE}-rc\.${NUM}$ ]]; then
elif [[ "$TAG" =~ ^${PREFIX}${CORE}-rc\.${NUM}$ ]]; then
FOLDER="staging"
elif [[ "$TAG" =~ ^${CORE}$ ]]; then
elif [[ "$TAG" =~ ^${PREFIX}${CORE}$ ]]; then
FOLDER="production"
else
FOLDER=""
fi
echo "folder=${FOLDER}" >> "$GITHUB_OUTPUT"
[[ -n "$FOLDER" ]] && echo "📁 Environment: ${FOLDER}" || echo "::warning::Tag '${TAG}' is not a release semver tag (vX.Y.Z, vX.Y.Z-beta.N, vX.Y.Z-rc.N) — manifest publish skipped."
[[ -n "$FOLDER" ]] && echo "📁 Environment: ${FOLDER}" || echo "::warning::Tag '${TAG}' is not a release semver tag (${SHAPES}) — manifest publish skipped."

# ----------------- AWS credentials (guarded) -----------------
# Skip on a dry-run (the composite previews with no AWS call) and when the
Expand All @@ -920,6 +943,8 @@ jobs:
with:
environment: ${{ steps.env.outputs.folder }}
github-token: ${{ github.token }}
# Only moves the lib-auth scope gate; manifest discovery stays repo-wide.
go-mod-path: ${{ inputs.manifest_go_mod_path }}
dry-run: ${{ inputs.dry_run }}

# ----------------- Extra Builds (tag push, opt-in) -----------------
Expand Down
29 changes: 29 additions & 0 deletions docs/go-release.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ A third layout needs `release_single_app: true`: **one semantic-release tag for
| `s3_upload_mirrors` | JSON object mapping an `s3_uploads` bucket to a second bucket that receives every file uploaded to it under the same key (see [Mirror bucket](#mirror-bucket)) | string | `{"lerian-migration-files":{"bucket":"lerian-development-migrations","region":"us-east-2"}}` |
| `run_manifest_publish` | Publish this service's own `permissions.yaml` to the shared Access-Manager RI catalog in S3 on tag push (see [Permission manifest publish](#permission-manifest-publish-ri)) | boolean | `true` |
| `manifest_publish_environment` | GitHub Environment to scope the manifest publish job to, putting the `AWS_INIT_DATA_ROLE_ARN` assume-role behind that environment's protection rules. Empty keeps the job unscoped | string | `''` |
| `manifest_go_mod_path` | Path to the `go.mod` the manifest publish scope gate reads for the direct lib-auth dependency, relative to the repo root. Point it at a service module in a monorepo with no root `go.mod` — discovery stays repo-wide | string | `'go.mod'` |
| `manifest_component_tags` | Also accept per-component release tags (`<component>-vX.Y.Z`, `-beta.N`, `-rc.N`) in the environment gate. The semver core stays strict either way | boolean | `false` |
| `enable_apidog_e2e` | Run the ApiDog E2E test job on tag push after a successful gitops-update | boolean | `false` |
| `apidog_runner_type` | Runner for the ApiDog E2E test job (needs reach to the deployed environment) | string | `eveo-lxc-runners` |
| `apidog_auto_detect_environment` | Auto-detect the ApiDog environment from the tag (beta → dev, rc → stg); when `false`, uses `APIDOG_ENVIRONMENT_ID` | boolean | `true` |
Expand Down Expand Up @@ -243,6 +245,33 @@ Set `run_manifest_publish: false` to opt out.

For an extra gate on **who** may publish, set `manifest_publish_environment` to the name of a GitHub Environment configured in the caller repo. The publish job then runs under that environment, so its protection rules apply to the assume-role — a **deployment tag policy** (e.g. `v*.*.*`) restricts publishing to the tags you protect, and required reviewers can hold a production publish for approval. Left empty (the default) the job stays unscoped, as before.

### Per-component tags and a non-root `go.mod`

A monorepo that cuts one version line per service — tags like `spi-v1.2.3`, `slc-edge-v1.2.3-beta.4` — matches none of those shapes and publishes nothing. Set `manifest_component_tags: true` to allow **one optional lowercase component prefix** before the version:

| Tag | `manifest_component_tags: false` | `manifest_component_tags: true` |
|---|---|---|
| `v1.2.3` | `production` | `production` |
| `spi-v1.2.3` | skipped | `production` |
| `slc-edge-v1.2.3-beta.4` | skipped | `development` |
| `cockpit-v2.0.0-rc.3` | skipped | `staging` |
| `v01.2.3` | skipped | skipped |
| `spi-v1.2.3-hotfix` | skipped | skipped |

The prefix is the **only** thing that widens: the semver core keeps rejecting leading zeroes and arbitrary suffixes, and the prefix itself must start with a lowercase letter and hold only lowercase letters, digits and hyphens. A tag off-shape still publishes nothing. Leave the input at its default and the gate behaves exactly as it always has.

`manifest_go_mod_path` moves **only** the lib-auth scope gate. A repo with per-service modules and no root `go.mod` points it at one module carrying the direct dependency; manifest discovery stays repo-wide, so the repo still publishes one object per `service:` value found anywhere in the tree:

```yaml
uses: LerianStudio/github-actions-shared-workflows/.github/workflows/go-release.yml@tier-1
with:
run_manifest_publish: true
manifest_go_mod_path: services/spi/go.mod
manifest_component_tags: true
secrets:
AWS_INIT_DATA_ROLE_ARN: ${{ secrets.AWS_INIT_DATA_ROLE_ARN }}
```

## ApiDog E2E tests

Set `enable_apidog_e2e: true` to run [api-dog-e2e-tests](./api-dog-e2e-tests.md) on tag push after a successful `update_gitops`. The job is skipped on branch pushes and when the gitops update did not succeed.
Expand Down
Loading