Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
263f619
chore(ci): fix reference
bedatty Mar 6, 2026
9b22512
Merge pull request #123 from LerianStudio/chore/fix-reference
bedatty Mar 6, 2026
f490988
chore: backmerge main into develop (sync release tags)
bedatty Mar 6, 2026
58b64d0
fix(ci): removing secret values
bedatty Mar 6, 2026
6d3c7a2
chore(deps): bump actions/github-script in the utilities group
dependabot[bot] Mar 9, 2026
583b8c1
Merge pull request #124 from LerianStudio/fix/github-values
bedatty Mar 9, 2026
08bd664
feat(build): add typescript docker build workflow and composite
bedatty Mar 9, 2026
064c173
fix(build): reference composite via external path instead of local
bedatty Mar 9, 2026
43be833
fix(build): address CodeRabbit review feedback on typescript build wo…
bedatty Mar 9, 2026
03ee1be
fix(build): fix helm version mismatch, harden prepare job inputs and …
bedatty Mar 9, 2026
9094c1f
Merge pull request #126 from LerianStudio/feat/typescript-build
bedatty Mar 9, 2026
5ddbc00
fix(build): use per-app build context with fallback to global input
bedatty Mar 9, 2026
605f2d0
Merge pull request #127 from LerianStudio/fix/typescript-build-context
bedatty Mar 10, 2026
91c8cd3
chore(ci): standardize runner to blacksmith-4vcpu-ubuntu-2404
bedatty Mar 10, 2026
13e7761
chore(ci): add runner rule to cursor rules
bedatty Mar 10, 2026
f4f4f69
Merge pull request #128 from LerianStudio/chore/standardize-blacksmit…
bedatty Mar 10, 2026
9ab0775
feat(ci): add go-fuzz reusable workflow
bedatty Mar 10, 2026
70f8d87
fix(ci): scope fuzz artifact upload to fuzz step failure
bedatty Mar 10, 2026
c389b2a
feat(ci): add timeout safety net and document fuzz command requirements
bedatty Mar 10, 2026
647b94d
Merge pull request #129 from LerianStudio/feat/go-fuzz-workflow
bedatty Mar 10, 2026
d7b516d
feat(ci): add release-notification reusable workflow with Discord and…
bedatty Mar 10, 2026
804c76a
fix(ci): address CodeRabbit review on release-notification workflow
bedatty Mar 10, 2026
1e66d3d
fix(ci): use external refs for composites in release-notification wor…
bedatty Mar 10, 2026
234e15a
fix(ci): add has_builds output to build workflow and update external …
bedatty Mar 11, 2026
ad751c2
fix(ci): address CodeRabbit review — markdownlint, pin refs, dry-run …
bedatty Mar 11, 2026
aee97ad
docs(ci): add skip-enabling outputs rule for workflows and composites
bedatty Mar 11, 2026
4097422
fix(docs): use external refs in skip-enabling output examples
bedatty Mar 11, 2026
52fbc04
Merge pull request #130 from LerianStudio/feat/release-notification-w…
bedatty Mar 11, 2026
337a6d2
feat(ci): add changed-paths composite action and refactor workflow to…
bedatty Mar 11, 2026
7b78c65
refactor(ci): remove changed-paths reusable workflow and migrate rele…
bedatty Mar 11, 2026
794200e
Merge pull request #133 from LerianStudio/feat/changed-paths-composite
bedatty Mar 11, 2026
fe42ff1
Merge pull request #119 from LerianStudio/dependabot/github_actions/d…
bedatty Mar 11, 2026
41c93c4
fix(ci): compare against previous tag instead of HEAD^ on tag pushes
bedatty Mar 11, 2026
72bcb47
Merge pull request #134 from LerianStudio/fix/tag-comparison-previous…
bedatty Mar 11, 2026
10dffbd
chore(deps): bump the release group with 2 updates (#117)
dependabot[bot] Mar 11, 2026
9566d76
chore(deps): bump goreleaser/goreleaser-action in the go-tooling grou…
dependabot[bot] Mar 11, 2026
eb76482
chore(deps): bump the security-scanners group with 2 updates (#115)
dependabot[bot] Mar 11, 2026
fb0eaa0
Merge pull request #114 from LerianStudio/dependabot/github_actions/d…
dependabot[bot] Mar 11, 2026
2d7febe
Merge pull request #113 from LerianStudio/dependabot/github_actions/d…
dependabot[bot] Mar 11, 2026
1876886
chore(deps): bump the actions-core group with 5 updates (#112)
dependabot[bot] Mar 11, 2026
8ab1bb0
fix(ci): use path segment boundary matching to prevent prefix collisi…
bedatty Mar 12, 2026
6d8d804
refactor(ci): migrate basic workflows to internal changed-paths compo…
bedatty Mar 12, 2026
896c92f
feat(ci): add force_multiplatform input to build workflow (#93)
bedatty Mar 12, 2026
fe4fa32
chore(deps): update actions to latest major versions for Node 24 comp…
bedatty Mar 12, 2026
0c7bd5b
feat(ci): add integration tests and test determinism jobs to go-pr-an…
bedatty Mar 12, 2026
ae466e0
fix(deps): correct tcort markdown-link-check action repository name (…
bedatty Mar 12, 2026
a36d49d
feat(security): add Docker Scout scan composite and integrate into pr…
bedatty Mar 13, 2026
0af0229
feat(security): Docker Scout integration with policy enforcement and …
bedatty Mar 17, 2026
3ac4d79
Merge pull request #146 from LerianStudio/main
bedatty Mar 17, 2026
46129c1
fix(changed-paths): use channel-aware tag comparison for beta/rc/release
bedatty Mar 18, 2026
40c5553
Merge pull request #153 from LerianStudio/fix/channel-aware-tag-compa…
bedatty Mar 18, 2026
10aec97
feat(ci): add YAML and GitHub Actions lint analysis for PRs (#148)
bedatty Mar 19, 2026
6cf6c4a
feat(changed-paths): add shared_paths input to trigger full matrix on…
bedatty Mar 20, 2026
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 .claude/commands/composite.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,65 @@ runs:
option: ${{ inputs.some-option }}
```

## Configurability — defaults first, override when needed

Every composite must be **self-contained with sensible defaults**. A caller should get a safe, useful result with zero extra configuration. Additional inputs allow the workflow (or caller) to override specific behaviors.

**Composite layer — always define defaults:**

```yaml
inputs:
enable-recommendations:
description: Include Docker Scout recommendations in the PR comment
required: false
default: "true" # ✅ composite works standalone
severity-threshold:
required: false
default: "high" # ✅ opinionated but safe default
```

**Rules:**
- All optional inputs must have a `default` — never `required: true` for feature flags
- Never hardcode feature flags — expose them as inputs so they can be overridden by the reusable workflow
- Step-level feature toggles (`if: inputs.enable_xxx`) belong in the **reusable workflow**, not inside the composite

**Three-layer configurability flow:**

```
Caller repo Reusable workflow Composite
──────────────────────── ────────────────────────── ──────────────────────────
enable_docker_scout_ → enable_docker_scout_ → enable-recommendations:
recommendations: false recommendations ${{ inputs.... }}
(passes it down)
```

## Step section titles

When a composite has more than one logical group of steps, separate them with a titled section comment:

```yaml
runs:
using: composite
steps:
# ----------------- Setup -----------------
- name: Login to Docker Registry
...

# ----------------- Scan -----------------
- name: Docker Scout CVEs
...

# ----------------- Recommendations -----------------
- name: Docker Scout Recommendations
...
```

**Rules:**
- Format: `# ----------------- Title -----------------` (exact spacing)
- Add when there are 2+ logical groups of steps
- Title must be short and action-oriented
- Place the comment immediately before the first step — no blank line between comment and step

## Design rules

- **5–15 steps maximum** — split if larger
Expand Down Expand Up @@ -100,6 +159,25 @@ src/deploy/helm-deploy/ ← any chart
src/config/labels-sync/ ← any repo
```

## Runner

Composites inherit the runner from the calling job. All usage examples in `README.md` must specify `blacksmith-4vcpu-ubuntu-2404` as the runner:

```yaml
jobs:
example:
runs-on: blacksmith-4vcpu-ubuntu-2404 # ✅ required runner
steps:
- uses: ./src/config/labels-sync
```

```yaml
# ❌ Never use other runners in examples
runs-on: ubuntu-latest
runs-on: ubuntu-22.04
runs-on: self-hosted
```

## README.md requirements

1. Logo header — HTML table layout (logo left, `h1` title right)
Expand Down Expand Up @@ -157,3 +235,23 @@ new-tool-category:
```

Never add `LerianStudio/*` actions to dependabot — pinned to `@main` intentionally.

## Reserved input names — never use

Never declare composite inputs using GitHub's reserved prefixes — they conflict with runtime variables and break jobs:

```yaml
# ❌ Reserved — conflicts with GitHub's runtime variable
inputs:
GITHUB_TOKEN:
GITHUB_SHA:
ACTIONS_RUNTIME_TOKEN:
RUNNER_OS:

# ✅ Use kebab-case and distinct names
inputs:
github-token:
manage-token:
```

Reserved prefixes: `GITHUB_*`, `ACTIONS_*`, `RUNNER_*`.
144 changes: 137 additions & 7 deletions .claude/commands/gha.md
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,28 @@ jobs:

---

## Runner

All jobs in reusable workflows must use `blacksmith-4vcpu-ubuntu-2404` as the runner:

```yaml
jobs:
build:
runs-on: blacksmith-4vcpu-ubuntu-2404 # ✅ required runner
# ...

deploy:
runs-on: blacksmith-4vcpu-ubuntu-2404 # ✅ required runner
# ...
```

```yaml
# ❌ Never use other runners
runs-on: ubuntu-latest
runs-on: ubuntu-22.04
runs-on: self-hosted
```

## Workflow structure

Every reusable workflow must:
Expand Down Expand Up @@ -231,6 +253,84 @@ on:
default: false
```

## Step section titles

When a job or composite has more than one logical group of steps, separate each group with a titled section comment:

```yaml
# ----------------- Security Scans -----------------
- name: Trivy Secret Scan
...

# ----------------- Docker Scout Analysis -----------------
- name: Docker Scout
...

# ----------------- PR Comment with Security Findings -----------------
- name: Post Results to PR
...
```

**Rules:**
- Format: `# ----------------- Title -----------------` (exact spacing, dashes on both sides)
- Add when there are 2+ logical groups of steps in the same job or composite
- Title must be short and action-oriented (e.g. "Build & Push", "Security Scans", "Notifications")
- Place the comment immediately before the first step of the group — no blank line between comment and step
- Single-group jobs with 2–3 tightly related steps do not need a title

## Configurability — three-layer defaults and overrides

Composites, reusable workflows, and callers each have a responsibility in the configurability chain. Follow this model to keep things flexible without requiring callers to know composite internals.

**Composite layer** — always define sensible defaults, never `required: true` for feature flags:

```yaml
inputs:
enable-recommendations:
description: Include Docker Scout recommendations in the PR comment
required: false
default: "true" # ✅ composite works standalone with no config
```

**Reusable workflow layer** — expose a matching input for every optional composite feature; pass it down explicitly:

```yaml
on:
workflow_call:
inputs:
enable_docker_scout:
description: Run Docker Scout vulnerability scan
required: false
type: boolean
default: true
enable_docker_scout_recommendations:
required: false
type: boolean
default: true

jobs:
scan:
steps:
- name: Docker Scout
if: inputs.enable_docker_scout # step-level gate — skip entire composite when disabled
uses: LerianStudio/github-actions-shared-workflows/src/security/docker-scout@v1.2.3
with:
enable-recommendations: ${{ inputs.enable_docker_scout_recommendations }}
```

**Rules:**
- Feature toggle `if:` conditions belong in the **reusable workflow** (step or job level), not inside the composite
- Input naming: workflow inputs → `snake_case`, composite inputs → `kebab-case`
- Composite defaults must be safe and sensible standalone; workflow defaults may be more opinionated

```
Caller repo Reusable workflow Composite
──────────────────────── ────────────────────────── ──────────────────────────
enable_docker_scout: false → if: inputs.enable_xxx → step is never reached
enable_docker_scout_ → enable-recommendations: → ${{ inputs.enable-
recommendations: false ${{ inputs.... }} recommendations }}
```

## dry_run pattern

| Mode | Goal | Log style |
Expand Down Expand Up @@ -262,12 +362,20 @@ on:

**Real run (`false`):** no extra `echo`, no debug flags, let failures surface via exit codes, one `::notice::` summary on success at most.

## Local path rule (critical)
## Composite action references (critical)

```yaml
uses: ./src/setup/setup-go # ✅ composite version matches workflow version
uses: LerianStudio/...@main # ❌ breaks versioning for callers on older tags
```
In reusable workflows (`workflow_call`), `uses: ./path` resolves to the **caller's workspace**, not this repository. This means `./src/...` only works when the caller IS this repo (i.e., `self-*` workflows).

- **Workflows called by external repos** — must use an external ref:
```yaml
uses: LerianStudio/github-actions-shared-workflows/src/notify/discord-release@v1.2.3 # ✅ pinned
uses: LerianStudio/github-actions-shared-workflows/src/notify/discord-release@develop # ⚠️ testing only
uses: ./src/notify/discord-release # ❌ resolves to caller's workspace, will fail
```
- **`self-*` workflows (internal only)** — local path for reusable workflow only:
```yaml
uses: ./.github/workflows/labels-sync.yml # ✅ caller is this repo
```

## Secrets management

Expand Down Expand Up @@ -353,8 +461,8 @@ runs:
jobs: # invalid — composites have steps, not jobs
build: ...

# ❌ External ref for composite inside a reusable workflow
uses: LerianStudio/github-actions-shared-workflows/src/setup-go@main
# ❌ Local path for composite in a workflow called by external repos
uses: ./src/setup-go # resolves to caller's workspace, not this repo

# ❌ Mutable ref on third-party actions
uses: some-action/tool@main
Expand Down Expand Up @@ -490,3 +598,25 @@ new-tool-category:
```

Never add `LerianStudio/*` actions to dependabot — pinned to `@main` intentionally.

## Reserved names — never use as secret, input, or env var

Never use GitHub's reserved prefixes for custom secrets, inputs, or env vars — they conflict with runtime variables and break jobs silently:

```yaml
# ❌ Reserved — GITHUB_TOKEN is injected automatically, cannot be a named secret
on:
workflow_call:
secrets:
GITHUB_TOKEN: # breaks callers
required: true

# ✅ Use a distinct name
on:
workflow_call:
secrets:
MANAGE_TOKEN:
required: false
```

Reserved prefixes (workflows and composites): `GITHUB_*`, `ACTIONS_*`, `RUNNER_*`.
Loading
Loading