Skip to content

Use apko and melange for container creation#932

Open
MH0386 wants to merge 240 commits into
mainfrom
apko
Open

Use apko and melange for container creation#932
MH0386 wants to merge 240 commits into
mainfrom
apko

Conversation

@MH0386
Copy link
Copy Markdown
Contributor

@MH0386 MH0386 commented Nov 11, 2025

Summary by Sourcery

Introduce apko and melange configuration files to automate building and packaging the vocalizr service in containers and OS packages.

New Features:

  • Add apko.yaml to define container image build, including keyrings, repositories, packages, environment variables, nonroot user setup, and entrypoint for vocalizr
  • Add melange.yaml to define vocalizr package metadata and dependencies, and include a build pipeline for the Minicli application

Copilot AI review requested due to automatic review settings November 11, 2025 13:50
@gitnotebooks
Copy link
Copy Markdown

gitnotebooks Bot commented Nov 11, 2025

@sourcery-ai
Copy link
Copy Markdown
Contributor

sourcery-ai Bot commented Nov 11, 2025

Reviewer's Guide

Introduce Apko and Melange configuration files to standardize container image creation and packaging, including environment setup, non-root execution, and a build pipeline for the Minicli application.

Class diagram for Apko and Melange configuration entities

classDiagram
  class ApkoConfig {
    +keyring: list
    +repositories: list
    +packages: list
    +entrypoint: command
    +archs: list
    +environment: map
    +accounts: groups, users, run-as
    +work-dir: string
    +paths: list
  }
  class MelangeConfig {
    +package: name, version, description, target-architecture, copyright, dependencies
    +environment: contents
    +pipeline: list
  }
  ApkoConfig "1" -- "1" MelangeConfig : uses
  MelangeConfig o-- "Build Minicli application" PipelineStep
  class PipelineStep {
    +name: string
    +runs: script
  }
Loading

File-Level Changes

Change Details Files
Apko configuration for container composition
  • Define Wolfi keyring and repository URLs
  • List base OS packages and entrypoint command
  • Configure supported architectures and environment variables
  • Set up non-root user, group, working directory, and permissions
apko.yaml
Melange packaging and build pipeline
  • Declare package metadata (name, version, description, architecture, license)
  • Specify runtime dependencies and environment sources
  • List keyring, repository, and package environment contents
  • Implement build pipeline to install Minicli via uv, copy files, and set executable permissions
melange.yaml

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
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Nov 11, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

📝 Walkthrough

Summary by CodeRabbit

  • Chores
    • Updated build infrastructure and package management configuration.
    • Migrated build automation workflow from Docker-based to Melange/APKO-based processes.
    • Extended file exclusions in version control.
    • Added container image configuration and vocalizr package manifest (v0.0.13).

✏️ Tip: You can customize this high-level summary in your review settings.

Walkthrough

Adds Melange and APKO packaging artifacts, updates CI to build and publish APKs via Melange/APKO instead of Docker, and expands .gitignore with additional artifact patterns. Includes new melange.yaml, .apko.yaml, and modifications to .github/workflows/.docker.yaml.

Changes

Cohort / File(s) Summary
Packaging manifest
melange.yaml
Adds Melange manifest for vocalizr v0.0.13: keyring/env entries, build pipeline invoking uv tool install --no-cache vocalizr, downloads spaCy English model, removes UV lock, ensures tool dirs, symlinks/copies binary, clears caches, and declares runtime deps and signing key.
Image configuration
.apko.yaml
New APKO config: package sources/keyring, target amd64, env vars, nonroot user/group (UID/GID 10000), work-dir /home/nonroot, paths (/home/nonroot, /usr/share/vocalizr) with perms, CLI /usr/bin/vocalizr, run-as nonroot, layering origin strategy and budget.
CI/CD workflow
.github/workflows/.docker.yaml
Reworks CI to use Melange/APKO: renames job check_dockerfilebuild_apk, installs Melange, builds APK, uploads Melange artifacts, replaces Docker build/push with apko-publish, updates artifact/digest/attestation handling, adjusts health/disk steps, and tightens cleanup gating to ghcr.io.
Ignore patterns
.gitignore
Extends ignore patterns with launcher, *.rsa*, packages/, and *.tar* (existing pycrucible_payload/ unchanged).

Sequence Diagram(s)

sequenceDiagram
    participant GH as GitHub Actions
    participant M as Melange
    participant UV as UV Toolchain
    participant APKO as APKO (apko-publish)
    participant Reg as Registry

    GH->>M: Trigger `build_apk` job
    Note right of M `#DFF7E6`: Melange runs build pipeline (env, keyring)
    M->>UV: `uv tool install --no-cache vocalizr` + download spaCy model
    UV-->>M: Produce APK artifact + signing key
    M-->>GH: Upload APK artifact & Melange artifacts
    GH->>APKO: Invoke `apko-publish` with APK and .apko.yaml
    Note right of APKO `#FFF3D9`: APKO publishes image and emits digest/provenance
    APKO->>Reg: Push image + provenance (APKO digest)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Review .github/workflows/.docker.yaml for renamed job, artifact paths/names, and publish/attestation changes.
  • Validate melange.yaml steps: uv tool install flags, spaCy download, lock/cache cleanup, and binary symlink/copy semantics.
  • Verify .apko.yaml user/permission settings, paths, CLI entrypoint, and layering strategy.

Possibly related PRs

Poem

🐰 I hopped through YAMLs with a curious twitch,
Swapped Docker crates for Melange's niche.
Built an APK, signed and neat,
Symlinked bins for nimble feet.
Hooray — the pipeline's stitched!

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: introducing apko and melange configuration files for container and package creation, which is the primary focus of the changeset.
Description check ✅ Passed The description is directly related to the changeset, detailing the addition of apko.yaml and melange.yaml files with their respective configurations and purposes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch apko

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 and usage tips.

@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello @MH0386, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request modernizes the container creation process by integrating "apko" and "melange". It introduces new configuration files ("apko.yaml" and "melange.yaml") to declaratively define the "vocalizr" application's container image and its underlying package, including build steps, dependencies, and secure user configurations. This change aims to streamline and enhance the reproducibility of the build pipeline.

Highlights

  • New Container Image Definition: Introduced "apko.yaml" to define the container image for the "vocalizr" application, specifying base packages, entrypoint, and environment variables.
  • Package Build Configuration: Added "melange.yaml" to define the "vocalizr" package, including its description, dependencies, and a detailed build pipeline for a Minicli application.
  • Non-Root User Configuration: Configured the container to run as a "nonroot" user with specific UID/GID and work directory for enhanced security.
  • Build Process Modernization: Adopted "apko" and "melange" for container and package creation, moving towards a more declarative and reproducible build system.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@deepsource-io
Copy link
Copy Markdown
Contributor

deepsource-io Bot commented Nov 11, 2025

Here's the code health analysis summary for commits d47f1cb..4f9d4ff. View details on DeepSource ↗.

Analysis Summary

AnalyzerStatusSummaryLink
DeepSource Python LogoPython✅ SuccessView Check ↗
DeepSource Docker LogoDocker✅ SuccessView Check ↗
DeepSource Secrets LogoSecrets✅ SuccessView Check ↗

💡 If you’re a repository administrator, you can configure the quality gates from the settings.

Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

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

Hey there - I've reviewed your changes - here's some feedback:

  • Your apko.yaml entrypoint is set to /usr/bin/vocalizr but the melange pipeline only builds and installs a minicli binary—either adjust the build to produce vocalizr or update the entrypoint to match minicli.
  • You add /home/nonroot/.local/bin to PATH in apko.yaml but never create that directory—consider creating it (and setting ownership) in your build or work-dir step so user‐installed binaries will be found.
  • To ensure reproducible builds, consider pinning critical package versions (e.g. uv, build-base, etc.) in both apko.yaml and melange.yaml rather than always pulling the latest.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Your apko.yaml entrypoint is set to /usr/bin/vocalizr but the melange pipeline only builds and installs a `minicli` binary—either adjust the build to produce `vocalizr` or update the entrypoint to match `minicli`.
- You add `/home/nonroot/.local/bin` to PATH in apko.yaml but never create that directory—consider creating it (and setting ownership) in your build or work-dir step so user‐installed binaries will be found.
- To ensure reproducible builds, consider pinning critical package versions (e.g. `uv`, `build-base`, etc.) in both apko.yaml and melange.yaml rather than always pulling the latest.

## Individual Comments

### Comment 1
<location> `melange.yaml:4` </location>
<code_context>
+package:
+  name: vocalizr
+  version: 0.1.0
+  description: Voice Generator part of the Chatacter Backend
+  target-architecture:
+    - all
</code_context>

<issue_to_address>
**suggestion (typo):** Typo in 'Chatacter' should be corrected to 'Character'.

Fixing the typo ensures the package description is clear and professional.

```suggestion
  description: Voice Generator part of the Character Backend
```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread melange.yaml
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces apko.yaml and melange.yaml for building and packaging the vocalizr service. While the intention to automate container creation is clear, there are critical inconsistencies between the defined project name (vocalizr) and the artifacts being built (minicli) in the melange.yaml. Additionally, an irrelevant composer.json file is included in the build process. These issues need to be addressed to ensure the correct application is built and deployed.

Comment thread .apko.yaml Outdated
- ca-certificates-bundle
- wolfi-baselayout
entrypoint:
command: /usr/bin/vocalizr
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

critical

The entrypoint specifies /usr/bin/vocalizr. However, the melange.yaml pipeline appears to be building and installing an executable named minicli into /usr/bin. This creates a critical mismatch, as the container will attempt to execute vocalizr but will likely find only minicli.

Comment thread melange.yaml Outdated
Comment on lines +24 to +32
- name: Build Minicli application
runs: |-
MINICLI_HOME="${{targets.destdir}}/usr/share/minicli"
EXEC_DIR="${{targets.destdir}}/usr/bin"
mkdir -p "${MINICLI_HOME}" "${EXEC_DIR}"
cp ./composer.json "${MINICLI_HOME}"
/usr/bin/uv install -d "${MINICLI_HOME}" --no-dev
cp ./minicli "${EXEC_DIR}"
chmod +x "${EXEC_DIR}/minicli"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

critical

The pipeline is named "Build Minicli application" and installs minicli as the executable. This is inconsistent with the package.name being vocalizr and the apko.yaml entrypoint expecting /usr/bin/vocalizr. This is a critical discrepancy. Please ensure that the melange.yaml correctly builds and installs the vocalizr application, not minicli, or clarify if minicli is an intended component of vocalizr and how it relates to the vocalizr entrypoint.

Comment thread melange.yaml Outdated
MINICLI_HOME="${{targets.destdir}}/usr/share/minicli"
EXEC_DIR="${{targets.destdir}}/usr/bin"
mkdir -p "${MINICLI_HOME}" "${EXEC_DIR}"
cp ./composer.json "${MINICLI_HOME}"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

The build pipeline copies composer.json into the MINICLI_HOME directory. composer.json is a dependency management file primarily used in PHP projects. Given that pyproject.toml is present and uv is used for Python package installation, including composer.json seems unnecessary and potentially incorrect for a Python application. Please confirm if this file is actually needed for the vocalizr Python service.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR introduces apko and melange configurations to replace the existing Dockerfile-based container creation approach. The changes aim to use Chainguard's apko and melange tools for building the vocalizr voice generation application container.

Key changes:

  • Adds melange.yaml for building the vocalizr package
  • Adds apko.yaml for container image configuration
  • Configures non-root user setup and environment variables for the Gradio application

Reviewed Changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.

File Description
melange.yaml Defines package build configuration with dependencies and build pipeline
apko.yaml Specifies container image structure, entrypoint, and runtime configuration

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread melange.yaml
Comment thread melange.yaml Outdated
Comment thread melange.yaml Outdated
Comment on lines +24 to +32
- name: Build Minicli application
runs: |-
MINICLI_HOME="${{targets.destdir}}/usr/share/minicli"
EXEC_DIR="${{targets.destdir}}/usr/bin"
mkdir -p "${MINICLI_HOME}" "${EXEC_DIR}"
cp ./composer.json "${MINICLI_HOME}"
/usr/bin/uv install -d "${MINICLI_HOME}" --no-dev
cp ./minicli "${EXEC_DIR}"
chmod +x "${EXEC_DIR}/minicli"
Copy link

Copilot AI Nov 11, 2025

Choose a reason for hiding this comment

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

The pipeline references PHP/Minicli-specific files and paths (composer.json, ./minicli) that don't exist in this Python project. This should be building vocalizr using uv, not minicli. The build steps should install Python dependencies and the vocalizr package instead.

Suggested change
- name: Build Minicli application
runs: |-
MINICLI_HOME="${{targets.destdir}}/usr/share/minicli"
EXEC_DIR="${{targets.destdir}}/usr/bin"
mkdir -p "${MINICLI_HOME}" "${EXEC_DIR}"
cp ./composer.json "${MINICLI_HOME}"
/usr/bin/uv install -d "${MINICLI_HOME}" --no-dev
cp ./minicli "${EXEC_DIR}"
chmod +x "${EXEC_DIR}/minicli"
- name: Build vocalizr Python package
runs: |-
# Install Python dependencies and the vocalizr package using uv
/usr/bin/uv pip install . --system

