diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4c5f206 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.claude/ diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..e1e4299 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,93 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Repository Overview + +This is a collection of reusable GitLab CI templates for Unbound Software projects. These templates are designed to be included in other projects' `.gitlab-ci.yml` files to provide standardized CI/CD workflows. + +## Architecture + +### Template Files + +- **Defaults.gitlab-ci.yml**: Default retry configuration for all jobs (handles runner failures, timeouts, etc.) +- **Pre-Commit-Go.gitlab-ci.yml**: Pre-commit job for Go projects using `unbound/pre-commit` Docker image +- **Pre-Commit-Node.gitlab-ci.yml**: Pre-commit job for Node.js projects using `unbound/pre-commit-node` Docker image +- **Release.gitlab-ci.yml**: Automated release management using git-cliff for changelog generation and version bumping + +### Release Pipeline Workflow + +The Release template implements a sophisticated automated release workflow: + +1. **unbound_release_preconditions_failed**: Validates that `UNBOUND_RELEASE_TOKEN` is set +2. **unbound_release_changelog**: Generates changelog using git-cliff and bumps version +3. **unbound_release_handle_mr**: Creates or updates a "next-release" branch and merge request with CHANGELOG.md and .version file +4. **unbound_release_prepare_release**: Prepares release artifacts (CHANGES.md, VERSION) +5. **unbound_release_create_release**: Creates GitLab release (when `UNBOUND_RELEASE_TAG_ONLY != "true"`) +6. **unbound_release_tag**: Creates git tag only (when `UNBOUND_RELEASE_TAG_ONLY == "true"`) + +### Key Environment Variables + +- `UNBOUND_RELEASE_TOKEN`: Personal/Project/Group Access Token with API access (required for release pipeline) +- `UNBOUND_RELEASE_TAG_ONLY`: Set to "true" to only create tags without full releases +- `CI_DEFAULT_BRANCH`: The default branch (usually "main") where releases are created +- `GOPRIVATE`: Set to `gitlab.com/unboundsoftware` in Go pre-commit template for private Go modules +- `PRE_COMMIT_HOME`: Cache directory for pre-commit hooks + +## Docker Images + +All images use SHA256 pinning for reproducibility and security: + +- `unbound/pre-commit:v0.3.5` - Go pre-commit environment +- `unbound/pre-commit-node:v0.0.23` - Node.js pre-commit environment +- `orhunp/git-cliff:2.10.1` - Changelog generation tool +- `amd64/alpine:3.22.2` - Lightweight base for shell scripts + +## Modifying Templates + +When editing templates: + +1. Ensure Docker image references include both version tags and SHA256 digests +2. Test changes by including the modified template in a test project's `.gitlab-ci.yml` +3. Release pipeline jobs should maintain backward compatibility or increment major version +4. Pre-commit templates should cache `PRE_COMMIT_HOME` for performance + +## Common Patterns + +### Including Templates in Projects + +Projects typically include these templates in their `.gitlab-ci.yml`: + +```yaml +include: + - project: 'unboundsoftware/ci-templates' + ref: main + file: 'Defaults.gitlab-ci.yml' + - project: 'unboundsoftware/ci-templates' + ref: main + file: 'Pre-Commit-Go.gitlab-ci.yml' + - project: 'unboundsoftware/ci-templates' + ref: main + file: 'Release.gitlab-ci.yml' +``` + +### Version Management + +- Version bumping follows conventional commits via git-cliff +- `.version` file stores current version as JSON: `{"version":"1.2.3"}` +- `CHANGELOG.md` is automatically maintained with full history +- `CHANGES.md` contains only the latest/unreleased changes + +### Authentication + +- Pre-commit Go template uses GitLab CI token for private Go module access via `.netrc` +- Release jobs use `UNBOUND_RELEASE_TOKEN` for API operations (creating MRs, releases, tags) + +## Testing Changes + +Since this repository contains templates only (no executable code), testing requires: + +1. Create a test project or use an existing project +2. Point the include reference to your branch: `ref: your-feature-branch` +3. Trigger the relevant pipeline in the consuming project +4. Verify job behavior and outputs