mirror of
https://github.com/Brodino96/webkit2gtk-automator.git
synced 2026-05-05 22:29:57 +02:00
feat: asked claude sonnet 4.6 to rework as github workflow instead of on my machine
This commit is contained in:
@@ -0,0 +1,284 @@
|
||||
# AGENTS.md — webkit2gtk-automator
|
||||
|
||||
This file provides guidance for agentic coding agents working in this repository.
|
||||
|
||||
---
|
||||
|
||||
## Project Overview
|
||||
|
||||
This project is a Bash/Docker automation daemon that:
|
||||
1. Polls the AUR RPC API for new `webkit2gtk` releases
|
||||
2. Builds the package using `makepkg` inside an Arch Linux container
|
||||
3. Publishes the resulting `.pkg.tar.zst` artifact to GitHub Releases
|
||||
4. Generates and pushes an updated `webkit2gtk-bin` PKGBUILD to the AUR
|
||||
|
||||
The entire codebase is Bash scripts orchestrated via Docker Compose. There is no application framework, no package manager (npm/pip/cargo), and no test suite.
|
||||
|
||||
---
|
||||
|
||||
## Repository Structure
|
||||
|
||||
```
|
||||
webkit2gtk-automator/
|
||||
├── .env.example # Template for required environment variables
|
||||
├── .gitignore
|
||||
├── Dockerfile # Arch Linux image with build dependencies
|
||||
├── docker-compose.yml # Defines the "builder" service
|
||||
├── README.md
|
||||
└── scripts/
|
||||
├── entrypoint.sh # Container entrypoint; polling loop
|
||||
├── check-update.sh # AUR API poll; triggers build + publish if new version
|
||||
├── build.sh # Runs makepkg; collects .pkg.tar.zst artifacts
|
||||
└── publish.sh # Uploads to GitHub Releases; pushes PKGBUILD to AUR
|
||||
```
|
||||
|
||||
Runtime-generated (gitignored):
|
||||
- `state/last_version` — tracks last published version
|
||||
- `state/artifacts/` — holds built `.pkg.tar.zst` files
|
||||
- `webkit2gtk/` — AUR source package clone
|
||||
- `webkit2gtk-bin/` — AUR binary package clone
|
||||
|
||||
---
|
||||
|
||||
## Environment Setup
|
||||
|
||||
Copy `.env.example` to `.env` and fill in all required values before starting:
|
||||
|
||||
```bash
|
||||
cp .env.example .env
|
||||
# Edit .env with your GITHUB_TOKEN, AUR SSH key path, GPG key, etc.
|
||||
```
|
||||
|
||||
All scripts validate required variables at startup using the pattern:
|
||||
```bash
|
||||
: "${GITHUB_TOKEN:?GITHUB_TOKEN is not set}"
|
||||
```
|
||||
Missing variables cause an immediate exit with a descriptive error.
|
||||
|
||||
---
|
||||
|
||||
## Build / Run Commands
|
||||
|
||||
| Purpose | Command |
|
||||
|---|---|
|
||||
| Start the daemon (detached) | `docker compose up -d` |
|
||||
| Start and rebuild the image | `docker compose up -d --build` |
|
||||
| Watch live logs | `docker compose logs -f` |
|
||||
| Stop the daemon | `docker compose down` |
|
||||
| Force a rebuild on next poll | `rm state/last_version && docker compose restart` |
|
||||
|
||||
---
|
||||
|
||||
## Running a Single Script
|
||||
|
||||
There is no test runner. To manually invoke a single script inside the container:
|
||||
|
||||
```bash
|
||||
# Run check-update.sh (polls AUR and triggers build+publish if needed)
|
||||
docker compose run --rm builder bash -c "source /workspace/.env && /workspace/scripts/check-update.sh"
|
||||
|
||||
# Run build.sh directly
|
||||
docker compose run --rm builder bash -c "source /workspace/.env && /workspace/scripts/build.sh"
|
||||
|
||||
# Run publish.sh directly
|
||||
docker compose run --rm builder bash -c "source /workspace/.env && /workspace/scripts/publish.sh"
|
||||
```
|
||||
|
||||
To test publish without recompiling, pre-place an artifact in `state/artifacts/`:
|
||||
```bash
|
||||
# build.sh detects existing artifact and skips makepkg
|
||||
cp some-existing.pkg.tar.zst state/artifacts/
|
||||
docker compose run --rm builder bash -c "source /workspace/.env && /workspace/scripts/publish.sh"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## No Test Suite
|
||||
|
||||
There are no unit tests, integration tests, or test commands. Manual invocation of
|
||||
individual scripts (see above) is the primary validation mechanism.
|
||||
|
||||
---
|
||||
|
||||
## Code Style Guidelines
|
||||
|
||||
### Shebang and Strict Mode
|
||||
|
||||
Every script **must** begin with:
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
```
|
||||
- `set -e` — exit immediately on any non-zero return code
|
||||
- `set -u` — treat unset variables as errors
|
||||
- `set -o pipefail` — propagate errors through pipelines
|
||||
|
||||
### Variable Naming
|
||||
|
||||
| Scope | Convention | Example |
|
||||
|---|---|---|
|
||||
| All variables (env or local) | `UPPER_SNAKE_CASE` | `PKG_VERSION`, `BUILD_DIR` |
|
||||
| Functions | `snake_case` | `log`, `die`, `check_deps` |
|
||||
| Script files | `kebab-case.sh` | `check-update.sh`, `build.sh` |
|
||||
|
||||
### Quoting
|
||||
|
||||
Always double-quote variable expansions. Use `${VAR}` brace syntax:
|
||||
```bash
|
||||
# Correct
|
||||
cp "${SRC_FILE}" "${DEST_DIR}/"
|
||||
echo "Version: ${PKG_VERSION}"
|
||||
|
||||
# Wrong — never do this
|
||||
cp $SRC_FILE $DEST_DIR/
|
||||
```
|
||||
|
||||
### Sourcing Files
|
||||
|
||||
Use `source` (not the POSIX `.` shorthand):
|
||||
```bash
|
||||
# Correct
|
||||
source /workspace/.env
|
||||
|
||||
# Avoid
|
||||
. /workspace/.env
|
||||
```
|
||||
|
||||
To auto-export all variables from a sourced file:
|
||||
```bash
|
||||
set -a
|
||||
source /workspace/.env
|
||||
set +a
|
||||
```
|
||||
|
||||
### Logging
|
||||
|
||||
Every script defines a `log()` function with a consistent timestamp prefix:
|
||||
```bash
|
||||
log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] [script-name] $*"; }
|
||||
```
|
||||
Use `log` for all informational output. Use `log "ERROR: ..." >&2` (or `die`) for errors.
|
||||
|
||||
### Arrays
|
||||
|
||||
Use Bash arrays when collecting multiple items:
|
||||
```bash
|
||||
packages=()
|
||||
packages+=("${pkg_file}")
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Error Handling Conventions
|
||||
|
||||
### Required Variable Checks
|
||||
|
||||
Use Bash parameter expansion to validate required env vars:
|
||||
```bash
|
||||
: "${GITHUB_TOKEN:?GITHUB_TOKEN is not set}"
|
||||
: "${AUR_SSH_KEY:?AUR_SSH_KEY is not set}"
|
||||
```
|
||||
|
||||
### `die()` Helper
|
||||
|
||||
Define and use a `die()` function for fatal errors:
|
||||
```bash
|
||||
die() {
|
||||
log "ERROR: $*" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Usage
|
||||
[[ -f "${pkg_file}" ]] || die "Expected artifact not found: ${pkg_file}"
|
||||
```
|
||||
|
||||
### Explicit Guard Blocks
|
||||
|
||||
Prefer explicit `if/else` over bare command calls for critical steps:
|
||||
```bash
|
||||
if "${SCRIPT_DIR}/build.sh"; then
|
||||
log "Build succeeded"
|
||||
else
|
||||
log "ERROR: Build failed, aborting"
|
||||
exit 1
|
||||
fi
|
||||
```
|
||||
|
||||
### Null/Empty API Response Checks
|
||||
|
||||
Always validate outputs from `curl | jq` pipelines:
|
||||
```bash
|
||||
aur_version=$(curl -s "${AUR_API_URL}" | jq -r '.results[0].Version')
|
||||
if [[ -z "${aur_version}" || "${aur_version}" == "null" ]]; then
|
||||
log "ERROR: Failed to parse version from AUR response"
|
||||
exit 1
|
||||
fi
|
||||
```
|
||||
|
||||
### Graceful No-Op
|
||||
|
||||
For idempotent operations (e.g., git commit), allow the no-op case:
|
||||
```bash
|
||||
git commit -m "Update to ${FULL_VERSION}" || {
|
||||
log "Nothing to commit, already at ${FULL_VERSION}"
|
||||
exit 0
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## External Tool Dependencies
|
||||
|
||||
These CLI tools are invoked directly by the scripts. They must be present in the container:
|
||||
|
||||
| Tool | Purpose |
|
||||
|---|---|
|
||||
| `curl` | HTTP requests to AUR RPC API |
|
||||
| `jq` | JSON parsing of AUR API responses |
|
||||
| `makepkg` | Arch Linux package build tool |
|
||||
| `gh` | GitHub CLI — creating releases and uploading assets |
|
||||
| `git` | Cloning/pulling AUR repos, committing, pushing |
|
||||
| `gpg` | Verifying PGP signatures on source tarballs |
|
||||
| `sha256sum` | Computing checksums for the artifact |
|
||||
| `bsdtar` | Extracting the `.pkg.tar.zst` in the generated PKGBUILD |
|
||||
| `sudo` | Dropping privileges from root to `builduser` for `makepkg` |
|
||||
| `ssh` | AUR authentication via SSH key |
|
||||
|
||||
All of these are installed in the `Dockerfile`. If adding a new dependency, add it there.
|
||||
|
||||
---
|
||||
|
||||
## Dockerfile and docker-compose.yml
|
||||
|
||||
- The base image is Arch Linux. Keep it updated with `pacman -Syu` in the `Dockerfile`.
|
||||
- The container runs as root but drops to a `builduser` account for `makepkg` (which
|
||||
refuses to run as root).
|
||||
- Secrets (`.env`, SSH keys, GPG keys) are mounted at runtime via volume mounts defined
|
||||
in `docker-compose.yml`. Never bake secrets into the image.
|
||||
|
||||
---
|
||||
|
||||
## ShellCheck
|
||||
|
||||
ShellCheck is the recommended linter for Bash scripts. It is not formally enforced (no
|
||||
`.shellcheckrc` or CI step), but inline directives are already used in the codebase
|
||||
(e.g., `# shellcheck source=/dev/null`). When editing scripts, run ShellCheck locally:
|
||||
|
||||
```bash
|
||||
shellcheck scripts/*.sh
|
||||
```
|
||||
|
||||
Fix all warnings before committing. Use inline directives sparingly and only with a
|
||||
comment explaining why the suppression is necessary.
|
||||
|
||||
---
|
||||
|
||||
## Adding a New Script
|
||||
|
||||
1. Create the file as `scripts/kebab-case-name.sh`
|
||||
2. Start with `#!/usr/bin/env bash` and `set -euo pipefail`
|
||||
3. Define a `log()` function matching the pattern above
|
||||
4. Validate all required env vars with `: "${VAR:?...}"`
|
||||
5. Define a `die()` helper for fatal errors
|
||||
6. Make it executable: `chmod +x scripts/kebab-case-name.sh`
|
||||
7. If it needs to run inside the container, invoke it via `docker compose run --rm builder`
|
||||
Reference in New Issue
Block a user