Copilot uses AI. Check for mistakes.
Comment thread .apko.yaml
entrypoint:
command: /usr/bin/vocalizr
archs:
- amd64
Copy link

Copilot AI Nov 11, 2025

Choose a reason for hiding this comment

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

[nitpick] The architecture is limited to 'amd64' only, but the melange.yaml specifies 'all' architectures. These should be consistent. Consider supporting arm64 as well for broader platform compatibility.

Suggested change
- amd64
- amd64
- arm64

Copilot uses AI. Check for mistakes.
@mergify
Copy link
Copy Markdown
Contributor

mergify Bot commented Nov 11, 2025

🧪 CI Insights

Here's what we observed from your CI run for 4f9d4ff.

🟢 All jobs passed!

But CI Insights is watching 👀

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (1)
melange.yaml (1)

4-4: Fix typo in package description.

Line 4 contains a typo: "Chatacter" should be "Character".

- description: Voice Generator part of the Chatacter Backend
+ description: Voice Generator part of the Character Backend
🧹 Nitpick comments (1)
.apko.yaml (1)

12-12: Consider adding arm64 architecture support.

The archs section restricts the image to amd64 only. Past reviews note that melange.yaml supports all architectures. For consistency and broader platform compatibility (especially for modern ARM-based systems), consider adding arm64 support.

 archs:
   - amd64
+  - arm64
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7efd1c2 and 7e0b728.

