From 5a32b57a4e89f451790ca31372ff38b166ebdeda Mon Sep 17 00:00:00 2001 From: Julien Cabillot Date: Tue, 16 Jun 2026 10:50:50 -0400 Subject: [PATCH] feat: init --- .gitea/workflows/docker-build.yaml | 56 ++++++++++++++++++++++++++++++ AGENTS.md | 39 +++++++++++++++++++++ Dockerfile | 21 +++++++++++ README.md | 27 +++++++++++++- renovate.json | 15 ++++++++ 5 files changed, 157 insertions(+), 1 deletion(-) create mode 100644 .gitea/workflows/docker-build.yaml create mode 100644 AGENTS.md create mode 100644 Dockerfile create mode 100644 renovate.json diff --git a/.gitea/workflows/docker-build.yaml b/.gitea/workflows/docker-build.yaml new file mode 100644 index 0000000..e332720 --- /dev/null +++ b/.gitea/workflows/docker-build.yaml @@ -0,0 +1,56 @@ +name: Docker Build and Push + +on: + pull_request: + branches: [main] + push: + branches: [main] + schedule: + - cron: '0 0 * * *' + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 + with: + fetch-depth: 0 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4 + + - name: Login to Docker Hub + if: github.event_name != 'pull_request' + uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Docker metadata + id: meta + uses: docker/metadata-action@80c7e94dd9b9319bd5eb7a0e0fe9291e23a2a2e9 # v6 + with: + images: jcabillot/hermes-agent + tags: | + type=raw,value=latest,enable=${{ github.ref == 'refs/heads/main' }} + type=sha + + - name: Build and push + uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf # v7.2.0 + with: + context: . + push: ${{ github.event_name != 'pull_request' }} + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + pull: true + + - name: Bump version and push tag + if: github.event_name == 'push' && github.ref == 'refs/heads/main' + uses: anothrNick/github-tag-action@4ed44965e0db8dab2b466a16da04aec3cc312fd8 # v1.75.0 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DEFAULT_BUMP: patch + RELEASE_BRANCHES: main + WITH_V: true + GIT_API_TAGGING: false diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..c43cdd6 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,39 @@ +# AGENTS.md + +## 1. Overview + +Container image definition for Hermes Agent with supplementary tooling, distributed via Docker Hub as `jcabillot/hermes-agent`. + +## 2. Folder Structure + +- `Dockerfile`: Multi-stage image build — starts from `nousresearch/hermes-agent`, installs `gnupg` and `jq`, drops privileges back to the base user. +- `.gitea/workflows/docker-build.yaml`: Gitea Actions pipeline — builds and pushes the image to Docker Hub on push to `main` and on a daily cron schedule. +- `renovate.json`: Regex-based custom manager that tracks upstream `nousresearch/hermes-agent` Docker tag updates and opens PRs automatically. +- `README.md`: Public-facing documentation (image usage, tags, build instructions). +- `AGENTS.md`: This file — contributor guide for AI agents. + +## 3. Core Behaviors & Patterns + +- **Build & Release**: The Dockerfile uses `ARG HERMES_AGENT_VERSION` pinned to a specific tag. On push to `main`, the CI pipeline builds with `docker build --pull`, tags the image as `latest` and `sha-`, pushes to `jcabillot/hermes-agent`, and auto-bumps the git tag (`patch`). A daily cron rebuild ensures the base image's latest security patches are pulled. +- **Dependency Tracking**: renovate.json uses a regex custom manager to scan `Dockerfile` for `ARG HERMES_AGENT_VERSION=v` and opens a PR when `nousresearch/hermes-agent` publishes a new Docker tag. Base image version is the single tracked dependency. +- **Security Posture**: The build runs as `root` only for `apt` operations, then drops to an unprivileged user (`UID/GID 10000`). The CI pipeline uses Docker Buildx with `pull: true` to ensure fresh base layers. +- **Tag Strategy**: Two tags produced — `latest` (floating, main branch) and `sha-` (immutable, per-commit). Rolling tags (branch names) are intentionally omitted to avoid ambiguity. + +## 4. Conventions + +- **Version Pinning**: Base image versions are pinned via `ARG` at the top of the Dockerfile, not hardcoded in `FROM`. The version is managed by renovate, not manually updated. +- **CI Secrets**: Three secrets required — `DOCKERHUB_USERNAME`, `DOCKERHUB_TOKEN`, `GITHUB_TOKEN`. The login step is skipped on pull request events to prevent credential exposure from forks. +- **Dockerfile Style**: `apt-get` operations run in a single `RUN` layer with cleanup (`rm -rf /var/lib/apt/lists/*`). Comments annotate user context transitions. Hadolint ignores pinned with inline comments. +- **Pin Hashing**: All GitHub Action versions in the pipeline are pinned to commit SHA hashes with the semantic version in a trailing comment. + +## 5. Working Agreements + +- Respond in the user's preferred language (French or English); keep technical terms in English, never translate code blocks +- Create tests/lint only when explicitly requested +- Build context by reviewing related usages and patterns before editing +- Prefer simple solutions; avoid unnecessary abstraction +- Ask for clarification when requirements are ambiguous +- Make minimal changes; preserve public APIs and behavior +- Run type-check after code changes (no type-checker in this project — skip) +- New files: single-purpose, colocated with related concerns +- External dependencies: only when necessary, explain why diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..1c28c62 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,21 @@ +# Base image (nousresearch/hermes-agent) already ships with: +# git, curl, ripgrep, docker-cli, openssh-client, python3-dev, +# gcc, ffmpeg, node 22, npm, procps, xz-utils, s6-overlay. + +ARG HERMES_AGENT_VERSION=v2026.6.5 +FROM nousresearch/hermes-agent:${HERMES_AGENT_VERSION} + +USER root + +# Install system packages and HashiCorp repo +# hadolint ignore=DL3008 +RUN apt-get update -qq && apt-get upgrade -qq --yes --no-install-recommends \ + gnupg \ + jq \ + && apt-get -qq --yes autoremove --purge \ + && rm -rf /var/lib/apt/lists/* + +# Drop back to the base image's default user +ARG HERMES_UID=10000 +ARG HERMES_GID=10000 +USER ${HERMES_UID}:${HERMES_GID} diff --git a/README.md b/README.md index 45dd341..05836a2 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,28 @@ # hermes-agent -Hermes Agent container image \ No newline at end of file +Container image for [Hermes Agent](https://github.com/NousResearch/hermes-agent) with additional tooling. + +## Image + +`jcabillot/hermes-agent` — [Docker Hub](https://hub.docker.com/r/jcabillot/hermes-agent) + +Based on `nousresearch/hermes-agent` with `gnupg` and `jq` added. + +## Usage + +```bash +docker pull jcabillot/hermes-agent +``` + +## Build locally + +```bash +docker build -t jcabillot/hermes-agent . +``` + +## Tags + +| Tag | Description | +|-----|-------------| +| `latest` | Latest stable build from `main` | +| `sha-` | Per-commit build | diff --git a/renovate.json b/renovate.json new file mode 100644 index 0000000..2a01871 --- /dev/null +++ b/renovate.json @@ -0,0 +1,15 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "customManagers": [ + { + "customType": "regex", + "description": "Track nousresearch/hermes-agent Docker tag pinned in Dockerfile ARG", + "managerFilePatterns": ["/^Dockerfile$/"], + "matchStrings": ["ARG HERMES_AGENT_VERSION=v(?[^\\s]+)"], + "depNameTemplate": "nousresearch/hermes-agent", + "datasourceTemplate": "docker", + "versioningTemplate": "docker", + "extractVersionTemplate": "v^(?.*)$" + } + ] +}