Skip to content
Merged
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
5 changes: 2 additions & 3 deletions .gemini/styleguide.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,8 @@

## CI
- Workflows MUST include weekly cron trigger for base image security updates
- Build caching is MANDATORY: `cache-from: type=gha` / `cache-to: type=gha,mode=max`
- Never use `no-cache: true` in CI workflows
- Dual-push (Quay + GHCR) uses two separate jobs, not steps
- Container builds go through `crunchtools/constitution/.github/workflows/container-release.yml`: build once per change, gate the digest, promote by `skopeo copy --all --preserve-digests`. Outside the repos listed in `container_release_custom` (profiles/requirements.toml), flag any job that publishes an image (`push`, `skopeo copy`, `docker/build-push-action` with push) or moves `:latest`/`:main`; a local build that is never pushed (an integration-test image) is fine. Everywhere, flag `imagetools create` and a `ghcr.io/crunchtools` reference
- Quay.io is the only registry

## Versioning
- Semantic Versioning 2.0.0
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/constitution.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@ permissions:
jobs:
constitution:
name: Constitution
uses: crunchtools/constitution/.github/workflows/validate.yml@v1.31.0
uses: crunchtools/constitution/.github/workflows/validate.yml@v1.39.1
131 changes: 19 additions & 112 deletions .github/workflows/container.yml
Original file line number Diff line number Diff line change
@@ -1,120 +1,27 @@
name: Container Build & Push

name: Container
on:
pull_request:
push:
branches: [main]
tags: ["v*"]
pull_request:
branches: [main]
schedule:
- cron: "17 5 * * 1"
workflow_dispatch:

env:
REGISTRY: quay.io
IMAGE_NAME: crunchtools/memory
GHCR_IMAGE: ghcr.io/crunchtools/memory

permissions: {}
jobs:
build-and-push-quay:
runs-on: ubuntu-latest
permissions:
contents: read

steps:
- name: Checkout repository
uses: actions/checkout@v7

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4

- name: Log in to Quay.io
if: github.event_name != 'pull_request'
uses: docker/login-action@v4
with:
registry: ${{ env.REGISTRY }}
username: ${{ secrets.QUAY_USERNAME }}
password: ${{ secrets.QUAY_PASSWORD }}

- name: Extract metadata (tags, labels)
id: meta
uses: docker/metadata-action@v6
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
# `latest` is the newest STABLE RELEASE, not the newest build of the
# branch, which has its own tag above (constitution 1.33.0, RT#1559).
# A prerelease is not what `latest` means, so it is excluded by the
# hyphen: SemVer puts every prerelease identifier after one.
type=raw,value=latest,enable=${{ github.ref_type == 'tag' && startsWith(github.ref_name, 'v') && !contains(github.ref_name, '-') }}

- name: Build and push container image
uses: docker/build-push-action@v7
with:
context: .
file: ./Containerfile
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max

- name: Run Trivy vulnerability scanner
continue-on-error: true
if: github.event_name != 'pull_request'
uses: aquasecurity/[email protected]
with:
image-ref: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.meta.outputs.version }}
format: "table"
exit-code: "0"
severity: "CRITICAL,HIGH"

build-and-push-ghcr:
runs-on: ubuntu-latest
needs: build-and-push-quay
if: github.event_name != 'pull_request'
container:
uses: crunchtools/constitution/.github/workflows/[email protected]
permissions:
contents: read
packages: write

steps:
- name: Checkout repository
uses: actions/checkout@v7

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4

- name: Log in to GitHub Container Registry
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ github.token }}

- name: Extract metadata (tags, labels)
id: meta
uses: docker/metadata-action@v6
with:
images: ${{ env.GHCR_IMAGE }}
tags: |
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
# `latest` is the newest STABLE RELEASE, not the newest build of the
# branch, which has its own tag above (constitution 1.33.0, RT#1559).
# A prerelease is not what `latest` means, so it is excluded by the
# hyphen: SemVer puts every prerelease identifier after one.
type=raw,value=latest,enable=${{ github.ref_type == 'tag' && startsWith(github.ref_name, 'v') && !contains(github.ref_name, '-') }}

- name: Build and push container image
uses: docker/build-push-action@v7
with:
context: .
file: ./Containerfile
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
pull-requests: read
with:
image: quay.io/crunchtools/memory
# The image's default CMD serves SSE on 0.0.0.0, which the server refuses
# without MCP_API_KEY and which the mcp-http profile cannot speak. Boot it
# over stdio (no transport flag) and require initialize + tools/list.
boot: mcp
boot-cmd: "--storage-backend sqlite_vec"
boot-timeout: 240
secrets:
QUAY_USERNAME: ${{ secrets.QUAY_USERNAME }}
QUAY_PASSWORD: ${{ secrets.QUAY_PASSWORD }}
2 changes: 1 addition & 1 deletion .github/workflows/dependabot-automerge.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ permissions:
jobs:
automerge:
name: Dependabot
uses: crunchtools/constitution/.github/workflows/dependabot-automerge.yml@v1.31.0
uses: crunchtools/constitution/.github/workflows/dependabot-automerge.yml@v1.39.1
6 changes: 3 additions & 3 deletions .specify/memory/constitution.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
> **Version:** 1.0.1
> **Ratified:** 2026-10-02
> **Status:** Active
> **Inherits:** [crunchtools/constitution](https://github.com/crunchtools/constitution) v1.31.0
> **Inherits:** [crunchtools/constitution](https://github.com/crunchtools/constitution) v1.39.1
> **Profile:** Forked MCP Server

This file holds what is specific to the memory image. The fleet rules and the
Expand Down Expand Up @@ -58,8 +58,8 @@ file still crashes; keep it populated.
## Deviations

- **Image name and registries.** The image is `quay.io/crunchtools/memory`,
not `mcp-memory`, and `container.yml` also pushes `ghcr.io/crunchtools/memory`.
Both predate the profile; renaming would break running deployments.
not `mcp-memory`; the name predates the profile and renaming would break
running deployments. Quay.io is the only registry.
- **Base image.** The Hummingbird Python image is pulled from
`registry.access.redhat.com/hi/python:3.14` (builder and runtime), pinned
to Python 3.14, rather than `quay.io/hummingbird/python:latest`. The builder
Expand Down
Loading