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
13 changes: 8 additions & 5 deletions .github/workflows/build-push-quay.yaml
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
# Reusable workflow: build a container image and push to Quay.io.
# Call from manager repos (service-provider-manager, catalog-manager, etc.).
# Caller must pass QUAY_USERNAME and QUAY_PASSWORD (or robot token) as secrets.
# Call from `dcm-project` repos that publish container images (control-plane,
# service providers, etc.).
# Caller repo secrets: QUAY_USERNAME and QUAY_TOKEN (Quay login password for
# that account; robot token or user password). Map to quay-username and
# quay-password inputs below.

name: Build and Push to Quay

on:
workflow_call:
inputs:
image-name:
description: 'Image name (e.g. service-provider-manager)'
description: 'Image name (e.g. control-plane)'
type: string
required: true
registry:
Expand Down Expand Up @@ -37,10 +40,10 @@ on:
default: 'linux/amd64,linux/arm64'
secrets:
quay-username:
description: 'Quay.io username or robot account name'
description: 'Quay username or robot account. Caller maps secrets.QUAY_USERNAME here.'
required: true
quay-password:
description: 'Quay.io password or robot token'
description: 'Quay login password (robot token or user password). Caller maps secrets.QUAY_TOKEN here.'
required: true

jobs:
Expand Down
107 changes: 0 additions & 107 deletions .github/workflows/gateway-contract-test.yaml

This file was deleted.

144 changes: 58 additions & 86 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,8 @@ Reusable GitHub Actions workflows for DCM project repositories.
| `check-aep.yaml` | Validate OpenAPI specs against AEP standards | Repos with OpenAPI |
| `check-generate.yaml` | Verify generated files are in sync | Repos with code generation |
| `check-clean-commits.yaml` | Ensure PR commits are cleaned before merge | All repos |
| `build-push-quay.yaml` | Build container image and push to Quay.io | Manager repos (Containerfile) |
| `build-push-quay.yaml` | Build container image and push to Quay.io | `dcm-project` repos with a Containerfile |
| `tag-release.yaml` | Git-tag all service repos with a release or RC version | shared-workflows (manual dispatch) |
| `gateway-contract-test.yaml` | Validate KrakenD gateway routes against backend OpenAPI specs | api-gateway and backend repos |
| `gitleaks.yaml` | Scan for leaked secrets using gitleaks | All repos |

## Usage
Expand All @@ -37,7 +36,8 @@ See individual workflow files for available options and inputs.

### Build and push to Quay.io

Use `build-push-quay.yaml` from manager repos that have a `Containerfile`. Create `.github/workflows/build-push-quay.yaml`:
Use `build-push-quay.yaml` from `dcm-project` repos that have a `Containerfile`. Create
`.github/workflows/build-push-quay.yaml`:

```yaml
name: Build and Push Image
Expand All @@ -55,11 +55,11 @@ jobs:
build-push:
uses: dcm-project/shared-workflows/.github/workflows/build-push-quay.yaml@main
with:
image-name: service-provider-manager
image-name: control-plane
version: ${{ github.event.inputs.version }}
secrets:
quay-username: ${{ secrets.QUAY_USERNAME }}
quay-password: ${{ secrets.QUAY_PASSWORD }}
quay-password: ${{ secrets.QUAY_TOKEN }}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit — the example now passes secrets.QUAY_TOKEN here, but the "Required secrets" section further down still says QUAY_USERNAME, QUAY_PASSWORD. Whichever name the org is actually using, the two spots should match so the next person setting up a new repo doesn't have to guess.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch.
Addressed in 4af19e2: can you please check if it reads better?

```

#### Tag behavior
Expand All @@ -71,68 +71,83 @@ jobs:
| Push of `v*` git tag | `<short-sha>`, tag name | `:a6882f7`, `:v0.0.1`, `:v0.0.1-rc.1` |
| Manual dispatch with `version` | Only the specified tag | `:v0.0.1` |

`main` tag is only produced by pushes to the `main` branch. Version branch and git tag pushes do not update it.
`main` tag is only produced by pushes to the `main` branch. Version branch and
git tag pushes do not update it.

#### Release flow

1. **Development happens on `main`** -- every merge triggers a build tagged `main` and `<short-sha>`.
1. **Development happens on `main`** -- every merge triggers a build tagged
`main` and `<short-sha>`.

2. **Create a release branch** prefixed with `release/`:
```bash
git checkout -b release/v0.0.1
git push -u origin release/v0.0.1
```

3. **Push fixes** to the release branch. Each push triggers CI, producing a `<short-sha>` image:
3. **Push fixes** to the release branch. Each push triggers CI, producing a
`<short-sha>` image:
```bash
git checkout release/v0.0.1
# ... commit fixes ...
git push origin release/v0.0.1
```