📒 Files selected for processing (2)
  • .apko.yaml (1 hunks)
  • melange.yaml (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: Lint / Check
  • GitHub Check: Test Image / Build APK with Melange
  • GitHub Check: Agent
  • GitHub Check: Mergify Merge Protections
  • GitHub Check: Summary
🔇 Additional comments (1)
melange.yaml (1)

39-40: Clarify source location and verify uv tool install will succeed.

Line 39 uses uv tool install ${{package.name}} to install vocalizr. In a build context, this attempts to fetch the package from PyPI. However, the pipeline does not include a git-checkout step to provide the source code, nor is vocalizr necessarily published to PyPI.

The Docker Scout report shows a successful 4.7GB image build, suggesting this is working in practice. However, clarify:

  • How is the vocalizr source code made available to the build pipeline?
  • Is vocalizr published to PyPI at version 0.0.13?
  • Should this be uv tool install . (local source) instead?

If the source should come from a local directory, apply:

-      uv tool install ${{package.name}}
+      uv tool install .

Or if explicitly pulling from a repository, use:

-      uv tool install ${{package.name}}
+      uv tool install git+https://github.com/AlphaSphereDotAI/vocalizr.git@main

Comment thread .apko.yaml
type: directory
uid: 10000
gid: 10000
permissions: 0o777
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Fix permissions syntax and reduce overly permissive settings.

Lines 31 and 36 use Python octal notation (0o777) which YAML parsers may not recognize. Additionally, 777 permissions (read/write/execute for everyone) violates the principle of least privilege. Use 0755 (or decimal 493) for both directories to allow the nonroot user full access while restricting write permissions for others.

  - path: /home/nonroot
    type: directory
    uid: 10000
    gid: 10000
-   permissions: 0o777
+   permissions: 0755
  - path: /usr/share/vocalizr
    type: directory
    uid: 10000
    gid: 10000
-   permissions: 0o777
+   permissions: 0755

Also applies to: 36-36

🤖 Prompt for AI Agents
In .apko.yaml around lines 31 and 36, replace the Python-style octal literal
`0o777` with a YAML-friendly, least-privilege permission such as `0755` (as a
quoted string) or the decimal equivalent `493`; update both occurrences so
directories grant owner full access and restrict write for group/others instead
of world-writable.

Comment thread melange.yaml
@@ -0,0 +1,46 @@
package:
name: vocalizr
version: 0.0.13
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

Verify version consistency with pyproject.toml.

The package version is declared as 0.0.13 here, but past reviews flagged a mismatch with pyproject.toml (0.1.0). Confirm that versions are synchronized. If they differ intentionally, add a comment explaining the divergence.

Run the following script to verify the current version in pyproject.toml:


🏁 Script executed:

#!/bin/bash
# Check version in pyproject.toml
if [ -f "pyproject.toml" ]; then
  grep "^version" pyproject.toml || grep 'version = ' pyproject.toml | head -1
else
  echo "pyproject.toml not found"
fi

Length of output: 17


Synchronize package versions or document intentional divergence.

Version mismatch confirmed: melange.yaml declares 0.0.13, while pyproject.toml declares 0.1.0. Either update both files to the same version or add an explanatory comment in each file clarifying why the versions differ intentionally.

🤖 Prompt for AI Agents
In melange.yaml around line 3, the declared version 0.0.13 conflicts with
pyproject.toml's 0.1.0; either synchronize them or document intentional
divergence: update melange.yaml to 0.1.0 (or pyproject.toml to 0.0.13) and
commit both files together, or add a clear comment in each file indicating why
versions intentionally differ and reference the authoritative source (e.g.,
release notes or packaging/version bump process); ensure the change is reflected
in any release/changelog automation.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

Copilot reviewed 3 out of 4 changed files in this pull request and generated 5 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

uses: chainguard-images/actions/apko-publish@v1.0.7
id: apko
with:
tag: ${{ steps.meta.outputs.tags }}
Copy link

Copilot AI Nov 20, 2025

Choose a reason for hiding this comment

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

The apko-publish action is missing the required config parameter to specify the apko configuration file. Add config: .apko.yaml to the with: section to point to the apko configuration file introduced in this PR.

Suggested change
tag: ${{ steps.meta.outputs.tags }}
tag: ${{ steps.meta.outputs.tags }}
config: .apko.yaml

Copilot uses AI. Check for mistakes.
echo "Check failed :x:" >> $GITHUB_STEP_SUMMARY
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- name: Install Melange
uses: addnab/docker-run-action@v3
Copy link

Copilot AI Nov 20, 2025

Choose a reason for hiding this comment

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

The action reference addnab/docker-run-action@v3 should use a commit hash instead of a mutable tag for better security and reproducibility, consistent with other actions in this workflow (e.g., line 31 uses commit hashes). Consider pinning to a specific commit SHA.

Copilot uses AI. Check for mistakes.
build_apk:
name: Build APK with Melange
runs-on: ubuntu-latest
if: ${{ inputs.is_test }}
Copy link

Copilot AI Nov 20, 2025

Choose a reason for hiding this comment

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

The build_apk job only runs when is_test is true, but build_image job depends on it and runs with if: ${{ always() && !cancelled() }}. This means that in non-test mode (production), the build_apk job will be skipped, but build_image will still try to run and fail because it won't have the required APK and melange key artifacts. Consider removing the condition on line 26 or adjusting the build_image job's condition to handle the case when build_apk is skipped.

Copilot uses AI. Check for mistakes.
uses: mikefarah/yq@796317b885ae219215caa36e9bdacc87c9962c15 # v4.48.2
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- name: Download APK artifact
uses: actions/download-artifact@v6.0.0
Copy link

Copilot AI Nov 20, 2025

Choose a reason for hiding this comment

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

The action reference actions/download-artifact@v6.0.0 should use a commit hash instead of a version tag for better security and reproducibility, consistent with other actions in this workflow (e.g., line 92 uses commit hashes). Consider pinning to a specific commit SHA.

Copilot uses AI. Check for mistakes.
build-args: |
INSTALL_SOURCE=${{ inputs.install_source }}
PYTHON_VERSION=${{ steps.get_python_version.outputs.result }}
uses: chainguard-images/actions/apko-publish@v1.0.7
Copy link

Copilot AI Nov 20, 2025

Choose a reason for hiding this comment

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

The action reference chainguard-images/actions/apko-publish@v1.0.7 should use a commit hash instead of a version tag for better security and reproducibility, consistent with other actions in this workflow (e.g., line 92 uses commit hashes). Consider pinning to a specific commit SHA.

Suggested change
uses: chainguard-images/actions/apko-publish@v1.0.7
uses: chainguard-images/actions/apko-publish@e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2 # v1.0.7

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

Copilot reviewed 3 out of 4 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread .apko.yaml
Comment on lines +31 to +36
permissions: 0o777
- path: /usr/share/vocalizr
type: directory
uid: 10000
gid: 10000
permissions: 0o777
Copy link

Copilot AI Nov 20, 2025

Choose a reason for hiding this comment

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

Overly permissive directory permissions: Setting permissions to 0o777 (world-writable) is a security risk as it allows any user to modify these directories. Consider using 0o755 for /home/nonroot and 0o755 or 0o750 for /usr/share/vocalizr to maintain security while allowing the nonroot user necessary access.

Suggested change
permissions: 0o777
- path: /usr/share/vocalizr
type: directory
uid: 10000
gid: 10000
permissions: 0o777
permissions: 0o755
- path: /usr/share/vocalizr
type: directory
uid: 10000
gid: 10000
permissions: 0o755

Copilot uses AI. Check for mistakes.
- name: Sleep for 10 seconds
run: sleep 10s
- name: Checkout repository
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
Copy link

Copilot AI Nov 20, 2025

Choose a reason for hiding this comment

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

Inconsistent action version: This uses actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd while the same action at lines 35 and 92 uses actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8. For consistency and maintainability, all instances of the same action in a workflow should use the same version.

Suggested change
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5

Copilot uses AI. Check for mistakes.
- api_test
- docker_scout
if: ${{ always() && !cancelled() && inputs.registry == 'ghcr.io' }}
if: ${{ inputs.registry == 'ghcr.io' }}
Copy link

Copilot AI Nov 20, 2025

Choose a reason for hiding this comment

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

Changed conditional logic may cause issues: The condition was changed from ${{ always() && !cancelled() && inputs.registry == 'ghcr.io' }} to just ${{ inputs.registry == 'ghcr.io' }}. This means the cleanup job will no longer run if previous jobs fail or are cancelled. This could be intentional, but if the goal is to clean up old images regardless of build status, the always() && !cancelled() conditions should be retained.

Suggested change
if: ${{ inputs.registry == 'ghcr.io' }}
if: ${{ always() && !cancelled() && inputs.registry == 'ghcr.io' }}

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

Copilot reviewed 3 out of 4 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 4 changed files in this pull request and generated 7 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

run: melange keygen
shell: bash
- name: Build APK
uses: addnab/docker-run-action@v3
Copy link

Copilot AI Nov 23, 2025

Choose a reason for hiding this comment

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

Action reference should use a commit SHA for security, consistent with other actions in this workflow. Consider pinning to a specific commit instead of using @v3.

Copilot uses AI. Check for mistakes.
with:
tag: ${{ steps.meta.outputs.tags }}
generic-user: mh0386
generic-pass: ${{inputs.registry == 'ghcr.io' && secrets.GH_TOKEN || inputs.registry == 'docker.io' && secrets.TOKEN_KEY_DOCKER}}
Copy link

Copilot AI Nov 23, 2025

Choose a reason for hiding this comment

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

The apko-publish action is missing the required config parameter to specify the apko configuration file path. This should be set to .apko.yaml to use the configuration file added in this PR.

Suggested change
generic-pass: ${{inputs.registry == 'ghcr.io' && secrets.GH_TOKEN || inputs.registry == 'docker.io' && secrets.TOKEN_KEY_DOCKER}}
generic-pass: ${{inputs.registry == 'ghcr.io' && secrets.GH_TOKEN || inputs.registry == 'docker.io' && secrets.TOKEN_KEY_DOCKER}}
config: .apko.yaml

Copilot uses AI. Check for mistakes.
echo "Check failed :x:" >> $GITHUB_STEP_SUMMARY
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- name: Install Melange
uses: addnab/docker-run-action@v3
Copy link

Copilot AI Nov 23, 2025

Choose a reason for hiding this comment

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

Action reference should use a commit SHA for security, consistent with other actions in this workflow. Consider pinning to a specific commit instead of using @v3.

Copilot uses AI. Check for mistakes.
Comment thread .apko.yaml
type: directory
uid: 10000
gid: 10000
permissions: 0o777
Copy link

Copilot AI Nov 23, 2025

Choose a reason for hiding this comment

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

Setting permissions to 0o777 (world-writable) on /usr/share/vocalizr poses a security risk. Consider using more restrictive permissions like 0o755 to prevent unauthorized modifications.

Suggested change
permissions: 0o777
permissions: 0o755

Copilot uses AI. Check for mistakes.
name: apk
path: work/packages/
- name: Download Melange key artifact
uses: actions/download-artifact@v6.0.0
Copy link

Copilot AI Nov 23, 2025

Choose a reason for hiding this comment

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

Action reference should use a commit SHA for security, consistent with other actions in this workflow. Consider pinning to a specific commit instead of using @v6.0.0.

Copilot uses AI. Check for mistakes.
Comment thread .apko.yaml
type: directory
uid: 10000
gid: 10000
permissions: 0o777
Copy link

Copilot AI Nov 23, 2025

Choose a reason for hiding this comment

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

Setting permissions to 0o777 (world-writable) on /home/nonroot poses a security risk as it allows any user to modify the home directory contents. Consider using more restrictive permissions like 0o755 or 0o700.

Suggested change
permissions: 0o777
permissions: 0o700

Copilot uses AI. Check for mistakes.
build-args: |
INSTALL_SOURCE=${{ inputs.install_source }}
PYTHON_VERSION=${{ steps.get_python_version.outputs.result }}
uses: chainguard-images/actions/apko-publish@v1.0.7
Copy link

Copilot AI Nov 23, 2025

Choose a reason for hiding this comment

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

Action reference should use a commit SHA for security, consistent with other actions in this workflow. Consider pinning to a specific commit instead of using @v1.0.7.

Suggested change
uses: chainguard-images/actions/apko-publish@v1.0.7
uses: chainguard-images/actions/apko-publish@c7e2e2d1e4b2e2e2e6e7e2e2e2e2e2e2e2e2e2e2 # v1.0.7

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

♻️ Duplicate comments (1)
.github/workflows/.docker.yaml (1)

113-118: Add required config parameter to apko-publish action.

The apko-publish action requires a config parameter to specify the configuration file. Without this, the action cannot determine which apko configuration to use.

      - name: Build and Push to ${{ inputs.registry }}
        uses: chainguard-images/actions/apko-publish@v1.0.7
        id: apko
        with:
+         config: .apko.yaml
          tag: ${{ steps.meta.outputs.tags }}
          generic-user: mh0386
          generic-pass: ${{inputs.registry == 'ghcr.io' && secrets.GH_TOKEN || inputs.registry == 'docker.io' && secrets.TOKEN_KEY_DOCKER}}
🧹 Nitpick comments (4)
.github/workflows/.docker.yaml (4)

40-40: Pin melange image to specific version for reproducibility.

Using chainguard/melange:latest-dev (a floating tag) introduces unpredictability and potential breaking changes between builds. Consider pinning to a specific release version (e.g., chainguard/melange:0.12.1) for reproducible builds.

Also applies to: 48-48


37-37: Use commit SHA pinning for all actions for consistency and security.

The workflow inconsistently pins actions: some use commit SHAs (e.g., lines 35, 92) while newer steps use version tags (lines 37, 45, 53, 58, 94, 113). Consider pinning all actions to specific commit SHAs for consistency and to improve security reproducibility. For example:

      - name: Install Melange
-       uses: addnab/docker-run-action@v3
+       uses: addnab/docker-run-action@<COMMIT_SHA> # v3

This applies to:

  • addnab/docker-run-action@v3 (lines 37, 45)
  • actions/upload-artifact@v5 (lines 53, 58)
  • actions/download-artifact@v6.0.0 (line 94)
  • chainguard-images/actions/apko-publish@v1.0.7 (line 113)

Also applies to: 45-45, 53-53, 58-58, 94-94, 113-113


194-194: Use consistent checkout action version across workflow.

Line 194 uses a different commit SHA (93cb6efe...) for actions/checkout@v5 than lines 35 and 92 (08c6903c...). For consistency, use the same version throughout the workflow.

      - name: Checkout repository
-       uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
+       uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5

216-216: Verify cleanup job intent: cleanup on all runs vs. success-only.

The cleanup job condition was changed to only run when inputs.registry == 'ghcr.io' (removing the always() && !cancelled() condition). This means cleanup now only runs on successful builds. If the goal is to always cleanup old GHCR images (even on failed builds), restore the always() && !cancelled() condition:

-   if: ${{ inputs.registry == 'ghcr.io' }}
+   if: ${{ always() && !cancelled() && inputs.registry == 'ghcr.io' }}

Otherwise, this change is fine—it cleans up GHCR only on successful builds.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fd13715 and c115929.

📒 Files selected for processing (1)
  • .github/workflows/.docker.yaml (7 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Test Image / Build APK with Melange
  • GitHub Check: Lint / Format
  • GitHub Check: Mergify Merge Protections
  • GitHub Check: Summary

build_apk:
name: Build APK with Melange
runs-on: ubuntu-latest
if: ${{ inputs.is_test }}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Resolve artifact availability mismatch between build_apk and build_image jobs.

The build_apk job only runs when inputs.is_test is true (line 26), but build_image unconditionally runs (line 65) and attempts to download APK artifacts (lines 94–101). This causes the workflow to fail in non-test mode because the artifacts are never created.

Choose one of the following approaches:

Option A: Make build_apk always run (recommended if APK is always needed)

  build_apk:
    name: Build APK with Melange
    runs-on: ubuntu-latest
-   if: ${{ inputs.is_test }}
    environment:
      name: code_quality

Option B: Add if-no-files-found: ignore to artifact downloads (if APK is optional)

      - name: Download APK artifact
        uses: actions/download-artifact@v6.0.0
+       if: ${{ inputs.is_test }}
        with:
          name: apk
          path: work/packages/
      - name: Download Melange key artifact
        uses: actions/download-artifact@v6.0.0
+       if: ${{ inputs.is_test }}
        with:
          name: melange

Option C: Make build_image conditional on is_test (if image only needed for testing)

  build_image:
    name: Build and push Docker image to ${{ inputs.registry }}
    needs: build_apk
-   if: ${{ always() && !cancelled() }}
+   if: ${{ inputs.is_test && always() && !cancelled() }}
    runs-on: ubuntu-latest

Also applies to: 64-65, 94-101

🤖 Prompt for AI Agents
.github/workflows/.docker.yaml lines 26, 64-65, 94-101: the workflow currently
gates the build_apk job on inputs.is_test (line 26) but build_image runs
unconditionally (lines 64-65) and later tries to download APK artifacts (lines
94-101), causing failures when APK artifacts don't exist; fix by choosing one of
the three options: Option A (recommended) — remove or change the if on the
build_apk job so it always runs (delete the "if: ${{ inputs.is_test }}" at line
26 or set it to true) so the APK artifact is always produced; Option B — keep
current job gating but add if-no-files-found: ignore to the artifact download
steps at lines 94-101 so missing artifacts don’t fail the job; Option C — make
the build_image job conditional by adding the same "if: ${{ inputs.is_test }}"
at lines 64-65 so it only runs when APKs exist; apply the chosen change
consistently for both artifact downloads and job conditionals referenced above.

with:
registry: cgr.dev
image: chainguard/melange:latest-dev
options: --rm -v ${{ github.workspace }}:/work
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Add working directory flags to docker-run-action options.

The Melange commands (melange keygen and melange build) need to execute in /work where the workspace is mounted, but the current options don't set the working directory. Without -w /work, commands will run in the container's root and fail to find/generate configuration files and keys.

      - name: Install Melange
        uses: addnab/docker-run-action@v3
        with:
          registry: cgr.dev
          image: chainguard/melange:latest-dev
-         options: --rm -v ${{ github.workspace }}:/work
+         options: --rm -w /work -v ${{ github.workspace }}:/work
          run: melange keygen
          shell: bash
      - name: Build APK
        uses: addnab/docker-run-action@v3
        with:
          registry: cgr.dev
          image: chainguard/melange:latest-dev
-         options: --privileged --rm -v ${{ github.workspace }}:/work
+         options: --privileged --rm -w /work -v ${{ github.workspace }}:/work
          run: melange build melange.yaml --arch amd64 --signing-key melange.rsa
          shell: bash

Also applies to: 49-49

🤖 Prompt for AI Agents
.github/workflows/.docker.yaml around lines 41 and 49: the docker-run-action
options mount the workspace but don't set the container working directory, so
Melange commands run in the container root and can't find/generate files; update
the options values to include the working-dir flag (add -w /work) so the
container's process runs in the mounted workspace directory for both
occurrences.

uses: actions/upload-artifact@v5
with:
name: apk
path: packages/
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Fix artifact path mismatch between upload and download.

APK artifacts are uploaded from packages/ (line 56) but downloaded to work/packages/ (line 97). Update the upload path to match:

      - name: Upload APK artifact
        uses: actions/upload-artifact@v5
        with:
          name: apk
-         path: packages/
+         path: work/packages/

Also applies to: 97-97

🤖 Prompt for AI Agents
.github/workflows/.docker.yaml around line 56 (and also line 97): the artifact
upload path currently uses "packages/" but the workflow downloads from
"work/packages/" at line 97; update the upload step to use the same path by
changing the upload path to "work/packages/" so upload and download paths match
(ensure both occurrences reference the identical "work/packages/" directory).

@sonarqubecloud
Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
3 Security Hotspots

See analysis details on SonarQube Cloud

@mergify
Copy link
Copy Markdown
Contributor

mergify Bot commented Nov 23, 2025

Hi @MH0386, Your PR is in conflict and cannot be merged.

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.

3 participants