Skip to content

Container package: publish engine image to GitHub Packages (GHCR) - #2

Merged
dsk-dev-ai merged 3 commits into
mainfrom
feat/package-ghcr
Sep 11, 2026
Merged

dsk-dev-ai merged 3 commits into
mainfrom
feat/package-ghcr

Conversation

@dsk-dev-ai

@dsk-dev-ai dsk-dev-ai commented Sep 11, 2026

Copy link
Copy Markdown
Owner

Purpose: populate the repo Packages tab by publishing a container image to GHCR via GitHub Packages.

  • Dockerfile: python:3.12 slim, installs the wheel, runs synth discover by default (--smoke), OCI metadata labels
  • Packages workflow: builds amd64+arm64 with Buildx, pushes to ghcr.io/dsk-dev-ai/algorithm-discovery-engine on release-published or manual dispatch — authenticated with GITHUB_TOKEN (no secrets)
  • Tags: v1.0.0, latest, sha-\<hash\>
  • README: GHCR badge + container usage section

Note: github.com GitHub Packages has no public PyPI registry (feature still requested), so a container is the native way to show a published package for this repo.

Summary by Sourcery

Publish the engine as a multi-architecture container image through GitHub Packages and document how to run it.

New Features:

  • Add a multi-architecture container image for the engine, published to GitHub Container Registry with version, commit, and latest tags.

Enhancements:

  • Provide a Python 3.12 container that runs algorithm discovery by default and includes OCI image metadata.

CI:

  • Automate container builds and publishing on release publication or manual workflow dispatch using GitHub Actions.

Documentation:

  • Document GHCR image availability and container usage in the README.

Multi-plarform (amd64/arm64) python:3.12 image; default runs synth discover --smoke
- release published or manual dispatch
- amd64 + arm64 via buildx, semver/sha/latest tags
- GITHUB_TOKEN (write:packages) auth, no secrets required
Multi-platform (amd64/arm64) python:3.12 image; default runs synth discover --smoke
@sourcery-ai

sourcery-ai Bot commented Sep 11, 2026

Copy link
Copy Markdown

Reviewer's Guide

Adds a Dockerized Python runtime and a GitHub Actions workflow that builds multi-architecture images and publishes them to GHCR using GITHUB_TOKEN, with OCI metadata, standard release/commit/latest tags, and README usage documentation.

Sequence diagram for multi architecture image publication

sequenceDiagram
    actor Maintainer
    participant GitHub as GitHub Actions
    participant Buildx
    participant GHCR

    Maintainer->>GitHub: workflow_dispatch
    GitHub->>GitHub: actions/checkout
    GitHub->>GitHub: docker/login-action
    GitHub->>Buildx: docker/buildx-push-action
    Buildx->>Buildx: Build linux/amd64 and linux/arm64
    Buildx->>GHCR: Push tagged image
    GHCR-->>GitHub: Published image
    GitHub-->>Maintainer: Report docker pull commands
Loading

Flow diagram for container image runtime

flowchart LR
    Docker[Docker run image] --> EntryPoint[python -m synth discover]
    EntryPoint --> Smoke[--smoke by default]
    Docker --> Override[Optional python -m command]
Loading

File-Level Changes

Change Details Files
Add a multi-architecture container build and GHCR publication workflow.
  • Trigger publishing on published releases or manual dispatch.
  • Authenticate with the repository token and grant package write access.
  • Build and push linux/amd64 and linux/arm64 images with semver, commit, and default-branch tags.
  • Attach generated OCI metadata and report published image references.
.github/workflows/packages.yml
Define a Python-based runtime image for the discovery engine.
  • Base the image on Python 3.12 slim and install the project package from the repository.
  • Compile Python sources during the image build and remove copied Git metadata.
  • Add OCI source, version, revision, description, and license labels.
  • Run synth discover --smoke by default while allowing command-argument overrides.
Dockerfile
.dockerignore
Document the published GHCR image and container usage.
  • Add a GHCR package badge and link.
  • Document versioned image pulls, supported tags, and default runtime behavior.
README.md

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@coderabbitai

coderabbitai Bot commented Sep 11, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: 655431d6-abad-49d8-ba7a-c1a6b0187f9f


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 5 issues

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path=".github/workflows/packages.yml" line_range="41" />
<code_context>
+        with:
+          images: ${{ env.IMAGE }}
+          tags: |
+            type=semver,pattern={{version}}
+            type=sha
+            type=raw,value=latest,enable={{is_default_branch}}
</code_context>
<issue_to_address>
**issue (bug_risk):** A published release tagged `v1.0.0` produces the image tag `1.0.0`, because the `{{version}}` pattern strips the `v` prefix. The documented and reported `v1.0.0` tag is therefore not published, so the README's release pull command fails.