4. **(Optional) Tag a release candidate**. Use the [script](https://github.com/dcm-project/shared-workflows/blob/main/hack/tag-release.sh)
4. **(Optional) Tag a release candidate**. Use the
[script](https://github.com/dcm-project/shared-workflows/blob/main/hack/tag-release.sh)
to git-tag all service repos at once from their release branch HEAD:
```bash
./hack/tag-release.sh v0.0.1-rc.1
```
Each git tag push triggers CI, which builds the image with tags `v0.0.1-rc.1` and `<short-sha>`.
Each git tag push triggers CI, which builds the image with tags `v0.0.1-rc.1`
and `<short-sha>`.

5. **QE validates** against the RC tag. If issues are found,
push fixes to the release branch (step 3) and cut the next RC (step 4).
5. **QE validates** against the RC tag. If issues are found, push fixes to the
release branch (step 3) and cut the next RC (step 4).

6. **Tag the final release** on the approved commit using the same script:
```bash
./hack/tag-release.sh v0.0.1
```
CI builds the image with tags `v0.0.1` and `<short-sha>` for each service.

7. **Cherry-pick** bug fixes from the release branch into `main` (if not already in main),
so that issues caught during stabilization are propagated into main.
7. **Cherry-pick** bug fixes from the release branch into `main` (if not already
in main), so that issues caught during stabilization are propagated into
main.

8. **For the next release**, create a new branch (e.g. `release/v0.0.2` or `release/v0.1.0`) and repeat from step 2.
8. **For the next release**, create a new branch (e.g. `release/v0.0.2` or
`release/v0.1.0`) and repeat from step 2.

#### Version convention

Follow [Semantic Versioning](https://semver.org/): `vMAJOR.MINOR.PATCH` (e.g. `v0.0.1`, `v1.2.0`).
All version identifiers must start with `v`. Release branches use the `release/` prefix (e.g. `release/v0.0.1`).
Both release candidates (`v0.0.1-rc.1`) and final releases (`v0.0.1`) are git-tagged.
Follow [Semantic Versioning](https://semver.org/): `vMAJOR.MINOR.PATCH` (e.g.
`v0.0.1`, `v1.2.0`). All version identifiers must start with `v`. Release
branches use the `release/` prefix (e.g. `release/v0.0.1`). Both release
candidates (`v0.0.1-rc.1`) and final releases (`v0.0.1`) are git-tagged.

**Required secrets:** `QUAY_USERNAME`, `QUAY_PASSWORD` (org or repo level). Default registry is `quay.io/dcm-project`. Images are built for `linux/amd64` and `linux/arm64`; override with the `platforms` input if needed.
**Required secrets:** `QUAY_USERNAME`, `QUAY_TOKEN` (org or repo level).
`QUAY_TOKEN` is the Quay password for that account (robot token or user
password). Map both to the workflow `quay-username` and `quay-password`
inputs as in the example above.
Default registry is `quay.io/dcm-project`. Images are built for `linux/amd64`
and `linux/arm64`; override with the `platforms` input if needed.

#### Release tagging

Use `tag-release.yaml` to git-tag all service repos at once from their release branch HEAD.
Each tag push triggers CI, which builds and pushes the image. This works for both RC tags and final releases.
Use `tag-release.yaml` to git-tag all service repos at once from their release
branch HEAD. Each tag push triggers CI, which builds and pushes the image. This
works for both RC tags and final releases.

**GitHub workflow** -- trigger via the Actions UI (shared-workflows -> Actions -> "Tag Release" -> Run workflow) or the CLI:
**GitHub workflow** -- trigger via the Actions UI (shared-workflows -> Actions
-> "Tag Release" -> Run workflow) or the CLI:

```bash
gh workflow run tag-release.yaml --repo dcm-project/shared-workflows \
-f tag=v0.0.1-rc.1

gh workflow run tag-release.yaml --repo dcm-project/shared-workflows \
-f tag=v0.0.1-rc.2 \
-f services="placement-manager catalog-manager"
-f services="control-plane"

gh workflow run tag-release.yaml --repo dcm-project/shared-workflows \
-f tag=v0.0.1
Expand All @@ -147,72 +162,21 @@ gh workflow run tag-release.yaml --repo dcm-project/shared-workflows \

```bash
./hack/tag-release.sh v0.0.1-rc.1 # tag all services
./hack/tag-release.sh v0.0.1-rc.2 placement-manager catalog-manager # specific services only
./hack/tag-release.sh v0.0.1-rc.2 control-plane # specific services only
./hack/tag-release.sh v0.0.1 # final release
```

The script resolves the HEAD of the release branch (derived from the tag: `v0.0.1-rc.1` or `v0.0.1` -> branch `release/v0.0.1`)
for each service repo via `gh api`, creates an annotated git tag at that commit, and pushes it.

### Gateway contract test

Use `gateway-contract-test.yaml` from the **api-gateway** repo to validate that KrakenD routes match backend OpenAPI specs, and from **manager** repos to validate that a service's OpenAPI spec is covered by the gateway. The gateway's `krakend.json` must define `x-contract-specs`.

**x-contract-specs** is a top-level key in the KrakenD config (e.g. `config/krakend.json`). It is an object mapping backend hostname (as used in gateway routes) to `{ "openapi_url": "https://..." }`. The script loads each spec from `openapi_url` and checks that every backend route's method and path exists in the corresponding spec. Example:

```json
"x-contract-specs": {
"service-provider-manager": {
"openapi_url": "https://raw.githubusercontent.com/dcm-project/service-provider-manager/main/api/v1alpha1/openapi.yaml"
},
"catalog-manager": {
"openapi_url": "https://raw.githubusercontent.com/dcm-project/catalog-manager/main/api/v1alpha1/openapi.yaml"
}
}
```

**Gateway repo:** In the repo that owns `krakend.json` (e.g. api-gateway), add a job to `.github/workflows/ci.yaml`:

```yaml
gateway-contract-test:
name: Gateway Contract Test
uses: dcm-project/shared-workflows/.github/workflows/gateway-contract-test.yaml@main
with:
warn-uncovered: true
watch-paths: |
config/krakend.json
config/krakend.json.tmpl
```

Use `warn-uncovered: true` to warn when the spec defines paths that no gateway route uses.

**Manager repo:** In a backend/manager repo that exposes an OpenAPI spec and is wired in the gateway's `x-contract-specs`, create `.github/workflows/gateway-contract-test.yaml` (or add a job to CI) that calls the shared workflow with `krakend-repo` set to the gateway repo and `override-spec` so this repo's OpenAPI file is used for that service. Run on PRs when `api/**/openapi.yaml` (or equivalent) changes:

```yaml
name: Gateway Contract Test
on:
pull_request:
branches: [main]

jobs:
contract-test:
uses: dcm-project/shared-workflows/.github/workflows/gateway-contract-test.yaml@main
with:
krakend-repo: dcm-project/api-gateway
krakend-config: config/krakend.json
override-spec: service-provider-manager=api/v1alpha1/openapi.yaml
service: service-provider-manager
watch-paths: |
api/**/openapi.yaml
```

`override-spec` is `hostname=path/to/openapi.yaml` (path relative to the manager repo root). `service` limits validation to that backend.

**Key inputs:** `krakend-repo`, `krakend-config`, `override-spec`, `service`, `warn-uncovered`, `watch-paths`. See the workflow file for the full list.
The script resolves the HEAD of the release branch (derived from the tag:
`v0.0.1-rc.1` or `v0.0.1` -> branch `release/v0.0.1`) for each service repo via
`gh api`, creates an annotated git tag at that commit, and pushes it.

### Gitleaks secret scanning

Use `gitleaks.yaml` to scan for leaked secrets. It supports three scan modes: **diff** (PR commits), **push** (pushed commits), and **full** (entire history). Results are reported in SARIF format and uploaded to GitHub Code Scanning by default, so findings appear in the repository Security tab and as inline PR annotations.
Use `gitleaks.yaml` to scan for leaked secrets. It supports three scan modes:
**diff** (PR commits), **push** (pushed commits), and **full** (entire history).
Results are reported in SARIF format and uploaded to GitHub Code Scanning by
default, so findings appear in the repository Security tab and as inline PR
annotations.

**Pull request scanning** -- create `.github/workflows/gitleaks.yaml`:

Expand Down Expand Up @@ -265,7 +229,15 @@ jobs:
| `artifact-name` | string | `'gitleaks-report'` | Artifact name when `upload-sarif` is false |
| `artifact-retention-days` | number | `90` | Artifact retention in days |

**Custom config:** To override gitleaks rules, add a `.gitleaks.toml` to your repo and pass its path via `config-path`. When empty, gitleaks uses its built-in ruleset.

**SARIF integration:** Results use [SARIF](https://docs.github.com/en/code-security/code-scanning/integrating-with-code-scanning/sarif-support-for-code-scanning) format and are uploaded to GitHub Code Scanning via `github/codeql-action/upload-sarif@v4`. This makes findings visible in the repository's Security tab and as inline PR annotations, consistent with other GitHub security tooling. For full-history scans, set `upload-sarif: false` to download the report as a workflow artifact instead.
**Custom config:** To override gitleaks rules, add a `.gitleaks.toml` to your
repo and pass its path via `config-path`. When empty, gitleaks uses its built-in
ruleset.

**SARIF integration:** Results use
[SARIF](https://docs.github.com/en/code-security/code-scanning/integrating-with-code-scanning/sarif-support-for-code-scanning)
format and are uploaded to GitHub Code Scanning via
`github/codeql-action/upload-sarif@v4`. This makes findings visible in the
repository's Security tab and as inline PR annotations, consistent with other
GitHub security tooling. For full-history scans, set `upload-sarif: false` to
download the report as a workflow artifact instead.

Loading