Skip to content

Commit ae18ccb

Browse files
authored
Merge pull request #22 from generalui/feat/ai-rules-and-contributing-docs
docs: add AI rules files and contributor documentation
2 parents 9fa11ae + 59c3970 commit ae18ccb

File tree

13 files changed

+525
-2
lines changed

13 files changed

+525
-2
lines changed

.cursorrules

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
CLAUDE.md

.github/copilot-instructions.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../CLAUDE.md

CLAUDE.md

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
# CLAUDE.md — AI Assistant Context
2+
3+
This file provides context for AI coding assistants (Claude, Cursor, GitHub Copilot).
4+
For full documentation, see the [`documentation/`](./documentation/) directory.
5+
6+
## What This Repository Is
7+
8+
A mono-repo of reusable [composite GitHub Actions](https://docs.github.com/en/actions/creating-actions/creating-a-composite-action)
9+
used across GenUI's CI/CD pipelines. All actions are composite actions (YAML + shell scripts) —
10+
not Docker or JavaScript actions.
11+
12+
Consumers reference actions via:
13+
14+
```yaml
15+
uses: generalui/github-workflow-accelerators/.github/actions/{action-name}@{version-tag}
16+
```
17+
18+
## Repository Structure
19+
20+
```text
21+
.github/
22+
actions/
23+
{action-name}/
24+
action.yml # Composite action definition
25+
project.json # Version — MUST be bumped on every change to this action
26+
README.md # Action documentation
27+
scripts/ # Shell scripts invoked by action.yml
28+
workflows/
29+
code-quality.yml # PR gate: markdownlint + per-action bats tests
30+
create-release.yml # Auto-releases on merge to main
31+
tests/
32+
unit/
33+
{action-name}/ # bats tests for that action's shell scripts
34+
helpers/
35+
mock_helpers.bash # Shared mock utilities
36+
documentation/ # Contributor and DevOps guides
37+
```
38+
39+
## Critical: Versioning Contract
40+
41+
**Every change to an action requires a `project.json` version bump. No exceptions.**
42+
43+
- Patch (1.0.0 → 1.0.1): bug fixes, dependency updates, documentation, refactors
44+
- Minor (1.0.0 → 1.1.0): new optional inputs, backwards-compatible features
45+
- Major (1.0.0 → 2.0.0): breaking changes to inputs or outputs
46+
47+
Skipping the version bump causes `create-release.yml` to fail on merge to `main` with a
48+
"tag already exists" error.
49+
50+
See [UPDATING_AN_ACTION.md](./documentation/UPDATING_AN_ACTION.md).
51+
52+
## CI vs Release Triggers
53+
54+
**`code-quality.yml`** (PR gate) — runs on PRs to `main`:
55+
56+
- Markdownlint: fires when any `**/*.md` file changes
57+
- bats tests: fires per-action when files in `.github/actions/{name}/` or `tests/unit/{name}/` change
58+
- To add a new testable action, add its name to the `actions_with_tests` array in `code-quality.yml`
59+
60+
**`create-release.yml`** (release) — runs on push to `main`:
61+
62+
- Reads `project.json` from each changed action directory
63+
- Ignores: `documentation/`, `tests/`, `*.md`, `.github/workflows/`, config files
64+
- Creates tag `{version}-{action-name}` and GitHub Release per changed action
65+
66+
See [DEVOPS.md](./documentation/DEVOPS.md), [CODE_QUALITY.md](./documentation/CODE_QUALITY.md),
67+
and [CREATE_RELEASE.md](./documentation/CREATE_RELEASE.md).
68+
69+
## Adding or Modifying Actions
70+
71+
- **Adding**: [ADDING_AN_ACTION.md](./documentation/ADDING_AN_ACTION.md)
72+
- **Modifying**: [UPDATING_AN_ACTION.md](./documentation/UPDATING_AN_ACTION.md)
73+
- **Testing**: [WRITING_TESTS.md](./documentation/WRITING_TESTS.md)
74+
- **Contributing**: [CONTRIBUTING.md](./documentation/CONTRIBUTING.md)
75+
76+
## Key Conventions
77+
78+
- `main` is protected — all changes via PR; direct commits are blocked
79+
- Shell scripts: `#!/usr/bin/env bash`, inputs passed via env vars not positional args
80+
- Tests: bats, `REPO_ROOT="$(cd "$BATS_TEST_DIRNAME/../../.." && pwd)"` (3 levels deep)
81+
- Internal action references are pinned to a specific release tag
82+
- New actions start at version `1.0.0`

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ This repo hold various accelerators for Github workflows (Actions) as well as re
2323

2424
## Contributing
2525

26+
See [documentation/CONTRIBUTING.md](./documentation/CONTRIBUTING.md) for the full contributor guide, including
27+
how to add or update actions, write tests, and understand the CI/CD workflows.
28+
2629
### Linting and Formatting
2730

2831
See [documentation/LINTING.md](./documentation/LINTING.md) for more information.

documentation/ADDING_AN_ACTION.md

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
# Adding an Action
2+
3+
This guide covers how to add a new reusable composite action to this repository.
4+
5+
## Directory Structure
6+
7+
Each action lives in its own directory under `.github/actions/`:
8+
9+
```text
10+
.github/actions/{action-name}/
11+
├── action.yml # Composite action definition (required)
12+
├── project.json # Version metadata (required)
13+
├── README.md # Action documentation (required)
14+
└── scripts/ # Shell scripts invoked by action.yml (if needed)
15+
└── {script}.sh
16+
```
17+
18+
## Step-by-Step
19+
20+
### 1. Create the action directory
21+
22+
Use kebab-case for the directory name. It becomes part of the version tag and the consumer's `uses:` reference.
23+
24+
```sh
25+
mkdir -p .github/actions/my-new-action/scripts
26+
```
27+
28+
### 2. Create `action.yml`
29+
30+
Refer to the [GitHub documentation on creating actions](https://docs.github.com/en/actions/sharing-automations/creating-actions)
31+
for the full `action.yml` syntax. Any action type is supported.
32+
33+
Two conventions specific to this repo:
34+
35+
- Reference internal actions (e.g. `configure-aws`) by pinning to a release tag:
36+
`uses: generalui/github-workflow-accelerators/.github/actions/configure-aws@{tag}`
37+
- When invoking shell scripts, pass inputs via environment variables rather than
38+
positional arguments — it keeps the script interface explicit and testable
39+
40+
### 3. Create `project.json`
41+
42+
Start at version `1.0.0`. This file is read by the release workflow to create a version tag on merge to `main`.
43+
44+
```json
45+
{
46+
"name": "my-new-action",
47+
"version": "1.0.0"
48+
}
49+
```
50+
51+
The `name` field must match the directory name exactly.
52+
53+
### 4. Create `README.md`
54+
55+
Document the action's inputs, outputs, and a usage example. See any existing action README for the expected format.
56+
57+
### 5. Write shell scripts (if applicable)
58+
59+
Place scripts in the `scripts/` directory. Follow the patterns established in existing scripts:
60+
61+
- Use `#!/usr/bin/env bash`
62+
- Guard required environment variables at the top before doing any work
63+
- Source `scripts/general/options_helpers.sh` if the script accepts CLI flags
64+
- Exit with code `1` on validation failure (makes testing straightforward)
65+
66+
### 6. Write tests (if the action contains testable shell scripts)
67+
68+
See [WRITING_TESTS.md](./WRITING_TESTS.md) for the full guide.
69+
70+
Then register the action in the `actions_with_tests` array in `.github/workflows/code-quality.yml`:
71+
72+
```yaml
73+
actions_with_tests=(
74+
"my-new-action"
75+
...
76+
)
77+
```
78+
79+
### 7. Open a pull request
80+
81+
The `code-quality.yml` PR gate will run markdownlint and, if registered, the bats test suite for your new action.
82+
83+
On merge to `main`, `create-release.yml` will automatically create a git tag `1.0.0-my-new-action` and a GitHub Release.
84+
85+
## Versioning
86+
87+
New actions always start at `1.0.0`. See [UPDATING_AN_ACTION.md](./UPDATING_AN_ACTION.md) for version bump rules when making subsequent changes.

documentation/CODE_QUALITY.md

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# Code Quality Workflow
2+
3+
The `code-quality.yml` workflow is the PR gate for this repository. It runs automatically on every pull request targeting `main`.
4+
5+
## What It Does
6+
7+
The workflow runs a single `quality` job with conditional steps:
8+
9+
1. **Detect changes** — uses `tj-actions/changed-files` to determine which files changed
10+
2. **Lint Markdown** — runs `markdownlint-cli2` if any `.md` files or the workflow file itself changed
11+
3. **Install bats** — installs the test runner if any action or test files changed
12+
4. **Per-action tests** — runs `bats tests/unit/{action-name}/` for each action whose files changed
13+
14+
Only the steps relevant to the PR's changes are executed, keeping runner time minimal.
15+
16+
## Triggering Conditions
17+
18+
| Step | Triggers when... |
19+
| ------ | ----------------- |
20+
| Lint Markdown | Any `**/*.md` file or `code-quality.yml` itself changed |
21+
| bats tests | Files changed in `.github/actions/{action-name}/` or `tests/unit/{action-name}/` |
22+
23+
## Per-Action Test Detection
24+
25+
The workflow maintains an explicit list of actions that have bats test suites:
26+
27+
```yaml
28+
actions_with_tests=(
29+
"promote-ecr-image"
30+
"test-python"
31+
"update-aws-ecs"
32+
"update-aws-lambda"
33+
)
34+
```
35+
36+
When adding a new action with testable shell scripts, add its name to this array. See [ADDING_AN_ACTION.md](./ADDING_AN_ACTION.md).
37+
38+
## Single-Job Design
39+
40+
All steps run sequentially in one job rather than as parallel matrix jobs. For fast-running bats suites, the overhead of spinning up multiple runners exceeds any parallelism benefit.
41+
42+
## Required Status Check
43+
44+
The `Quality` check produced by this workflow is a required status check on `main`. A PR cannot be merged until it passes.

documentation/CONTRIBUTING.md

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# Contributing
2+
3+
Thank you for contributing to GitHub Workflow Accelerators. This document is the starting point for contributors — human or AI.
4+
5+
## Prerequisites
6+
7+
- [bats-core](https://github.com/bats-core/bats-core) — for running shell script tests locally
8+
- [markdownlint-cli2](https://github.com/DavidAnson/markdownlint-cli2) — for linting markdown
9+
- [shellcheck](https://www.shellcheck.net/) — recommended for shell script authoring
10+
11+
See [LINTING.md](./LINTING.md) and [TESTING.md](./TESTING.md) for setup details.
12+
13+
## Guides
14+
15+
| Task | Document |
16+
| ------ | ---------- |
17+
| Add a new action | [ADDING_AN_ACTION.md](./ADDING_AN_ACTION.md) |
18+
| Modify an existing action | [UPDATING_AN_ACTION.md](./UPDATING_AN_ACTION.md) |
19+
| Write tests for shell scripts | [WRITING_TESTS.md](./WRITING_TESTS.md) |
20+
| Understand CI/CD workflows | [DEVOPS.md](./DEVOPS.md) |
21+
22+
## Branch and PR Conventions
23+
24+
- `main` is a protected branch — all changes must go through a pull request
25+
- Branch naming: `feat/`, `fix/`, `chore/` prefixes (e.g. `feat/add-notify-slack`)
26+
- Each PR should change only the action(s) it intends to change
27+
- PRs that change an action's files **must** include a `project.json` version bump — see [UPDATING_AN_ACTION.md](./UPDATING_AN_ACTION.md)
28+
29+
## Commit Messages
30+
31+
Use conventional commit prefixes:
32+
33+
- `feat:` — new action or new feature in an existing action
34+
- `fix:` — bug fix
35+
- `chore:` — dependency updates, version bumps, tooling changes
36+
- `docs:` — documentation only changes
37+
- `refactor:` — code changes that don't affect behaviour
38+
- `test:` — adding or updating tests
39+
40+
## Code Review
41+
42+
- The `code-quality.yml` PR gate must pass before merging
43+
- Markdownlint and bats tests run automatically for changed files — see [DEVOPS.md](./DEVOPS.md)

documentation/CREATE_RELEASE.md

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# Create Release Workflow
2+
3+
The `create-release.yml` workflow automatically creates versioned git tags and GitHub Releases when changes are merged to `main`.
4+
5+
## How It Works
6+
7+
1. **Detect changed files** — uses `tj-actions/changed-files` to identify which files changed in the push
8+
2. **Extract action paths** — parses changed file paths to identify which action directories were modified
9+
3. **Validate versions** — reads `project.json` from each changed action and verifies the version tag does not already exist
10+
4. **Tag and release** — for each changed action, creates a git tag and GitHub Release with an auto-generated changelog
11+
12+
## Version Tag Format
13+
14+
Tags follow the format `{version}-{action-name}`:
15+
16+
```text
17+
1.0.1-update-aws-ecs
18+
1.2.0-lint-test-yarn
19+
```
20+
21+
The changelog is generated from commit messages between the previous tag and the new one.
22+
23+
## What Triggers a Release
24+
25+
A push to `main` triggers a release for any action whose files changed **and** whose `project.json` version is higher than the most recent tag for that action.
26+
27+
If the version has not been bumped, the workflow fails with:
28+
29+
```text
30+
The tag {version}-{action-name} already exists,
31+
ensure you have incremented the version in project.json.
32+
```
33+
34+
Always bump `project.json` before merging. See [UPDATING_AN_ACTION.md](./UPDATING_AN_ACTION.md).
35+
36+
## What Does NOT Trigger a Release
37+
38+
The following paths are excluded from change detection:
39+
40+
| Path | Reason |
41+
| ------ | -------- |
42+
| `.github/workflows/create-release.yml` | Self-referential |
43+
| `.github/workflows/code-quality.yml` | Workflow-only change |
44+
| `.github/**/*.md` | Workflow documentation |
45+
| `documentation/**` | Documentation only |
46+
| `tests/**` | Test files only |
47+
| `*.md` | Root markdown files |
48+
| `.vscode/**` | Editor config |
49+
| `.gitignore`, `.markdownlint*`, `*.code-workspace` | Config files |
50+
51+
If you need to add a new top-level directory that should not trigger releases, add it to the `files_ignore` list in `create-release.yml`.
52+
53+
## Matrix Releases
54+
55+
If multiple actions change in a single merge, the workflow releases each one independently in parallel via a matrix strategy. Each action gets its own tag, changelog, and GitHub Release.

documentation/DEVOPS.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# DevOps
2+
3+
This document covers the CI/CD infrastructure for this repository.
4+
5+
## CI/CD Workflows
6+
7+
All workflows are defined in `.github/workflows/`.
8+
9+
| Workflow | Trigger | Purpose |
10+
| ---------- | --------- | --------- |
11+
| [`code-quality.yml`](./../.github/workflows/code-quality.yml) | PR to `main` | Linting and unit tests |
12+
| [`create-release.yml`](./../.github/workflows/create-release.yml) | Push to `main` | Version tagging and GitHub Releases |
13+
14+
### Code Quality
15+
16+
See [CODE_QUALITY.md](./CODE_QUALITY.md) for details on the PR gate workflow.
17+
18+
### Create Release
19+
20+
See [CREATE_RELEASE.md](./CREATE_RELEASE.md) for details on the release workflow.
21+
22+
## Branch Protection
23+
24+
The `main` branch is protected:
25+
26+
- All changes must be submitted via pull request
27+
- The `Quality` check (from `code-quality.yml`) must pass before merging
28+
- Direct commits to `main` are blocked
29+
30+
## Dependency Management
31+
32+
Actions in this repo reference specific versions of external GitHub Actions (e.g. `actions/checkout`).
33+
When new versions are released — particularly those resolving runtime deprecation warnings — the `action.yml`
34+
files and corresponding `project.json` versions should be updated. See [UPDATING_AN_ACTION.md](./UPDATING_AN_ACTION.md).

documentation/TESTING.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ tests/
3131
## What Is Tested
3232

3333
| Action | Script | Tests | What's covered |
34-
|--------|--------|-------|----------------|
34+
| -------- | -------- | ------- | ---------------- |
3535
| `promote-ecr-image` | `options_helpers.sh` | 15 | `has_argument()` and `extract_argument()` parsing logic |
3636
| `promote-ecr-image` | `aws_unset.sh` | 7 | All 4 AWS credential env vars are cleared; no-op when already unset |
3737
| `promote-ecr-image` | `promote_image.sh` | 13 | Every required env var validation (exits 1 for each missing var); `--help` |
@@ -93,6 +93,11 @@ and runs tests only for those actions — each in its own isolated job.
9393

9494
## Writing New Tests
9595

96+
For a full guide on writing new tests — including the mock pattern, exit code testing, and how to register
97+
a new action with CI — see [WRITING_TESTS.md](./WRITING_TESTS.md).
98+
99+
Quick reference:
100+
96101
1. Create `tests/unit/<action-name>/test_<script_name>.bats`.
97102
2. Set `REPO_ROOT` relative to `BATS_TEST_DIRNAME` — tests are three levels deep,
98103
so use: `REPO_ROOT="$(cd "$BATS_TEST_DIRNAME/../../.." && pwd)"`

0 commit comments

Comments
 (0)