**Triggers:** When the workflow is triggered by a release whose tag uses the documented `vX.Y.Z` format.

**Suggested fix:** Use a semver pattern that preserves the prefix, such as `pattern=v{{version}}`, or document and report the unprefixed tag.
</issue_to_address>

### Comment 2
<location path=".github/workflows/packages.yml" line_range="43" />
<code_context>
+          tags: |
+            type=semver,pattern={{version}}
+            type=sha
+            type=raw,value=latest,enable={{is_default_branch}}
+
+      - name: Build and push
</code_context>
<issue_to_address>
**issue (bug_risk):** The `latest` tag is disabled for release events because `is_default_branch` is false when the workflow runs on a release tag. Consequently, the normal release publication does not produce the `latest` tag promised by the README.

**Triggers:** When the workflow is triggered by `release.published`, as opposed to a manual dispatch on the default branch.

**Suggested fix:** Enable the raw `latest` tag for release events as well, or use an explicit condition that recognizes the release trigger.
</issue_to_address>

### Comment 3
<location path=".github/workflows/packages.yml" line_range="57" />
<code_context>
+      - name: Report image
+        run: |
+          echo "Published:"
+          echo "  docker pull ${{ env.IMAGE }}:${{ github.ref_name }}"
+          echo "  docker pull ${{ env.IMAGE }}:latest"
\ No newline at end of file
</code_context>
<issue_to_address>
**issue:** The report prints a pull command using `github.ref_name` even when the workflow is manually dispatched. On manual dispatch this is the selected branch name, but metadata-action does not create a corresponding branch tag, so the printed image reference does not exist.

**Triggers:** When the workflow is manually dispatched from a branch, including the default branch where only `latest` and `sha-*` are generated.

**Suggested fix:** Report only tags that are guaranteed to be generated, or select the release/version tag and generated metadata dynamically.
</issue_to_address>

### Comment 4
<location path="README.md" line_range="193" />
<code_context>
+```
+
+Tags: `latest`, per-version (`v1.0.0`), and per-commit (`sha-<hash>`). The image runs
+the local algorithm synthesizer by default; override with any `python -m` command.
+
 ## Documentation
</code_context>
<issue_to_address>
**issue:** The image has a fixed `ENTRYPOINT` of `python -m synth discover`, so arguments in `docker run IMAGE python -m ...` are appended to that command rather than replacing it. The documented claim that any `python -m` command can override the default is false, and such a command is parsed as invalid discovery arguments.

**Triggers:** When a user follows the README's instruction to override the image with another `python -m` command.

**Suggested fix:** Document `docker run --entrypoint python IMAGE -m ...`, or change the image interface to use a wrapper that supports command replacement.

```suggestion
the local algorithm synthesizer by default; to run pattern discovery instead, use `docker run --rm --entrypoint python ghcr.io/dsk-dev-ai/algorithm-discovery-engine:v1.0.0 -m algo_discovery 1 4 9 16`.
```
</issue_to_address>

### Comment 5
<location path="Dockerfile" line_range="3-7" />
<code_context>
+FROM python:3.12-slim
+
+ARG VERSION=1.0.0
+
+LABEL org.opencontainers.image.source=https://github.com/dsk-dev-ai/algorithm-discovery-engine
+LABEL org.opencontainers.image.version=$VERSION
+LABEL org.opencontainers.image.revision=$VERSION
+LABEL org.opencontainers.image.description="Multi-language algorithms & data structures engine with a local algorithm synthesizer (Python tier)."
+LABEL org.opencontainers.image.licenses=MIT
+
</code_context>
<issue_to_address>
**nitpick:** The OCI revision label is populated with the static package version via `$VERSION`, so every build reports `1.0.0` as its source revision instead of the commit that produced the image. Builds from later releases or different commits therefore carry incorrect provenance metadata.

**Triggers:** When the image is built from any commit whose revision is not the package version.

**Suggested fix:** Pass the commit SHA as a build argument and set `org.opencontainers.image.revision` from that argument, while keeping the package version in the version label.

```suggestion
ARG VERSION=1.0.0
ARG COMMIT_SHA

LABEL org.opencontainers.image.source=https://github.com/dsk-dev-ai/algorithm-discovery-engine
LABEL org.opencontainers.image.version=$VERSION
LABEL org.opencontainers.image.revision=$COMMIT_SHA
```
</issue_to_address>

Sourcery assessment

Needs a human reviewer. 4 findings to address first, and this publishes a container image and tags that can remain available after the workflow or Dockerfile is reverted, so users could pull and run an incorrect image. The affected tags can be deleted or replaced with a corrected build, making the fallout bounded and repairable.

Blocking findings: .github/workflows/packages.yml:41, .github/workflows/packages.yml:43, .github/workflows/packages.yml:57, README.md:193


Sourcery is free for open source - if you like our reviews please consider sharing them ✨

with:
images: ${{ env.IMAGE }}
tags: |
type=semver,pattern={{version}}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): A published release tagged v1.0.0 produces the image tag 1.0.0, because the {{version}} pattern strips the v prefix. The documented and reported v1.0.0 tag is therefore not published, so the README's release pull command fails.

Triggers: When the workflow is triggered by a release whose tag uses the documented vX.Y.Z format.

Suggested fix: Use a semver pattern that preserves the prefix, such as pattern=v{{version}}, or document and report the unprefixed tag.

tags: |
type=semver,pattern={{version}}
type=sha
type=raw,value=latest,enable={{is_default_branch}}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): The latest tag is disabled for release events because is_default_branch is false when the workflow runs on a release tag. Consequently, the normal release publication does not produce the latest tag promised by the README.

Triggers: When the workflow is triggered by release.published, as opposed to a manual dispatch on the default branch.

Suggested fix: Enable the raw latest tag for release events as well, or use an explicit condition that recognizes the release trigger.

- name: Report image
run: |
echo "Published:"
echo " docker pull ${{ env.IMAGE }}:${{ github.ref_name }}"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue: The report prints a pull command using github.ref_name even when the workflow is manually dispatched. On manual dispatch this is the selected branch name, but metadata-action does not create a corresponding branch tag, so the printed image reference does not exist.

Triggers: When the workflow is manually dispatched from a branch, including the default branch where only latest and sha-* are generated.

Suggested fix: Report only tags that are guaranteed to be generated, or select the release/version tag and generated metadata dynamically.

Comment thread README.md
```

Tags: `latest`, per-version (`v1.0.0`), and per-commit (`sha-<hash>`). The image runs
the local algorithm synthesizer by default; override with any `python -m` command.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue: The image has a fixed ENTRYPOINT of python -m synth discover, so arguments in docker run IMAGE python -m ... are appended to that command rather than replacing it. The documented claim that any python -m command can override the default is false, and such a command is parsed as invalid discovery arguments.

Triggers: When a user follows the README's instruction to override the image with another python -m command.

Suggested fix: Document docker run --entrypoint python IMAGE -m ..., or change the image interface to use a wrapper that supports command replacement.

Suggested change
the local algorithm synthesizer by default; override with any `python -m` command.
the local algorithm synthesizer by default; to run pattern discovery instead, use `docker run --rm --entrypoint python ghcr.io/dsk-dev-ai/algorithm-discovery-engine:v1.0.0 -m algo_discovery 1 4 9 16`.

Comment thread Dockerfile
Comment on lines +3 to +7
ARG VERSION=1.0.0

LABEL org.opencontainers.image.source=https://github.com/dsk-dev-ai/algorithm-discovery-engine
LABEL org.opencontainers.image.version=$VERSION
LABEL org.opencontainers.image.revision=$VERSION

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick: The OCI revision label is populated with the static package version via $VERSION, so every build reports 1.0.0 as its source revision instead of the commit that produced the image. Builds from later releases or different commits therefore carry incorrect provenance metadata.

Triggers: When the image is built from any commit whose revision is not the package version.

Suggested fix: Pass the commit SHA as a build argument and set org.opencontainers.image.revision from that argument, while keeping the package version in the version label.

Suggested change
ARG VERSION=1.0.0
LABEL org.opencontainers.image.source=https://github.com/dsk-dev-ai/algorithm-discovery-engine
LABEL org.opencontainers.image.version=$VERSION
LABEL org.opencontainers.image.revision=$VERSION
ARG VERSION=1.0.0
ARG COMMIT_SHA
LABEL org.opencontainers.image.source=https://github.com/dsk-dev-ai/algorithm-discovery-engine
LABEL org.opencontainers.image.version=$VERSION
LABEL org.opencontainers.image.revision=$COMMIT_SHA

@dsk-dev-ai
dsk-dev-ai merged commit dc3f59d into main Sep 11, 2026
13 checks passed
@dsk-dev-ai
dsk-dev-ai deleted the feat/package-ghcr branch September 11, 2026 16:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant