Skip to content
Open
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
112 changes: 112 additions & 0 deletions .agents/skills/create-commit/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
---
name: create-commit
description: Follow the project's commit message conventions when making a git commit. Use this whenever you are about to run `git commit`.
---

# Create Commit

## Commit Message Rules

### COMMIT-1: Commit Messages

**RULE**: Commit messages should be loosely based on the rules of [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/) but without prefixes. Write a clear, concise summary of what the change does, starting with a lowercase verb in imperative mood.

**DO**:

```text
add the BucketAccess custom resource
fix the bucket deletion when Garage answers 409
remove the backend probes from the readiness check
update Garage to 2.4.1
rename the admin token key to admin_token
extract the Garage admin client into a factory
```

**DON'T**:

```text
// Incorrect - using conventional commit prefixes
feat: add the BucketAccess custom resource
fix: the bucket deletion when Garage answers 409
refactor: extract the Garage admin client into a factory

// Incorrect - not imperative mood
added the BucketAccess custom resource
adding the BucketAccess custom resource

// Incorrect - including ticket IDs
#123 add the BucketAccess custom resource
[#123] fix the bucket deletion when Garage answers 409

// Incorrect - vague or meaningless
fix bug
update code
changes
WIP

// Incorrect - too long, should be concise
fix the bucket deletion because Garage answers 409 instead of 400 for a bucket that still holds objects and the operator then reported a generic error that confused the administrators
```

### COMMIT-2: Commit Body Only When Necessary

**RULE**: Most commits have only the summary line. Add a body only when a human reader needs context that the summary
and the diff cannot give: the reason for a non-obvious decision, a constraint outside the code, or a consequence that
the reader would otherwise miss. Keep the body short: a few lines, not a list of every changed file or step.

**DON'T** repeat in the body what the diff already shows: which files changed, which methods were renamed, or a
step-by-step account of the work.

**DO**:

```text
address buckets and keys by their recorded id

Garage does not enforce unique key names, so a lookup by name could pick up
or delete a key that belongs to another AccessKey.
```

**DON'T**:

```text
update the AccessKey reconciler

- Changed AccessKeyReconciler.java
- Added findManagedAccessKey
- Renamed the cleanup variables
- Updated the imports
- Reformatted the file
```

### COMMIT-3: AI Attribution with `Assisted-by`

**RULE**: A commit that an AI agent wrote or helped to write ends with an `Assisted-by:` trailer in the format
`AGENT_NAME:MODEL_VERSION`, without spaces (e.g. `Claude:claude-opus-5-5`, `Junie:<model>`). Never use
`Co-Authored-By:` for an AI agent: that trailer is for human co-authors. This rule replaces any default attribution of
the agent.

**RATIONALE**: The format comes from the Linux kernel guide for AI coding assistants. The kernel changed it to
`Assisted-by: LLM` in Linux 7.3. This project keeps the agent and the model, because they tell a reviewer which agent
(Claude Code or Junie) and which model made the change.

**DO**:

```text
fix the bucket deletion when Garage answers 409

Assisted-by: Claude:claude-opus-5-5
```

```text
add the Secret watch to the AccessKey reconciler

Assisted-by: Junie:<model>
```

**DON'T**:

```text
fix the bucket deletion when Garage answers 409

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
```
1 change: 1 addition & 0 deletions .claude/skills
5 changes: 5 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
*
!build/*-runner
!build/*-runner.jar
!build/lib/*
!build/quarkus-app/*
21 changes: 21 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
root = true

[*]
charset = utf-8
end_of_line = lf
indent_size = 4
indent_style = space
insert_final_newline = true
max_line_length = 120
tab_width = 4
ij_continuation_indent_size = 8

[{*.yml,*.yaml}]
indent_size = 2

[*.md]
max_line_length = off
indent_size = 2

[Makefile*]
indent_style = tab
9 changes: 9 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Line endings: store LF in the repository and check out LF on every platform.
# Git detects binary files itself through text=auto. The entries below are the exceptions.
* text=auto eol=lf

# Windows batch files need CRLF in the working tree.
*.bat text eol=crlf

# Binary files
*.jar binary
6 changes: 6 additions & 0 deletions .githooks/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/bash

set -e
set -o pipefail

./gradlew --console=colored checkstyleMain checkstyleTest
18 changes: 18 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: Test

on:
push:
branches:
- main
pull_request:
types: [ opened, reopened, synchronize ]

concurrency:
group: ${{ github.ref }}
cancel-in-progress: true

jobs:
test:
name: Tests
uses: ./.github/workflows/test.yml
secrets: inherit
105 changes: 105 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
name: Release

on:
workflow_dispatch:
inputs:
increment:
description: "Version increment type"
type: choice
required: true
default: "Patch"
options:
- "Major"
- "Minor"
- "Patch"
- "Prerelease"

env:
DOCKER_IMAGE: ghcr.io/${{ github.repository }}

jobs:
test:
uses: ./.github/workflows/test.yml
secrets: inherit

build-and-release:
needs: test
runs-on: ubuntu-24.04
timeout-minutes: 5
steps:
- uses: actions/checkout@v6
with:
token: ${{ secrets.GH_PERSONAL_ACCESS_TOKEN }}
- uses: aboutbits/github-actions-base/git-setup@v2
- uses: aboutbits/github-actions-java/setup-with-gradle@v4
with:
java-version: 25
cache-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }}
- name: Increment version
run: ./gradlew --console=colored createRelease -Prelease.versionIncrementer=increment${{ github.event.inputs.increment }}
shell: bash
- name: Get next package version
id: nextVersion
run: echo "version=$(./gradlew currentVersion -q -Prelease.quiet)" >> $GITHUB_OUTPUT
shell: bash
- name: Build package
run: ./gradlew --console=colored build -x test
env:
GITHUB_USER_NAME: ${{ github.actor }}
GITHUB_ACCESS_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- uses: aboutbits/github-actions-docker/build-push@v1
with:
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
docker-image: ${{ env.DOCKER_IMAGE }}
docker-tag: ${{ steps.nextVersion.outputs.version }}
working-directory: './operator'
dockerfile: './operator/src/main/docker/Dockerfile.jvm'
- name: Push tag to remote
run: ./gradlew --console=colored pushRelease
shell: bash
- uses: aboutbits/github-actions-base/github-create-release@v2
with:
tag-name: 'v${{ steps.nextVersion.outputs.version }}'
release-description: |
## Installation

### Helm Chart
```bash
helm install garage-operator https://github.com/${{ github.repository }}/releases/download/v${{ steps.nextVersion.outputs.version }}/garage-operator-${{ steps.nextVersion.outputs.version }}.tgz
```

With the Helm chart, the Custom Resource Definitions (CRDs) are installed automatically.
However, if you deploy the operator directly from the OCI image, the CRDs are not automatically applied and must be installed separately.

### Manual CRD Installation

The CRD manifests are attached to this release as `*.garage.aboutbits.it-v1.yml` assets and can be applied directly, for example:
```bash
kubectl apply -f https://github.com/${{ github.repository }}/releases/download/v${{ steps.nextVersion.outputs.version }}/garageclusters.garage.aboutbits.it-v1.yml
```

## Upgrading

Helm never upgrades CRDs, so apply the CRDs of this release **before** upgrading the chart:
```bash
for crd in garageclusters s3connections buckets accesskeys bucketaccesses; do
kubectl apply --server-side --force-conflicts -f https://github.com/${{ github.repository }}/releases/download/v${{ steps.nextVersion.outputs.version }}/${crd}.garage.aboutbits.it-v1.yml
done

helm upgrade garage-operator https://github.com/${{ github.repository }}/releases/download/v${{ steps.nextVersion.outputs.version }}/garage-operator-${{ steps.nextVersion.outputs.version }}.tgz
```
release-notes-generation: 'true'
- name: Upload Helm chart and CRD assets
env:
GH_TOKEN: ${{ secrets.GH_PERSONAL_ACCESS_TOKEN }}
run: |
gh release upload v${{ steps.nextVersion.outputs.version }} operator/build/helm/kubernetes/garage-operator-${{ steps.nextVersion.outputs.version }}.tgz operator/build/kubernetes/*.garage.aboutbits.it-v1.yml
shell: bash
- name: Update readme.md
run: |
sed -i "s|releases/download/v[0-9.]*/garage-operator-[0-9.]*.tgz|releases/download/v${{ steps.nextVersion.outputs.version }}/garage-operator-${{ steps.nextVersion.outputs.version }}.tgz|g" readme.md
git add readme.md
git diff-index --quiet HEAD || git commit -m "update readme.md with version ${{ steps.nextVersion.outputs.version }}"
git push
shell: bash
25 changes: 25 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: Tests

on:
workflow_call:

jobs:
test:
name: Tests
runs-on: ubuntu-24.04
timeout-minutes: 10
steps:
- uses: actions/checkout@v6
- uses: aboutbits/github-actions-java/setup-with-gradle@v4
with:
java-version: 25
cache-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }}
- name: Build & Test
run: >-
./gradlew
--console=colored
:operator:test
--fail-fast
env:
GITHUB_USER_NAME: ${{ github.actor }}
GITHUB_ACCESS_TOKEN: ${{ secrets.GITHUB_TOKEN }}
67 changes: 67 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
### Garage Operator ###
config/
# The kubectl cache of the Dev Services cluster
operator/.kube/
.rumdl_cache/
.claude/settings.local.json
.claude/worktrees/

### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache

### IntelliJ IDEA ###
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
.idea/*
!.idea/codeStyles
!.idea/.gitignore
!.idea/checkstyle-idea.xml
!.idea/encodings.xml
!.idea/misc.xml
!.idea/sqldialects.xml
!.idea/vcs.xml

*.iml
*.ipr
*.iws

### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/

### VS Code ###
.vscode/

### Mac ###
.DS_Store

### Gradle ###
# Reference: https://github.com/github/gitignore/blob/main/Gradle.gitignore
.gradle
**/build/
!**/src/**/build/
gradle-app.setting
!gradle-wrapper.jar
!gradle-wrapper.properties
.gradletasknamecache

### Quarkus ###
# Local environment
.env

# Plugin directory
/.quarkus/cli/plugins/

# Quinoa
.quinoa/
10 changes: 10 additions & 0 deletions .idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading