perf(ci): pre-baked images + cargo/npm caching (~70% faster builds) #36

Merged
sarman merged 7 commits from feat/pr-review-workflow into master 2026-04-13 01:23:50 +00:00
Owner

Summary

  • Switch all Rust CI jobs from rust:1.88-slim to the pre-baked trcaa-linux-amd64:rust1.88-node22 image (Tauri libs + Node.js + rustfmt + clippy already installed)
  • Switch build-windows-amd64 and build-linux-arm64 release jobs to trcaa-windows-cross and trcaa-linux-arm64 images respectively
  • Add actions/cache@v3 for Cargo registry (keyed on Cargo.lock) and npm (keyed on package-lock.json) to all Rust and build jobs
  • Bake rustfmt and clippy components into both Linux Dockerfiles so the images include everything test jobs need
  • Update docs/wiki/CICD-Pipeline.md with new sections: Pre-baked Builder Images, Cargo and npm Caching, and server prerequisites

Expected time savings

Job Before After
rust-fmt-check ~2 min ~20 sec
rust-clippy ~4 min ~45 sec
rust-tests ~5 min ~1.5 min
frontend-typecheck ~2 min ~30 sec
frontend-tests ~3 min ~40 sec
build-linux-amd64 ~10 min ~3 min
build-windows-amd64 ~12 min ~4 min
build-linux-arm64 ~15 min ~4 min
PR test total ~5 min ~1.5 min
Release total ~25 min ~7 min

Test plan

  • Trigger build-images.yml via workflow_dispatch before merging — new Dockerfiles add rustfmt/clippy; workflows assume they are present
  • Confirm {"insecure-registries":["172.0.0.29:3000"]} is in /etc/docker/daemon.json on the CI host
  • PR test suite passes with no apt-get or rustup component add output in job logs
  • Cache hit messages appear on a second run of the PR test suite
  • After merge, auto-tag.yml release builds complete without Install dependencies step and produce artifacts for all platforms
## Summary - Switch all Rust CI jobs from `rust:1.88-slim` to the pre-baked `trcaa-linux-amd64:rust1.88-node22` image (Tauri libs + Node.js + rustfmt + clippy already installed) - Switch `build-windows-amd64` and `build-linux-arm64` release jobs to `trcaa-windows-cross` and `trcaa-linux-arm64` images respectively - Add `actions/cache@v3` for Cargo registry (keyed on `Cargo.lock`) and npm (keyed on `package-lock.json`) to all Rust and build jobs - Bake `rustfmt` and `clippy` components into both Linux Dockerfiles so the images include everything test jobs need - Update `docs/wiki/CICD-Pipeline.md` with new sections: Pre-baked Builder Images, Cargo and npm Caching, and server prerequisites ## Expected time savings | Job | Before | After | |-----|--------|-------| | rust-fmt-check | ~2 min | ~20 sec | | rust-clippy | ~4 min | ~45 sec | | rust-tests | ~5 min | ~1.5 min | | frontend-typecheck | ~2 min | ~30 sec | | frontend-tests | ~3 min | ~40 sec | | build-linux-amd64 | ~10 min | ~3 min | | build-windows-amd64 | ~12 min | ~4 min | | build-linux-arm64 | ~15 min | ~4 min | | **PR test total** | **~5 min** | **~1.5 min** | | **Release total** | **~25 min** | **~7 min** | ## Test plan - [ ] Trigger `build-images.yml` via `workflow_dispatch` **before merging** — new Dockerfiles add `rustfmt`/`clippy`; workflows assume they are present - [ ] Confirm `{"insecure-registries":["172.0.0.29:3000"]}` is in `/etc/docker/daemon.json` on the CI host - [ ] PR test suite passes with no `apt-get` or `rustup component add` output in job logs - [ ] Cache hit messages appear on a second run of the PR test suite - [ ] After merge, `auto-tag.yml` release builds complete without `Install dependencies` step and produce artifacts for all platforms
sarman added 1 commit 2026-04-12 23:18:36 +00:00
perf(ci): use pre-baked images and add cargo/npm caching
Some checks failed
Test / rust-fmt-check (pull_request) Failing after 1s
Test / frontend-typecheck (pull_request) Successful in 2m47s
Test / rust-clippy (pull_request) Failing after 1s
Test / rust-tests (pull_request) Failing after 0s
PR Review Automation / review (pull_request) Successful in 3m25s
Test / frontend-tests (pull_request) Failing after 1m33s
f1461a0d7e
Switch all test and release build jobs from raw base images to the
pre-baked images already defined in .docker/ and pushed to the local
Gitea registry. Add actions/cache@v3 for Cargo registry and npm to
eliminate redundant downloads on subsequent runs.

Changes:
- Dockerfile.linux-amd64/arm64: bake in rustfmt and clippy components
- test.yml: rust jobs → trcaa-linux-amd64:rust1.88-node22; drop inline
  apt-get and rustup component-add steps; add cargo cache
- test.yml: frontend jobs → add npm cache
- auto-tag.yml: build-linux-amd64 → trcaa-linux-amd64; drop Install
  dependencies step and rustup target add
- auto-tag.yml: build-windows-amd64 → trcaa-windows-cross; drop Install
  dependencies step and rustup target add
- auto-tag.yml: build-linux-arm64 → trcaa-linux-arm64 (ubuntu:22.04-based);
  drop ~40-line Install dependencies step, . "$HOME/.cargo/env", and
  rustup target add (all pre-baked in image ENV PATH)
- All build jobs: add cargo and npm cache steps
- docs/wiki/CICD-Pipeline.md: document pre-baked images, cache keys,
  and insecure-registries daemon prerequisite

Expected savings: ~70% faster PR test suite (~1.5 min vs ~5 min),
~72% faster release builds (~7 min vs ~25 min) after cache warms up.

NOTE: Trigger build-images.yml via workflow_dispatch before merging
to ensure images contain rustfmt/clippy before workflow changes land.
sarman reviewed 2026-04-12 23:22:01 +00:00
sarman left a comment
Author
Owner

🤖 Automated PR Review:\n\n### Code Review: Pre-baked Images + Cargo/npm Caching


1. Summary

This PR significantly improves CI performance by:

  • Switching CI jobs to use pre-baked Docker images (trcaa-*) hosted on a local Gitea registry instead of installing dependencies at runtime.
  • Adding Cargo and npm caching via actions/cache@v3.
  • Including rustfmt and clippy components in Rust Dockerfiles.
  • Updating documentation and acceptance criteria.

Overall direction is excellent — reducing build time by ~70% is a major win.

⚠️ However, there are critical correctness and security issues that must be fixed before merging.


2. Bugs / Correctness Issues

🔴 Critical: rustup component add in Dockerfiles may fail if components already exist

In both Dockerfile.linux-amd64 and Dockerfile.linux-arm64, you added:

RUN rustup component add rustfmt clippy

Problem:
rustup component add fails with exit code 1 if components are already installed, even with --no-self-update. This will break Docker builds (and image rebuilds) unless the components are idempotently added.

Fix: Use || true or check first:

# Option 1 (simple, but hides other errors)
RUN rustup component add rustfmt clippy || true

# Option 2 (idempotent, safer)
RUN rustup component list --installed | grep -q rustfmt || rustup component add rustfmt
RUN rustup component list --installed | grep -q clippy || rustup component add clippy

💡 Rationale: rustup is strict about idempotency. This is a known pain point — see rust-lang/rustup#2702.


🔴 Critical: Gitea registry is HTTP (not HTTPS)

The images are hosted at 172.0.0.29:3000 — an insecure HTTP registry (no TLS).

Problem:

  • Docker requires explicit insecure-registries config (documented in CICD-Pipeline.md), but:
    • This is a security anti-pattern — pushes/pulls are unencrypted and unauthenticated.
    • If act_runner runs on shared/multi-tenant infrastructure, credentials or artifacts could leak.
    • Some CI runners (e.g., GitHub-hosted) block insecure registries by default.

Fix (choose one):

  1. Best: Use HTTPS with a valid cert (e.g., via Let’s Encrypt + reverse proxy like Nginx).
  2. Acceptable for internal use: Document the insecure registry requirement and enforce it programmatically:
    # In .gitea/workflows/*.yml, add a pre-check step:
    - name: Verify insecure registry config
      run: |
        if ! grep -q '"insecure-registries"' /etc/docker/daemon.json; then
          echo "ERROR: Insecure registry not configured. See docs/wiki/CICD-Pipeline.md"
          exit 1
        fi    
    
  3. Better long-term: Push images to a public registry (e.g., GitHub Container Registry) or use a signed/verified image supply chain (e.g., Cosign).

⚠️ Note: The PR description says "local Gitea registry" — this is fine only if the entire CI infrastructure is fully air-gapped/internal. If runners are public (e.g., self-hosted but internet-facing), this is a high-risk gap.


🟠 Bug: Cache keys may collide across architectures

In auto-tag.yml, the build-windows-amd64 and build-linux-arm64 jobs use:

key: ${{ runner.os }}-cargo-windows-${{ hashFiles('**/Cargo.lock') }}
key: ${{ runner.os }}-cargo-arm64-${{ hashFiles('**/Cargo.lock') }}

Problem:
runner.os is Linux for all three jobs (Linux-amd64, Linux-arm64, Windows-cross), so:

  • build-linux-amd64 → key: Linux-cargo-<hash>
  • build-linux-arm64 → key: Linux-cargo-arm64-<hash>
  • build-windows-amd64 → key: Linux-cargo-windows-<hash> (since runner is linux-amd64)

This is actually correct — you’re using cargo-windows/cargo-arm64 suffixes to disambiguate.

But:
In test.yml, the rust-* jobs all use Linux-cargo-<hash>, which is safe (same architecture, same toolchain), but:

  • If rust-fmt-check, clippy, and tests run in parallel, they’ll share the cache — good.
  • If any job modifies the cache (e.g., cargo build), it could cause race conditions.

Recommendation: Add --locked or --frozen to cargo commands to prevent accidental cache pollution (see best practices below).


🟠 Bug: apt-get install git removed but git may not be in image

In auto-tag.yml and test.yml, you removed:

- apt-get update -qq && apt-get install -y -qq git

from checkout steps.

Problem:
The pre-baked images (trcaa-*) are based on rust:1.88-slim (Debian-based), and git is not included by default in slim variants.

Fix:
Either:

  1. Add git to the Dockerfiles:
    RUN apt-get update -qq && apt-get install -y -qq git && rm -rf /var/lib/apt/lists/*
    
  2. Or install git in the workflow step (but this defeats the "no inline install" goal):
    - name: Checkout
      run: |
        apt-get update -qq && apt-get install -y -qq git
        git init ...    
    

🔍 Verify: Check Dockerfile.linux-amd64 — it installs git? No. So this will fail.


3. Security Issues

🔴 Critical: No image signing or verification
  • Images are pulled from 172.0.0.29:3000/... with no signature verification (e.g., Cosign, Notary).
  • If the registry is compromised, malicious code could be injected.

Fix:

  • Enable image signing (e.g., cosign sign --key ...).
  • In workflows, add:
    - name: Verify image signature
      run: cosign verify --key cosign.pub 172.0.0.29:3000/...:tag
    
🟠 Medium: Hardcoded registry IP
image: 172.0.0.29:3000/sarman/trcaa-linux-amd64:rust1.88-node22
  • Hardcoded IPs are brittle (change network? IP changes → CI breaks).
  • No DNS fallback or abstraction.

Fix:

  • Use a DNS name (e.g., gitea-registry.internal) + update /etc/hosts or DNS.
  • Or define a CI variable: ${{ vars.REGISTRY_URL }}.

4. Best Practices

Good: Cache key hygiene
  • Using hashFiles('**/Cargo.lock') is excellent — ensures cache invalidates on dependency changes.
  • Suffixing cross-compile keys (-windows, -arm64) prevents collisions.
Good: npm ci --legacy-peer-deps
  • Uses ci (not install) for deterministic builds.
  • --legacy-peer-deps is acceptable if peer deps are messy (but consider fixing peer deps long-term).
🟡 Opportunity: Use cargo build --locked in build steps

In auto-tag.yml, cargo fmt, clippy, and test use --manifest-path, but build steps do not enforce locked versions.

Recommendation:

- run: cargo build --locked --target x86_64-unknown-linux-gnu

This ensures builds use exactly the versions in Cargo.lock, not just compatible ones.

🟡 Opportunity: Avoid npm ci in test jobs?

test.yml uses npm ci in frontend-typecheck and test jobs — but these jobs only need TypeScript/Node.js, not full node_modules.

Consider:

  • Caching node_modules/.cache + node_modules/.bin instead of full node_modules.
  • Or use npm ci --ignore-scripts if scripts aren’t needed.
🟡 Opportunity: Document image rebuild triggers more clearly

In CICD-Pipeline.md, you list:

Rebuild triggers: Rust toolchain version bump, webkit2gtk/gtk major version change, Node.js major version change.

But:

  • What about openssl version changes? (used in OPENSSL_STATIC=1)
  • What about tauri CLI version changes? (may require new system deps)

Add:

  • Tauri CLI or tauri.conf.json changes that affect bundler dependencies
  • Major updates to OpenSSL, GTK, or WebKit2GTK (check Cargo.lock for webkit2gtk version)

Final Checklist Before Merge

Issue Status Action
rustup component add idempotency Critical Add `
git missing from images Critical Install git in Dockerfiles
Insecure HTTP registry ⚠️ High Add TLS or enforce insecure-registries config
No image signing ⚠️ Medium Add Cosign verification
Hardcoded registry IP ⚠️ Low Use DNS or CI variables
--locked in build steps 🟡 Optimize Add cargo build --locked
Cache pollution risk 🟡 Monitor Use --frozen/--locked to avoid accidental updates

Suggested Fixes Summary

  1. In Dockerfile.linux-amd64 and Dockerfile.linux-arm64:

    RUN rustup component list --installed | grep -q rustfmt || rustup component add rustfmt
    RUN rustup component list --installed | grep -q clippy || rustup component add clippy
    
  2. In all Dockerfiles:

    RUN apt-get update -qq && apt-get install -y -qq git && rm -rf /var/lib/apt/lists/*
    
  3. In docs/wiki/CICD-Pipeline.md:

    • Add: "⚠️ Security note: This setup uses an insecure HTTP registry. Ensure all runners are in a trusted network."
    • Add: "For production, replace 172.0.0.29:3000 with a TLS-enabled registry URL."
  4. In workflows (optional but recommended):

    - name: Verify git is installed
      run: git --version || (apt-get update && apt-get install -y git)
    

Verdict

Do not merge yet — fix the critical bugs (idempotent rustup, missing git, insecure registry risks) first. Once those are addressed, this is a high-impact, production-ready optimization.\n\n---\nthis is an automated review from Ollama

🤖 Automated PR Review:\n\n### **Code Review: Pre-baked Images + Cargo/npm Caching** --- #### **1. Summary** This PR significantly improves CI performance by: - Switching CI jobs to use **pre-baked Docker images** (`trcaa-*`) hosted on a local Gitea registry instead of installing dependencies at runtime. - Adding **Cargo and npm caching** via `actions/cache@v3`. - Including `rustfmt` and `clippy` components in Rust Dockerfiles. - Updating documentation and acceptance criteria. ✅ **Overall direction is excellent** — reducing build time by ~70% is a major win. ⚠️ **However**, there are **critical correctness and security issues** that must be fixed before merging. --- #### **2. Bugs / Correctness Issues** ##### 🔴 **Critical: `rustup component add` in Dockerfiles may fail if components already exist** In both `Dockerfile.linux-amd64` and `Dockerfile.linux-arm64`, you added: ```dockerfile RUN rustup component add rustfmt clippy ``` **Problem**: `rustup component add` **fails with exit code 1** if components are *already installed*, even with `--no-self-update`. This will break Docker builds (and image rebuilds) unless the components are idempotently added. ✅ **Fix**: Use `|| true` or check first: ```dockerfile # Option 1 (simple, but hides other errors) RUN rustup component add rustfmt clippy || true # Option 2 (idempotent, safer) RUN rustup component list --installed | grep -q rustfmt || rustup component add rustfmt RUN rustup component list --installed | grep -q clippy || rustup component add clippy ``` > 💡 **Rationale**: `rustup` is strict about idempotency. This is a known pain point — see [rust-lang/rustup#2702](https://github.com/rust-lang/rustup/issues/2702). --- ##### 🔴 **Critical: Gitea registry is HTTP (not HTTPS)** The images are hosted at `172.0.0.29:3000` — an **insecure HTTP registry** (no TLS). **Problem**: - Docker requires explicit `insecure-registries` config (documented in `CICD-Pipeline.md`), but: - This is a **security anti-pattern** — pushes/pulls are unencrypted and unauthenticated. - If `act_runner` runs on shared/multi-tenant infrastructure, credentials or artifacts could leak. - Some CI runners (e.g., GitHub-hosted) **block insecure registries by default**. ✅ **Fix** (choose one): 1. **Best**: Use HTTPS with a valid cert (e.g., via Let’s Encrypt + reverse proxy like Nginx). 2. **Acceptable for internal use**: Document the insecure registry requirement **and** enforce it programmatically: ```yaml # In .gitea/workflows/*.yml, add a pre-check step: - name: Verify insecure registry config run: | if ! grep -q '"insecure-registries"' /etc/docker/daemon.json; then echo "ERROR: Insecure registry not configured. See docs/wiki/CICD-Pipeline.md" exit 1 fi ``` 3. **Better long-term**: Push images to a public registry (e.g., GitHub Container Registry) or use a signed/verified image supply chain (e.g., Cosign). > ⚠️ **Note**: The PR description says "local Gitea registry" — this is fine *only* if the entire CI infrastructure is fully air-gapped/internal. If runners are public (e.g., self-hosted but internet-facing), this is a high-risk gap. --- ##### 🟠 **Bug: Cache keys may collide across architectures** In `auto-tag.yml`, the `build-windows-amd64` and `build-linux-arm64` jobs use: ```yaml key: ${{ runner.os }}-cargo-windows-${{ hashFiles('**/Cargo.lock') }} key: ${{ runner.os }}-cargo-arm64-${{ hashFiles('**/Cargo.lock') }} ``` **Problem**: `runner.os` is `Linux` for all three jobs (Linux-amd64, Linux-arm64, Windows-cross), so: - `build-linux-amd64` → key: `Linux-cargo-<hash>` - `build-linux-arm64` → key: `Linux-cargo-arm64-<hash>` - `build-windows-amd64` → key: `Linux-cargo-windows-<hash>` (since runner is `linux-amd64`) ✅ **This is actually correct** — you’re using `cargo-windows`/`cargo-arm64` suffixes to disambiguate. But: ❌ **In `test.yml`, the `rust-*` jobs all use `Linux-cargo-<hash>`**, which is **safe** (same architecture, same toolchain), but: - If `rust-fmt-check`, `clippy`, and `tests` run in parallel, they’ll share the cache — good. - If any job modifies the cache (e.g., `cargo build`), it could cause race conditions. ✅ **Recommendation**: Add `--locked` or `--frozen` to `cargo` commands to prevent accidental cache pollution (see best practices below). --- ##### 🟠 **Bug: `apt-get install git` removed but `git` may not be in image** In `auto-tag.yml` and `test.yml`, you removed: ```yaml - apt-get update -qq && apt-get install -y -qq git ``` from checkout steps. **Problem**: The pre-baked images (`trcaa-*`) are based on `rust:1.88-slim` (Debian-based), and `git` is **not included by default** in `slim` variants. ✅ **Fix**: Either: 1. Add `git` to the Dockerfiles: ```dockerfile RUN apt-get update -qq && apt-get install -y -qq git && rm -rf /var/lib/apt/lists/* ``` 2. Or install `git` in the workflow step (but this defeats the "no inline install" goal): ```yaml - name: Checkout run: | apt-get update -qq && apt-get install -y -qq git git init ... ``` > 🔍 **Verify**: Check `Dockerfile.linux-amd64` — it installs `git`? No. So this will fail. --- #### **3. Security Issues** ##### 🔴 **Critical: No image signing or verification** - Images are pulled from `172.0.0.29:3000/...` with no signature verification (e.g., Cosign, Notary). - If the registry is compromised, malicious code could be injected. ✅ **Fix**: - Enable image signing (e.g., `cosign sign --key ...`). - In workflows, add: ```yaml - name: Verify image signature run: cosign verify --key cosign.pub 172.0.0.29:3000/...:tag ``` ##### 🟠 **Medium: Hardcoded registry IP** ```yaml image: 172.0.0.29:3000/sarman/trcaa-linux-amd64:rust1.88-node22 ``` - Hardcoded IPs are brittle (change network? IP changes → CI breaks). - No DNS fallback or abstraction. ✅ **Fix**: - Use a DNS name (e.g., `gitea-registry.internal`) + update `/etc/hosts` or DNS. - Or define a CI variable: `${{ vars.REGISTRY_URL }}`. --- #### **4. Best Practices** ##### ✅ **Good: Cache key hygiene** - Using `hashFiles('**/Cargo.lock')` is excellent — ensures cache invalidates on dependency changes. - Suffixing cross-compile keys (`-windows`, `-arm64`) prevents collisions. ##### ✅ **Good: `npm ci --legacy-peer-deps`** - Uses `ci` (not `install`) for deterministic builds. - `--legacy-peer-deps` is acceptable if peer deps are messy (but consider fixing peer deps long-term). ##### 🟡 **Opportunity: Use `cargo build --locked` in build steps** In `auto-tag.yml`, `cargo fmt`, `clippy`, and `test` use `--manifest-path`, but build steps do not enforce locked versions. ✅ **Recommendation**: ```yaml - run: cargo build --locked --target x86_64-unknown-linux-gnu ``` This ensures builds use *exactly* the versions in `Cargo.lock`, not just compatible ones. ##### 🟡 **Opportunity: Avoid `npm ci` in test jobs?** `test.yml` uses `npm ci` in `frontend-typecheck` and `test` jobs — but these jobs only need TypeScript/Node.js, not full `node_modules`. ✅ **Consider**: - Caching `node_modules/.cache` + `node_modules/.bin` instead of full `node_modules`. - Or use `npm ci --ignore-scripts` if scripts aren’t needed. ##### 🟡 **Opportunity: Document image rebuild triggers more clearly** In `CICD-Pipeline.md`, you list: > **Rebuild triggers:** Rust toolchain version bump, webkit2gtk/gtk major version change, Node.js major version change. But: - What about `openssl` version changes? (used in `OPENSSL_STATIC=1`) - What about `tauri` CLI version changes? (may require new system deps) ✅ **Add**: > - Tauri CLI or `tauri.conf.json` changes that affect bundler dependencies > - Major updates to OpenSSL, GTK, or WebKit2GTK (check `Cargo.lock` for `webkit2gtk` version) --- ### **Final Checklist Before Merge** | Issue | Status | Action | |-------|--------|--------| | `rustup component add` idempotency | ❌ Critical | Add `|| true` or check-installed logic | | `git` missing from images | ❌ Critical | Install `git` in Dockerfiles | | Insecure HTTP registry | ⚠️ High | Add TLS or enforce `insecure-registries` config | | No image signing | ⚠️ Medium | Add Cosign verification | | Hardcoded registry IP | ⚠️ Low | Use DNS or CI variables | | `--locked` in build steps | 🟡 Optimize | Add `cargo build --locked` | | Cache pollution risk | 🟡 Monitor | Use `--frozen`/`--locked` to avoid accidental updates | --- ### **Suggested Fixes Summary** 1. **In `Dockerfile.linux-amd64` and `Dockerfile.linux-arm64`**: ```dockerfile RUN rustup component list --installed | grep -q rustfmt || rustup component add rustfmt RUN rustup component list --installed | grep -q clippy || rustup component add clippy ``` 2. **In all Dockerfiles**: ```dockerfile RUN apt-get update -qq && apt-get install -y -qq git && rm -rf /var/lib/apt/lists/* ``` 3. **In `docs/wiki/CICD-Pipeline.md`**: - Add: "⚠️ **Security note**: This setup uses an insecure HTTP registry. Ensure all runners are in a trusted network." - Add: "For production, replace `172.0.0.29:3000` with a TLS-enabled registry URL." 4. **In workflows** (optional but recommended): ```yaml - name: Verify git is installed run: git --version || (apt-get update && apt-get install -y git) ``` --- ### **Verdict** **Do not merge yet** — fix the **critical bugs** (idempotent `rustup`, missing `git`, insecure registry risks) first. Once those are addressed, this is a **high-impact, production-ready optimization**.\n\n---\n*this is an automated review from Ollama*
sarman added 1 commit 2026-04-12 23:29:43 +00:00
fix(ci): address AI review — rustup idempotency and cargo --locked
Some checks failed
Test / rust-fmt-check (pull_request) Failing after 0s
PR Review Automation / review (pull_request) Successful in 4m19s
Test / rust-clippy (pull_request) Failing after 2s
Test / frontend-typecheck (pull_request) Successful in 1m45s
Test / rust-tests (pull_request) Failing after 1s
Test / frontend-tests (pull_request) Failing after 1m35s
f59559327e
Dockerfiles:
- Merge rustup target add and component add into one chained RUN with
  || true guard, making it safe if rustfmt/clippy are already present
  in the base image's default toolchain profile (rust:1.88-slim default
  profile includes both; the guard is belt-and-suspenders)

test.yml:
- Add --locked to cargo clippy and cargo test to enforce Cargo.lock
  during CI, preventing silent dependency upgrades

Not addressed (accepted/out of scope):
- git in images: already installed in all three Dockerfiles (lines 19,
  13, 15 respectively) — reviewer finding was incorrect
- HTTP registry: accepted risk for air-gapped self-hosted infrastructure
- Image signing (Cosign): no infrastructure in place yet
- Hardcoded registry IP: consistent with project-wide pattern
sarman added 1 commit 2026-04-12 23:30:23 +00:00
fix(ci): replace docker:24-cli with alpine + docker-cli in build-images
Some checks failed
Test / rust-clippy (pull_request) Failing after 1s
Test / frontend-typecheck (pull_request) Successful in 1m29s
Test / rust-tests (pull_request) Failing after 1s
Test / frontend-tests (pull_request) Failing after 1m21s
PR Review Automation / review (pull_request) Successful in 3m55s
Test / rust-fmt-check (pull_request) Failing after 1s
1d0f420042
act_runner v0.3.1 has special-case handling for images named docker:*:
it automatically adds /var/run/docker.sock to the container's bind
mounts. The runner's own global config already mounts the socket, so
the two entries collide and the container fails to start with
"Duplicate mount point: /var/run/docker.sock".

Fix: use alpine:latest (no special handling) and install docker-cli
via apk alongside git in each Checkout step. The docker socket is
still available via the runner's global bind — we just stop triggering
the duplicate.
sarman reviewed 2026-04-12 23:34:02 +00:00
sarman left a comment
Author
Owner

🤖 Automated PR Review:\n\nThis PR introduces significant performance improvements by leveraging pre-baked Docker images and caching, aiming for ~70% faster builds. Below is a detailed review covering correctness, security, and best practices, with actionable suggestions.


1. Summary of Changes

Area Change Benefit
Dockerfiles Added rustfmt/clippy components (with `
CI Workflows Replaced generic rust:1.88-slim/ubuntu:22.04 images with custom pre-baked images (trcaa-*) Eliminates repeated apt-get/rustup setup → faster, more reproducible builds
Caching Added actions/cache@v3 for ~/.cargo/registry and ~/.npm Reduces redundant downloads, especially for incremental builds
Build Images Workflow Switched docker:24-clialpine:latest + docker-cli Lighter, more minimal base for building images (though see ⚠️ below)
Docs Updated CICD-Pipeline.md with new image strategy and caching Improves maintainability and onboarding

⚠️ 2. Critical & High-Impact Issues

🔴 A. Security: Insecure Registry Usage

Issue:
The PR assumes access to a local HTTP registry (172.0.0.29:3000) without TLS. This is explicitly flagged in the docs:

Server prerequisite — insecure registry (one-time, on 172.0.0.29):
echo '{"insecure-registries":["172.0.0.29:3000"]}' | sudo tee /etc/docker/daemon.json

Risk:

  • Man-in-the-middle attacks (MITM) on image pulls.
  • Tampering with base images (e.g., supply-chain compromise).
  • Violates security best practices (TLS required in production).

Recommendation:

  • Short term: Document clearly that this is for internal dev/test only, not production.
  • Medium term: Use a self-signed cert + proper CA trust (e.g., via ca-certificates), or migrate to a registry with TLS.
  • Better: Use Gitea’s built-in container registry with HTTPS (requires reverse proxy + cert, e.g., via Caddy/Nginx).
  • Do not enable insecure-registries in production or shared runners.

🟠 B. Dockerfile || true on rustup component add

Issue:
In both Dockerfiles:

&& rustup component add rustfmt clippy || true

Problem:

  • rustup component add fails if components are already installed (e.g., on rebuilds or image reuse).
  • || true masks failures — e.g., if rustup is broken, the build silently continues without fmt/clippy.
  • This defeats the purpose of pre-baking tooling.

Fix:

# Option 1: Idempotent install (preferred)
&& rustup component add --toolchain 1.88.0 rustfmt clippy 2>/dev/null || true

# Option 2: Check before adding
&& if ! rustup component list --installed | grep -q rustfmt; then rustup component add rustfmt; fi \
&& if ! rustup component list --installed | grep -q clippy; then rustup component add clippy; fi

💡 Bonus: Add a health check in the image (e.g., RUN rustfmt --version && clippy --version) to fail fast if components are missing.


🟠 C. alpine:latest in build-images.yml

Issue:

container:
  image: alpine:latest

latest is non-deterministic. Alpine changes break builds unexpectedly.

Fix: Pin to a specific version (e.g., alpine:3.20 or alpine:3.19), especially since this is a build-time dependency.

Also: docker-cli is installed via apk, but docker daemon isn’t available inside the container.
→ This only works if the runner uses Docker-in-Docker (DinD) or rootless Docker, but the workflow doesn’t clarify this.

Recommendation:

  • Clarify the runner setup (e.g., "uses Docker socket mounting" or "uses Kaniko/Buildah").
  • Prefer docker:dind + docker buildx for reliability, or switch to kaniko for safer builds.

🟡 3. Medium-Impact Issues

🔶 D. Cache Key Collision Risk

Issue:
All jobs use runner.os in cache keys:

key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}

But runner.os is Linux, Windows, etc. — not architecture-specific.

However, cross-compile jobs (arm64, Windows) use different Cargo.lock files (due to --target), but the cache key doesn’t distinguish them.

Risk:

  • Cache pollution: arm64 build might restore amd64 Cargo.lock artifacts → build errors or wasted bandwidth.

Fix: Include target in cache key:

key: ${{ runner.os }}-cargo-${{ matrix.target || 'default' }}-${{ hashFiles('**/Cargo.lock') }}

Or use a more specific key (e.g., cargo-${{ hashFiles('**/Cargo.lock') }}-${{ hashFiles('**/Cargo.toml') }}).

Already partially done for Windows/arm64 (-cargo-windows-, -cargo-arm64-), but inconsistent.


🔶 E. Missing --locked in cargo fmt/clippy

Issue:
cargo fmt --check and cargo clippy do not use --locked, while cargo test does:

# test.yml
- run: cargo fmt --manifest-path src-tauri/Cargo.toml --check
- run: cargo clippy --locked --manifest-path ...

Risk:

  • cargo fmt/clippy might use different dependency versions than cargo test, leading to:
    • False positives/negatives.
    • Inconsistent linting vs. test results.

Fix:
Add --locked to all Rust tooling commands:

- run: cargo fmt --locked --manifest-path src-tauri/Cargo.toml --check
- run: cargo clippy --locked --manifest-path src-tauri/Cargo.toml ...

🔶 F. git init + git fetch in CI is redundant

Issue:
All workflows do:

git init
git remote add origin ...
git fetch --depth=1 origin "$GITHUB_SHA"
git checkout FETCH_HEAD

But actions/checkout@v4 (or git fetch directly) would be simpler and more robust.

Why it matters:

  • git init + manual fetch is error-prone (e.g., if GITHUB_SHA is missing).
  • actions/checkout handles submodules, shallow clones, and auth better.

Recommendation:
Replace with:

- uses: actions/checkout@v4
  with:
    ref: ${{ github.sha }}
    fetch-depth: 1

Note: This requires GITHUB_TOKEN permissions, but the current setup uses http://... (no auth), so it may not work. If so, keep the manual fetch but add error handling.


4. Best Practices Followed Well

Practice Evidence
Reproducibility Pinning Rust 1.88.0, Node.js 22.x, and using --profile minimal in rustup.
Minimal images --no-install-recommends, rm -rf /var/lib/apt/lists/*, --no-modify-path.
Caching Proper use of actions/cache@v3, restore-keys, and hash-based keys.
Documentation Clear table in CICD-Pipeline.md explaining images, triggers, and rebuild triggers.
Idempotency `

📝 5. Suggested Fixes Summary

Priority Issue Fix
🔴 Critical Insecure registry Add TLS or clearly document as dev-only.
🔴 Critical `
🟠 High alpine:latest Pin to alpine:3.20 (or similar).
🟠 High Cache key collision risk Include target in cache key (e.g., cargo-${{ matrix.target }}-...).
🟡 Medium Missing --locked in fmt/clippy Add --locked to all cargo commands.
🟡 Medium Manual git setup Prefer actions/checkout@v4 (if auth works) or improve error handling.

Final Verdict

This PR is a net positive for performance and maintainability — the pre-baked images and caching are well-designed in concept. However, security and correctness gaps must be fixed before merging:

  • Do not merge with insecure-registries enabled in production.
  • Do not merge with || true masking rustup failures.
  • Fix cache key collisions to avoid flaky builds.

Once those are addressed, this is a strong, production-ready optimization.


Would you like me to draft a revised Dockerfile + workflow snippet for the critical fixes?\n\n---\nthis is an automated review from Ollama

🤖 Automated PR Review:\n\nThis PR introduces significant performance improvements by leveraging pre-baked Docker images and caching, aiming for ~70% faster builds. Below is a detailed **review covering correctness, security, and best practices**, with actionable suggestions. --- ## ✅ **1. Summary of Changes** | Area | Change | Benefit | |------|--------|---------| | **Dockerfiles** | Added `rustfmt`/`clippy` components (with `|| true`) | Ensures tooling is available in images | | **CI Workflows** | Replaced generic `rust:1.88-slim`/`ubuntu:22.04` images with custom pre-baked images (`trcaa-*`) | Eliminates repeated `apt-get`/`rustup` setup → faster, more reproducible builds | | **Caching** | Added `actions/cache@v3` for `~/.cargo/registry` and `~/.npm` | Reduces redundant downloads, especially for incremental builds | | **Build Images Workflow** | Switched `docker:24-cli` → `alpine:latest` + `docker-cli` | Lighter, more minimal base for building images (though see ⚠️ below) | | **Docs** | Updated `CICD-Pipeline.md` with new image strategy and caching | Improves maintainability and onboarding | --- ## ⚠️ **2. Critical & High-Impact Issues** ### 🔴 **A. Security: Insecure Registry Usage** **Issue**: The PR assumes access to a **local HTTP registry** (`172.0.0.29:3000`) without TLS. This is explicitly flagged in the docs: > Server prerequisite — insecure registry (one-time, on 172.0.0.29): > `echo '{"insecure-registries":["172.0.0.29:3000"]}' | sudo tee /etc/docker/daemon.json` **Risk**: - Man-in-the-middle attacks (MITM) on image pulls. - Tampering with base images (e.g., supply-chain compromise). - Violates security best practices (TLS required in production). **Recommendation**: - ✅ **Short term**: Document clearly that this is for *internal dev/test only*, not production. - ✅ **Medium term**: Use a self-signed cert + proper CA trust (e.g., via `ca-certificates`), or migrate to a registry with TLS. - ✅ **Better**: Use Gitea’s built-in container registry with HTTPS (requires reverse proxy + cert, e.g., via Caddy/Nginx). - ❌ **Do not** enable `insecure-registries` in production or shared runners. --- ### 🟠 **B. Dockerfile `|| true` on `rustup component add`** **Issue**: In both Dockerfiles: ```Dockerfile && rustup component add rustfmt clippy || true ``` **Problem**: - `rustup component add` fails if components are already installed (e.g., on rebuilds or image reuse). - `|| true` masks failures — e.g., if `rustup` is broken, the build *silently continues without fmt/clippy*. - This defeats the purpose of pre-baking tooling. **Fix**: ```Dockerfile # Option 1: Idempotent install (preferred) && rustup component add --toolchain 1.88.0 rustfmt clippy 2>/dev/null || true # Option 2: Check before adding && if ! rustup component list --installed | grep -q rustfmt; then rustup component add rustfmt; fi \ && if ! rustup component list --installed | grep -q clippy; then rustup component add clippy; fi ``` > 💡 **Bonus**: Add a health check in the image (e.g., `RUN rustfmt --version && clippy --version`) to fail fast if components are missing. --- ### 🟠 **C. `alpine:latest` in `build-images.yml`** **Issue**: ```yaml container: image: alpine:latest ``` → `latest` is **non-deterministic**. Alpine changes break builds unexpectedly. **Fix**: Pin to a specific version (e.g., `alpine:3.20` or `alpine:3.19`), especially since this is a *build-time dependency*. Also: `docker-cli` is installed via `apk`, but `docker` daemon isn’t available inside the container. → This only works if the runner uses **Docker-in-Docker (DinD)** or **rootless Docker**, but the workflow doesn’t clarify this. **Recommendation**: - Clarify the runner setup (e.g., "uses Docker socket mounting" or "uses Kaniko/Buildah"). - Prefer `docker:dind` + `docker buildx` for reliability, or switch to `kaniko` for safer builds. --- ## 🟡 **3. Medium-Impact Issues** ### 🔶 **D. Cache Key Collision Risk** **Issue**: All jobs use `runner.os` in cache keys: ```yaml key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} ``` But `runner.os` is `Linux`, `Windows`, etc. — **not architecture-specific**. However, cross-compile jobs (arm64, Windows) use *different* `Cargo.lock` files (due to `--target`), but the cache key doesn’t distinguish them. **Risk**: - Cache pollution: arm64 build might restore amd64 `Cargo.lock` artifacts → build errors or wasted bandwidth. **Fix**: Include target in cache key: ```yaml key: ${{ runner.os }}-cargo-${{ matrix.target || 'default' }}-${{ hashFiles('**/Cargo.lock') }} ``` Or use a more specific key (e.g., `cargo-${{ hashFiles('**/Cargo.lock') }}-${{ hashFiles('**/Cargo.toml') }}`). > ✅ Already partially done for Windows/arm64 (`-cargo-windows-`, `-cargo-arm64-`), but inconsistent. --- ### 🔶 **E. Missing `--locked` in `cargo fmt`/`clippy`** **Issue**: `cargo fmt --check` and `cargo clippy` **do not use `--locked`**, while `cargo test` does: ```yaml # test.yml - run: cargo fmt --manifest-path src-tauri/Cargo.toml --check - run: cargo clippy --locked --manifest-path ... ``` **Risk**: - `cargo fmt`/`clippy` might use *different* dependency versions than `cargo test`, leading to: - False positives/negatives. - Inconsistent linting vs. test results. **Fix**: Add `--locked` to all Rust tooling commands: ```yaml - run: cargo fmt --locked --manifest-path src-tauri/Cargo.toml --check - run: cargo clippy --locked --manifest-path src-tauri/Cargo.toml ... ``` --- ### 🔶 **F. `git init` + `git fetch` in CI is redundant** **Issue**: All workflows do: ```yaml git init git remote add origin ... git fetch --depth=1 origin "$GITHUB_SHA" git checkout FETCH_HEAD ``` But `actions/checkout@v4` (or `git fetch` directly) would be simpler and more robust. **Why it matters**: - `git init` + manual fetch is error-prone (e.g., if `GITHUB_SHA` is missing). - `actions/checkout` handles submodules, shallow clones, and auth better. **Recommendation**: Replace with: ```yaml - uses: actions/checkout@v4 with: ref: ${{ github.sha }} fetch-depth: 1 ``` > Note: This requires `GITHUB_TOKEN` permissions, but the current setup uses `http://...` (no auth), so it may not work. If so, keep the manual fetch but add error handling. --- ## ✅ **4. Best Practices Followed Well** | Practice | Evidence | |---------|----------| | **Reproducibility** | Pinning Rust 1.88.0, Node.js 22.x, and using `--profile minimal` in `rustup`. | | **Minimal images** | `--no-install-recommends`, `rm -rf /var/lib/apt/lists/*`, `--no-modify-path`. | | **Caching** | Proper use of `actions/cache@v3`, `restore-keys`, and hash-based keys. | | **Documentation** | Clear table in `CICD-Pipeline.md` explaining images, triggers, and rebuild triggers. | | **Idempotency** | `|| true` (though flawed — see above), but `npm ci` ensures deterministic installs. | --- ## 📝 **5. Suggested Fixes Summary** | Priority | Issue | Fix | |--------|-------|-----| | 🔴 **Critical** | Insecure registry | Add TLS or clearly document as dev-only. | | 🔴 **Critical** | `|| true` on `rustup component add` | Replace with idempotent install or health check. | | 🟠 **High** | `alpine:latest` | Pin to `alpine:3.20` (or similar). | | 🟠 **High** | Cache key collision risk | Include target in cache key (e.g., `cargo-${{ matrix.target }}-...`). | | 🟡 **Medium** | Missing `--locked` in fmt/clippy | Add `--locked` to all `cargo` commands. | | 🟡 **Medium** | Manual `git` setup | Prefer `actions/checkout@v4` (if auth works) or improve error handling. | --- ## ✅ **Final Verdict** **This PR is a net positive for performance and maintainability** — the pre-baked images and caching are well-designed *in concept*. However, **security and correctness gaps must be fixed before merging**: - **Do not merge** with `insecure-registries` enabled in production. - **Do not merge** with `|| true` masking `rustup` failures. - **Fix cache key collisions** to avoid flaky builds. Once those are addressed, this is a **strong, production-ready optimization**. --- Would you like me to draft a revised Dockerfile + workflow snippet for the critical fixes?\n\n---\n*this is an automated review from Ollama*
sarman reviewed 2026-04-12 23:34:47 +00:00
sarman left a comment
Author
Owner

🤖 Automated PR Review:\n\nHere's a comprehensive review of the PR changes, covering correctness, security, and best practices:


1. Summary of Changes

This PR improves CI performance by:

  • Pre-baking Docker images with all dependencies (Rust toolchain, Node.js, Tauri dev libs, cross-compilers)
  • Adding Cargo & npm caching via actions/cache@v3
  • Removing redundant apt-get/rustup setup steps in CI workflows
  • Updating documentation (CICD-Pipeline.md) to reflect new architecture

2. Correctness Assessment

✔️ Dockerfile Changes

  • rustup component add rustfmt clippy || true is safe and correct:
    • || true prevents build failure if components are already installed (idempotent).
    • rustup component add is safe to run multiple times.
    • Good practice: avoids build flakiness due to incremental updates.

✔️ Workflow Changes

  • Removed rustup target add in build steps → correct, since target is pre-installed in images.
  • Removed apt-get install of system deps → correct, since images are pre-baked.
  • Removed apt-get install git in checkout steps → correct (git is part of pre-baked images).
  • Added --locked to cargo clippy/test excellent: ensures reproducibility and prevents accidental version drift.

⚠️ Potential Issue: Missing source "$HOME/.cargo/env" in ARM64 workflow

-      - name: Build
         env:
           CC_aarch64_unknown_linux_gnu: aarch64-linux-gnu-gcc
           OPENSSL_STATIC: "1"
           APPIMAGE_EXTRACT_AND_RUN: "1"
         run: |
-          . "$HOME/.cargo/env"
           npm ci --legacy-peer-deps
-          rustup target add aarch64-unknown-linux-gnu
           CI=true npx tauri build --target aarch64-unknown-linux-gnu --bundles deb,rpm
  • Problem: . "$HOME/.cargo/env" was removed, but rustup is installed in /root/.cargo/bin, and PATH is set in Dockerfile only for the ARM64 Dockerfile:

    ENV PATH="/root/.cargo/bin:${PATH}"
    

    This is safe because the Dockerfile sets PATH, so rustup/cargo are available.

  • However, the arm64 Dockerfile uses:

    RUN curl --proto ... | sh -s -- ... --no-modify-path
    

    and later sets PATH. This is correct — but only if the image is built after this change.
    🔍 Recommendation: Verify that trcaa-linux-arm64:rust1.88-node22 includes the PATH env in its Dockerfile (it does — line 43).

Verdict: Correct — but critical to ensure image rebuilds happen before merging.


🔒 3. Security Issues

⚠️ Insecure Registry Usage

  • Documented prerequisite:
    echo '{"insecure-registries":["172.0.0.29:3000"]}' | sudo tee /etc/docker/daemon.json
    
  • Risk: Using HTTP (not HTTPS) for a registry exposes traffic to MITM attacks.
    • 172.0.0.29 is a private IP — low external risk, but still violates defense-in-depth.
    • If this registry is ever exposed (e.g., misconfigured firewall), credentials/secrets could leak.

Mitigation:

  • Strongly recommend adding TLS (e.g., self-signed cert + insecure-registriesregistry-mirrors with CA).
  • At minimum: document the risk in CICD-Pipeline.md and restrict registry access via firewall.

⚠️ Hardcoded Registry URL

  • 172.0.0.29:3000 is hardcoded in:
    • Dockerfiles (not present, but in workflows)
    • Workflow images
    • Docs
  • Risk: Hard to rotate or migrate registry.
  • Best Practice: Use an environment variable or CI secret (e.g., REGISTRY_URL).
    container:
      image: ${{ env.REGISTRY_URL }}/sarman/trcaa-linux-amd64:rust1.88-node22
    
  • Suggestion: Add REGISTRY_URL as a repo variable (e.g., REGISTRY_URL=172.0.0.29:3000).

No other security issues

  • No secrets in logs (good).
  • --no-install-recommends, rm -rf /var/lib/apt/lists/* — best practices followed.
  • sh.rustup.rs via --proto '=https' --tlsv1.2 — safe.

🛠️ 4. Best Practices

Excellent Caching Strategy

  • Cargo cache keys use Cargo.lock hash → correct.
  • npm cache uses package-lock.json hash → correct.
  • restore-keys fallbacks ensure partial cache hits (e.g., after lockfile changes).
  • Best practice: Avoids full re-downloads.

Idempotent Dockerfile Steps

  • || true on rustup component add → safe.
  • --no-install-recommends → minimal image size.

Documentation Improvements

  • Clear table of images/contents.
  • Rebuild triggers documented.
  • Prerequisites (insecure registry) clearly called out.

⚠️ Minor: Use of || true in Dockerfile

  • While safe, consider:
    RUN rustup component add rustfmt clippy 2>/dev/null || true
    
    to suppress noise in logs (optional).

⚠️ build-images.yml Container Image Change

  • Changed from docker:24-clialpine:latest
    • Problem: alpine:latest is not pinned → may break if Alpine changes.
    • Fix: Use pinned version, e.g., alpine:3.19.
    • Also: docker-cli is installed, but docker daemon may not be available — unless docker-in-docker is used (not obvious from diff).
      Verify: Does this workflow actually build/push images? If yes, it likely uses dockerd or docker buildx, which requires privileged mode or Docker-in-Docker (DinD).
      🔍 Check: Is services: docker defined? (Not in diff — may be missing.)

Workflow Cleanup

  • Removed redundant apt-get update/install steps → faster, cleaner, more reproducible.
  • Removed GITHUB_PATH usage (not needed since PATH is set in Dockerfile).

📋 Recommendations Summary

Category Issue Severity Fix
Security Insecure HTTP registry ⚠️ Medium Add TLS; document risk
Reliability alpine:latest unpinned ⚠️ Medium Pin to alpine:3.19
Reliability Registry URL hardcoded ⚠️ Low Use env var (REGISTRY_URL)
Reliability Missing DinD config in build-images.yml ⚠️ Medium-High Confirm DinD setup or use docker:dind service
Best Practice ` true` in Dockerfile
Best Practice --locked in cargo commands Excellent Keep!

Final Verdict

Approve with conditions:

  1. Correctness: All changes are logically sound and improve reproducibility.
  2. ⚠️ Security: Address insecure registry (TLS + docs).
  3. ⚠️ Reliability: Pin alpine version; confirm DinD setup.
  4. Performance: Achieves stated goal (~70% faster builds via pre-baking + caching).

Before merging:

  • Rebuild all images after merging Dockerfile changes.
  • Test build-images.yml to ensure it can push to 172.0.0.29:3000.
  • Add TLS to registry (or document risk mitigation).

Let me know if you'd like a patch for the insecure registry or alpine pinning!\n\n---\nthis is an automated review from Ollama

🤖 Automated PR Review:\n\nHere's a comprehensive review of the PR changes, covering correctness, security, and best practices: --- ### ✅ **1. Summary of Changes** This PR improves CI performance by: - **Pre-baking Docker images** with all dependencies (Rust toolchain, Node.js, Tauri dev libs, cross-compilers) - **Adding Cargo & npm caching** via `actions/cache@v3` - **Removing redundant `apt-get`/`rustup` setup steps** in CI workflows - **Updating documentation** (`CICD-Pipeline.md`) to reflect new architecture --- ### ✅ **2. Correctness Assessment** #### ✔️ **Dockerfile Changes** - `rustup component add rustfmt clippy || true` is **safe and correct**: - `|| true` prevents build failure if components are already installed (idempotent). - `rustup component add` is safe to run multiple times. - ✅ **Good practice**: avoids build flakiness due to incremental updates. #### ✔️ **Workflow Changes** - **Removed `rustup target add`** in build steps → ✅ correct, since target is pre-installed in images. - **Removed `apt-get install`** of system deps → ✅ correct, since images are pre-baked. - **Removed `apt-get install git`** in checkout steps → ✅ correct (git is part of pre-baked images). - **Added `--locked` to `cargo clippy/test`** → ✅ **excellent**: ensures reproducibility and prevents accidental version drift. #### ⚠️ **Potential Issue: Missing `source "$HOME/.cargo/env"` in ARM64 workflow** ```diff - - name: Build env: CC_aarch64_unknown_linux_gnu: aarch64-linux-gnu-gcc OPENSSL_STATIC: "1" APPIMAGE_EXTRACT_AND_RUN: "1" run: | - . "$HOME/.cargo/env" npm ci --legacy-peer-deps - rustup target add aarch64-unknown-linux-gnu CI=true npx tauri build --target aarch64-unknown-linux-gnu --bundles deb,rpm ``` - **Problem**: `. "$HOME/.cargo/env"` was removed, but `rustup` is installed in `/root/.cargo/bin`, and `PATH` is set in Dockerfile **only for the ARM64 Dockerfile**: ```dockerfile ENV PATH="/root/.cargo/bin:${PATH}" ``` → ✅ This is **safe** because the Dockerfile sets `PATH`, so `rustup`/`cargo` are available. - **However**, the `arm64` Dockerfile uses: ```dockerfile RUN curl --proto ... | sh -s -- ... --no-modify-path ``` and later sets `PATH`. This is correct — but **only if** the image is built *after* this change. 🔍 **Recommendation**: Verify that `trcaa-linux-arm64:rust1.88-node22` includes the `PATH` env in its Dockerfile (it does — line 43). ✅ **Verdict**: Correct — but **critical to ensure image rebuilds happen before merging**. --- ### 🔒 **3. Security Issues** #### ⚠️ **Insecure Registry Usage** - **Documented prerequisite**: ```sh echo '{"insecure-registries":["172.0.0.29:3000"]}' | sudo tee /etc/docker/daemon.json ``` - **Risk**: Using HTTP (not HTTPS) for a registry **exposes traffic to MITM attacks**. - `172.0.0.29` is a private IP — low external risk, but **still violates defense-in-depth**. - If this registry is ever exposed (e.g., misconfigured firewall), credentials/secrets could leak. ✅ **Mitigation**: - **Strongly recommend** adding TLS (e.g., self-signed cert + `insecure-registries` → `registry-mirrors` with CA). - At minimum: **document the risk** in `CICD-Pipeline.md` and restrict registry access via firewall. #### ⚠️ **Hardcoded Registry URL** - `172.0.0.29:3000` is hardcoded in: - Dockerfiles (not present, but in workflows) - Workflow images - Docs - **Risk**: Hard to rotate or migrate registry. - **Best Practice**: Use an environment variable or CI secret (e.g., `REGISTRY_URL`). ```yaml container: image: ${{ env.REGISTRY_URL }}/sarman/trcaa-linux-amd64:rust1.88-node22 ``` - **Suggestion**: Add `REGISTRY_URL` as a repo variable (e.g., `REGISTRY_URL=172.0.0.29:3000`). #### ✅ **No other security issues** - No secrets in logs (good). - `--no-install-recommends`, `rm -rf /var/lib/apt/lists/*` — best practices followed. - `sh.rustup.rs` via `--proto '=https' --tlsv1.2` — safe. --- ### 🛠️ **4. Best Practices** #### ✅ **Excellent Caching Strategy** - Cargo cache keys use `Cargo.lock` hash → **correct**. - npm cache uses `package-lock.json` hash → **correct**. - `restore-keys` fallbacks ensure partial cache hits (e.g., after lockfile changes). - ✅ **Best practice**: Avoids full re-downloads. #### ✅ **Idempotent Dockerfile Steps** - `|| true` on `rustup component add` → safe. - `--no-install-recommends` → minimal image size. #### ✅ **Documentation Improvements** - Clear table of images/contents. - Rebuild triggers documented. - Prerequisites (insecure registry) clearly called out. #### ⚠️ **Minor: Use of `|| true` in Dockerfile** - While safe, consider: ```dockerfile RUN rustup component add rustfmt clippy 2>/dev/null || true ``` to suppress noise in logs (optional). #### ⚠️ **`build-images.yml` Container Image Change** - Changed from `docker:24-cli` → `alpine:latest` - ❗ **Problem**: `alpine:latest` is **not pinned** → may break if Alpine changes. - ✅ **Fix**: Use pinned version, e.g., `alpine:3.19`. - Also: `docker-cli` is installed, but `docker` daemon may not be available — unless `docker-in-docker` is used (not obvious from diff). → **Verify**: Does this workflow actually build/push images? If yes, it likely uses `dockerd` or `docker buildx`, which requires privileged mode or Docker-in-Docker (DinD). 🔍 **Check**: Is `services: docker` defined? (Not in diff — may be missing.) #### ✅ **Workflow Cleanup** - Removed redundant `apt-get update`/install steps → faster, cleaner, more reproducible. - Removed `GITHUB_PATH` usage (not needed since `PATH` is set in Dockerfile). --- ### 📋 **Recommendations Summary** | Category | Issue | Severity | Fix | |--------|-------|----------|-----| | **Security** | Insecure HTTP registry | ⚠️ Medium | Add TLS; document risk | | **Reliability** | `alpine:latest` unpinned | ⚠️ Medium | Pin to `alpine:3.19` | | **Reliability** | Registry URL hardcoded | ⚠️ Low | Use env var (`REGISTRY_URL`) | | **Reliability** | Missing DinD config in `build-images.yml` | ⚠️ Medium-High | Confirm DinD setup or use `docker:dind` service | | **Best Practice** | `|| true` in Dockerfile | Low | Optional: suppress stderr | | **Best Practice** | `--locked` in cargo commands | ✅ Excellent | Keep! | --- ### ✅ **Final Verdict** **Approve with conditions**: 1. ✅ **Correctness**: All changes are logically sound and improve reproducibility. 2. ⚠️ **Security**: Address insecure registry (TLS + docs). 3. ⚠️ **Reliability**: Pin `alpine` version; confirm DinD setup. 4. ✅ **Performance**: Achieves stated goal (~70% faster builds via pre-baking + caching). **Before merging**: - Rebuild all images *after* merging Dockerfile changes. - Test `build-images.yml` to ensure it can push to `172.0.0.29:3000`. - Add TLS to registry (or document risk mitigation). Let me know if you'd like a patch for the insecure registry or `alpine` pinning!\n\n---\n*this is an automated review from Ollama*
sarman added 1 commit 2026-04-12 23:55:01 +00:00
docs(docker): expand rebuild trigger comments to include OpenSSL and Tauri CLI
Some checks failed
Test / rust-fmt-check (pull_request) Failing after 0s
Test / rust-clippy (pull_request) Failing after 0s
Test / rust-tests (pull_request) Failing after 0s
Test / frontend-tests (pull_request) Failing after 1m19s
Test / frontend-typecheck (pull_request) Successful in 1m26s
PR Review Automation / review (pull_request) Successful in 2m55s
7323c93463
sarman reviewed 2026-04-12 23:57:57 +00:00
sarman left a comment
Author
Owner

🤖 Automated PR Review:\n\nHere's a comprehensive review of the PR changes, covering correctness, security, and best practices:


1. Summary

This PR significantly improves CI performance by:

  • Pre-baking Docker images with all system dependencies (Rust, Node.js, Tauri libs, cross-compilers), eliminating apt-get and toolchain setup in CI jobs.
  • Adding cargo/npm caching via actions/cache@v3 to further speed up builds.
  • Updating documentation (docs/wiki/CICD-Pipeline.md) to reflect the new architecture.

The changes are well-structured, logically consistent, and align with modern CI/CD best practices for reproducibility and speed.


⚠️ 2. Bugs & Correctness Issues

🔴 Critical: || true in rustup component add may hide failures

Location: All three Dockerfiles (e.g., .docker/Dockerfile.linux-amd64, line 26–27)

&& rustup component add rustfmt clippy || true

Problem:
Using || true silently ignores failures (e.g., if rustfmt/clippy components are missing in future toolchains). This breaks the pre-baked promise — the image may build but lack required components, causing CI failures later.

Fix:
Remove || true and ensure components exist in the toolchain.
Add a version check or rustup component list --installed to validate presence.
Alternatively, use --no-self-update and a pinned rustup version to avoid transient failures.

# Better: fail fast if components are unavailable
RUN rustup component add rustfmt clippy

💡 Rationale: Pre-baked images must be fully verified at build time. Silent failures defeat the purpose.


🟡 Medium: Inconsistent use of --locked in cargo clippy/test

Location: .gitea/workflows/test.yml, lines 70 & 99

- run: cargo clippy --locked --manifest-path ...

But cargo fmt (line 33) does not use --locked.

Issue:

  • cargo fmt without --locked may behave differently if Cargo.lock is out-of-sync with Cargo.toml, leading to inconsistent formatting checks.
  • While --locked is good for reproducibility in clippy/test, omitting it in fmt creates inconsistency.

Fix:
Add --locked to cargo fmt:

- run: cargo fmt --locked --manifest-path ...

💡 Note: cargo fmt supports --locked since Rust 1.67 (well before 1.88).


🟡 Medium: apt-get install git removed from auto-tag.yml, but git may not be in base image

Location: .gitea/workflows/auto-tag.yml, all build jobs

All build jobs now rely on pre-baked images (e.g., trcaa-linux-amd64:rust1.88-node22) that include git?
Check Dockerfiles:
Yes — git is installed via apt-get install ... git in Dockerfile.linux-amd64 (line 15), and explicitly in linux-arm64 (Step 1).
⚠️ But windows-cross Dockerfile (line 15) does not install git.

Problem:
git init/fetch in auto-tag.yml will fail on Windows-cross job if git is missing.

Fix:
Add git to windows-cross Dockerfile:

RUN apt-get update -qq \
    && apt-get install -y --no-install-recommends \
        git \
        ...

🟡 Low: Cache key collision risk for cross-compile jobs

Location: .gitea/workflows/auto-tag.yml, Windows & arm64 cache keys

key: ${{ runner.os }}-cargo-windows-${{ hashFiles('**/Cargo.lock') }}
key: ${{ runner.os }}-cargo-arm64-${{ hashFiles('**/Cargo.lock') }}

Issue:
runner.os is Linux for all jobs (they run on Linux runners), so:

  • Linux-cargo-windows-... and Linux-cargo-arm64-... are distinct
  • But if Cargo.lock changes, all three (amd64, windows, arm64) will have different keys — good.

However:
The cache is not shared between jobs (each job runs in isolation), so cross-job cache reuse isn’t expected. The suffix (-windows, -arm64) is safe and appropriate.

No fix needed, but consider documenting why suffixes are used.


🔒 3. Security Issues

🟠 High: Insecure registry (172.0.0.29:3000) without TLS

Location: .docker/Dockerfile.*, .gitea/workflows/*.yml, docs/wiki/CICD-Pipeline.md

All images are pulled from 172.0.0.29:3000 (HTTP, no TLS). The docs acknowledge this and require:

echo '{"insecure-registries":["172.0.0.29:3000"]}' | sudo tee /etc/docker/daemon.json

Risks:

  • Man-in-the-middle (MITM) attacks on the registry.
  • Image tampering (e.g., supply-chain compromise).
  • No integrity verification (no signature verification).

Mitigation:
Short-term: Ensure 172.0.0.29 is on an isolated, trusted network (e.g., internal CI infrastructure).
Long-term:

  • Use a proper registry with TLS (e.g., registry.example.com).
  • Enable Docker Content Trust (DOCKER_CONTENT_TRUST=1) + Notary.
  • Sign images with cosign or Docker’s built-in signing.

📌 Recommendation: Add a security note in docs/wiki/CICD-Pipeline.md:
"This setup assumes the local registry is on a trusted, air-gapped network. Do not expose 172.0.0.29:3000 to untrusted networks."


🟠 Medium: curl ... | bash - in Dockerfiles

Location: All Dockerfiles (e.g., linux-arm64, line 32)

RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- ...

Issue:
Piping curl output directly to bash is risky if the URL is compromised or DNS is hijacked.
While --proto '=https' and --tlsv1.2 help, they don’t prevent MITM if the CA is compromised.

Fix:
Download + verify checksum + execute:

RUN curl -fsSL https://sh.rustup.rs -o rustup.sh \
    && echo "rustup.sh checksum" | sha256sum -c \
    && sh rustup.sh -s -- ...

But: Rustup.rs doesn’t publish checksums.
Alternative: Use apt-installed rustup (if available) or pin to a specific rustup binary version.

💡 Best practice: Avoid curl | sh in production Dockerfiles. Use official images or pre-downloaded binaries.


🛠️ 4. Best Practices & Suggestions

Good: Pre-baked images + caching strategy

  • Combining pre-baked images (for system deps) with cargo/npm caching (for Rust/JS deps) is optimal.
  • Cache keys use hashFiles('**/Cargo.lock'), which is correct (lockfile changes = cache invalidation).

Good: Explicit rebuild triggers documented

  • Rebuild triggers (toolchain, libs, Node.js, OpenSSL, Tauri CLI) are clearly listed.

Good: --locked in cargo test/clippy

  • Ensures reproducible builds.

🔶 Suggestion: Add image versioning best practices

  • Consider adding image digest pinning (e.g., trcaa-linux-amd64@sha256:...) in auto-tag.yml to prevent drift if the tag is overwritten.

🔶 Suggestion: Add health checks for pre-baked images

  • In build-images.yml, add a RUN step to verify critical tools:
    RUN rustc --version && cargo --version && node --version && npm --version
    

🔶 Suggestion: Add --no-verify to git fetch?

  • In auto-tag.yml, git fetch --depth=1 is used.
    If the remote repo is trusted, this is fine.
    But consider adding git fetch --verify-tags if tags are used for releases.

🔶 Suggestion: Remove || true from rustup component add (already noted)

This is the most actionable fix.


Final Recommendation

Approve with conditions:

  1. Mandatory: Remove || true from rustup component add.
  2. Strongly recommended: Add git to windows-cross Dockerfile.
  3. Document security risk of insecure registry and recommend TLS.
  4. Optional but recommended: Pin image digests and add --locked to cargo fmt.

This is a high-quality PR that significantly improves CI performance while maintaining correctness — just needs minor hardening.

Let me know if you'd like a patch file for the fixes!\n\n---\nthis is an automated review from Ollama

🤖 Automated PR Review:\n\nHere's a comprehensive review of the PR changes, covering correctness, security, and best practices: --- ## ✅ **1. Summary** This PR significantly improves CI performance by: - **Pre-baking Docker images** with all system dependencies (Rust, Node.js, Tauri libs, cross-compilers), eliminating `apt-get` and toolchain setup in CI jobs. - **Adding cargo/npm caching** via `actions/cache@v3` to further speed up builds. - Updating documentation (`docs/wiki/CICD-Pipeline.md`) to reflect the new architecture. The changes are well-structured, logically consistent, and align with modern CI/CD best practices for reproducibility and speed. --- ## ⚠️ **2. Bugs & Correctness Issues** ### 🔴 **Critical: `|| true` in `rustup component add` may hide failures** **Location**: All three Dockerfiles (e.g., `.docker/Dockerfile.linux-amd64`, line 26–27) ```dockerfile && rustup component add rustfmt clippy || true ``` **Problem**: Using `|| true` silently ignores failures (e.g., if `rustfmt`/`clippy` components are missing in future toolchains). This breaks the *pre-baked* promise — the image may build but lack required components, causing CI failures later. **Fix**: ✅ **Remove `|| true`** and ensure components exist in the toolchain. ✅ Add a version check or `rustup component list --installed` to validate presence. ✅ Alternatively, use `--no-self-update` and a pinned `rustup` version to avoid transient failures. ```dockerfile # Better: fail fast if components are unavailable RUN rustup component add rustfmt clippy ``` > 💡 *Rationale*: Pre-baked images must be *fully verified* at build time. Silent failures defeat the purpose. --- ### 🟡 **Medium: Inconsistent use of `--locked` in `cargo clippy`/`test`** **Location**: `.gitea/workflows/test.yml`, lines 70 & 99 ```yaml - run: cargo clippy --locked --manifest-path ... ``` But `cargo fmt` (line 33) does **not** use `--locked`. **Issue**: - `cargo fmt` without `--locked` may behave differently if `Cargo.lock` is out-of-sync with `Cargo.toml`, leading to inconsistent formatting checks. - While `--locked` is good for reproducibility in `clippy`/`test`, omitting it in `fmt` creates inconsistency. **Fix**: ✅ Add `--locked` to `cargo fmt`: ```yaml - run: cargo fmt --locked --manifest-path ... ``` > 💡 *Note*: `cargo fmt` supports `--locked` since Rust 1.67 (well before 1.88). --- ### 🟡 **Medium: `apt-get install git` removed from `auto-tag.yml`, but `git` may not be in base image** **Location**: `.gitea/workflows/auto-tag.yml`, all build jobs All build jobs now rely on pre-baked images (e.g., `trcaa-linux-amd64:rust1.88-node22`) that include `git`? → **Check Dockerfiles**: ✅ Yes — `git` is installed via `apt-get install ... git` in `Dockerfile.linux-amd64` (line 15), and explicitly in `linux-arm64` (Step 1). ⚠️ But `windows-cross` Dockerfile (line 15) **does not install `git`**. **Problem**: `git init`/`fetch` in `auto-tag.yml` will fail on Windows-cross job if `git` is missing. **Fix**: ✅ Add `git` to `windows-cross` Dockerfile: ```dockerfile RUN apt-get update -qq \ && apt-get install -y --no-install-recommends \ git \ ... ``` --- ### 🟡 **Low: Cache key collision risk for cross-compile jobs** **Location**: `.gitea/workflows/auto-tag.yml`, Windows & arm64 cache keys ```yaml key: ${{ runner.os }}-cargo-windows-${{ hashFiles('**/Cargo.lock') }} key: ${{ runner.os }}-cargo-arm64-${{ hashFiles('**/Cargo.lock') }} ``` **Issue**: `runner.os` is `Linux` for all jobs (they run on Linux runners), so: - `Linux-cargo-windows-...` and `Linux-cargo-arm64-...` are distinct ✅ - But if `Cargo.lock` changes, **all three** (amd64, windows, arm64) will have different keys — *good*. **However**: The cache is **not shared** between jobs (each job runs in isolation), so cross-job cache reuse isn’t expected. The suffix (`-windows`, `-arm64`) is safe and appropriate. ✅ **No fix needed**, but consider documenting why suffixes are used. --- ## 🔒 **3. Security Issues** ### 🟠 **High: Insecure registry (`172.0.0.29:3000`) without TLS** **Location**: `.docker/Dockerfile.*`, `.gitea/workflows/*.yml`, `docs/wiki/CICD-Pipeline.md` All images are pulled from `172.0.0.29:3000` (HTTP, no TLS). The docs acknowledge this and require: ```sh echo '{"insecure-registries":["172.0.0.29:3000"]}' | sudo tee /etc/docker/daemon.json ``` **Risks**: - Man-in-the-middle (MITM) attacks on the registry. - Image tampering (e.g., supply-chain compromise). - No integrity verification (no signature verification). **Mitigation**: ✅ **Short-term**: Ensure `172.0.0.29` is on an isolated, trusted network (e.g., internal CI infrastructure). ✅ **Long-term**: - Use a proper registry with TLS (e.g., `registry.example.com`). - Enable Docker Content Trust (`DOCKER_CONTENT_TRUST=1`) + Notary. - Sign images with `cosign` or Docker’s built-in signing. > 📌 **Recommendation**: Add a security note in `docs/wiki/CICD-Pipeline.md`: > _"This setup assumes the local registry is on a trusted, air-gapped network. Do not expose `172.0.0.29:3000` to untrusted networks."_ --- ### 🟠 **Medium: `curl ... | bash -` in Dockerfiles** **Location**: All Dockerfiles (e.g., `linux-arm64`, line 32) ```dockerfile RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- ... ``` **Issue**: Piping `curl` output directly to `bash` is risky if the URL is compromised or DNS is hijacked. While `--proto '=https'` and `--tlsv1.2` help, they don’t prevent MITM if the CA is compromised. **Fix**: ✅ **Download + verify checksum + execute**: ```dockerfile RUN curl -fsSL https://sh.rustup.rs -o rustup.sh \ && echo "rustup.sh checksum" | sha256sum -c \ && sh rustup.sh -s -- ... ``` But: Rustup.rs doesn’t publish checksums. ✅ **Alternative**: Use `apt`-installed `rustup` (if available) or pin to a specific `rustup` binary version. > 💡 *Best practice*: Avoid `curl | sh` in production Dockerfiles. Use official images or pre-downloaded binaries. --- ## 🛠️ **4. Best Practices & Suggestions** ### ✅ **Good: Pre-baked images + caching strategy** - Combining pre-baked images (for system deps) with cargo/npm caching (for Rust/JS deps) is optimal. - Cache keys use `hashFiles('**/Cargo.lock')`, which is correct (lockfile changes = cache invalidation). ### ✅ **Good: Explicit rebuild triggers documented** - Rebuild triggers (toolchain, libs, Node.js, OpenSSL, Tauri CLI) are clearly listed. ### ✅ **Good: `--locked` in `cargo test`/`clippy`** - Ensures reproducible builds. ### 🔶 **Suggestion: Add image versioning best practices** - Consider adding **image digest pinning** (e.g., `trcaa-linux-amd64@sha256:...`) in `auto-tag.yml` to prevent drift if the tag is overwritten. ### 🔶 **Suggestion: Add health checks for pre-baked images** - In `build-images.yml`, add a `RUN` step to verify critical tools: ```dockerfile RUN rustc --version && cargo --version && node --version && npm --version ``` ### 🔶 **Suggestion: Add `--no-verify` to `git fetch`?** - In `auto-tag.yml`, `git fetch --depth=1` is used. If the remote repo is trusted, this is fine. But consider adding `git fetch --verify-tags` if tags are used for releases. ### 🔶 **Suggestion: Remove `|| true` from `rustup component add` (already noted)** This is the most actionable fix. --- ## ✅ Final Recommendation **Approve with conditions**: 1. **Mandatory**: Remove `|| true` from `rustup component add`. 2. **Strongly recommended**: Add `git` to `windows-cross` Dockerfile. 3. **Document security risk** of insecure registry and recommend TLS. 4. **Optional but recommended**: Pin image digests and add `--locked` to `cargo fmt`. This is a **high-quality PR** that significantly improves CI performance while maintaining correctness — just needs minor hardening. Let me know if you'd like a patch file for the fixes!\n\n---\n*this is an automated review from Ollama*
sarman added 1 commit 2026-04-13 00:42:12 +00:00
fix(docker): add ca-certificates to arm64 base image step 1
Some checks failed
Test / rust-fmt-check (pull_request) Successful in 11s
Test / frontend-typecheck (pull_request) Successful in 1m29s
PR Review Automation / review (pull_request) Successful in 3m49s
Test / rust-tests (pull_request) Failing after 14s
Test / rust-clippy (pull_request) Failing after 18s
Test / frontend-tests (pull_request) Failing after 1m12s
84dd6d57c3
ubuntu:22.04 minimal does not guarantee ca-certificates is present
before the multiarch apt operations in Step 2. curl in Step 3 then
fails with error 77 (CURLE_SSL_CACERT_BADFILE) when fetching the
nodesource setup script over HTTPS.
sarman reviewed 2026-04-13 00:46:00 +00:00
sarman left a comment
Author
Owner

🤖 Automated PR Review:\n\n### Code Review: Pre-baked Images + Cargo/npm Caching


1. Summary

This PR significantly improves CI performance by:

  • Introducing pre-baked Docker images (for Linux AMD64, ARM64, and Windows cross) that include all system dependencies (Rust, Node.js, OpenSSL, Tauri libs, cross-compilers).
  • Adding cargo registry and npm caching to further accelerate builds.
  • Updating documentation to reflect the new workflow.

Positive impact: ~70% faster builds (as claimed) is realistic — eliminating apt-get, rustup, and npm ci setup steps per job is a major win.

⚠️ However, several security, correctness, and maintainability issues must be addressed before merging.


2. Bugs / Correctness Issues

2.1. || true on rustup component add is dangerous

Files: .docker/Dockerfile.linux-amd64, .docker/Dockerfile.linux-arm64

&& rustup component add rustfmt clippy || true

Problem:
Using || true silently ignores failures. If rustfmt/clippy fail to install (e.g., due to toolchain mismatch, network issue, or component rename), the build will proceed without them, leading to:

  • Silent CI test failures (e.g., cargo fmt missing in test.yml)
  • Inconsistent developer experience (locally may have components, in CI not)
  • Hard-to-debug flaky builds

Fix:
Remove || true and ensure the toolchain version supports the components.
Add a comment explaining why 1.88.0 is safe (it does support rustfmt/clippy):

# rustfmt/clippy are included in rustup 1.88.0 minimal profile
&& rustup component add rustfmt clippy

🔍 Verification: rustup component list --installed in rust:1.88-slim shows rustfmt and clippy are not installed by default. But they are available for installation in 1.88.0. So the command is valid — but must not be masked.

2.2. Missing ca-certificates in Windows cross Dockerfile

File: .docker/Dockerfile.windows-cross
Not modified in the diff, but build-images.yml adds ca-certificates to Linux Dockerfiles.

Issue:
The Windows cross Dockerfile (rust:1.88-slim) is based on slim (Debian), which does include ca-certificates by default. So no bug here — but the PR description and Linux Dockerfiles now explicitly list it, which may cause confusion.

Recommendation:
Add ca-certificates for consistency and future-proofing (e.g., if base image changes):

RUN apt-get update -qq \
    && apt-get install -y --no-install-recommends \
       ca-certificates curl git gcc g++ make patchelf pkg-config perl jq \
       ...
2.3. actions/cache@v3 is deprecated

Files: .gitea/workflows/*.yml
All cache steps use uses: actions/cache@v3.

Issue:
actions/cache@v3 is deprecated. The current stable version is actions/cache@v4 (released 2024-03-22), with:

  • Better performance (parallel uploads)
  • Support for larger caches
  • Fixes for race conditions

Fix:
Upgrade to actions/cache@v4:

uses: actions/cache@v4

📌 Note: Gitea 1.22+ supports the Actions cache API, but the client (actions/cache) must be updated to leverage it fully.

2.4. docker:24-clialpine:latest + docker-cli may break Docker-in-Docker

File: .gitea/workflows/build-images.yml

Issue:
The build-images.yml workflow builds Docker images using Docker-in-Docker (DinD). Previously, it used docker:24-cli, which includes both Docker CLI and Docker daemon (via dockerd). Now it uses alpine:latest + docker-cli, which only provides the CLI — no dockerd.

This will cause:

Cannot connect to the Docker daemon at unix:///var/run/docker.sock

Fix:
Either:

  • Revert to docker:24-cli (simplest), or
  • Use docker:dind as a sidecar container (requires services: config, not shown here).

Suggested fix (minimal change):

container:
  image: docker:24-cli

🔍 Why this is critical: Without a running Docker daemon, docker build commands in the workflow will fail.


3. Security Issues

3.1. Insecure registry (172.0.0.29:3000) over HTTP

Files: All workflow files, docs

Issue:
The registry is accessed via http://172.0.0.29:3000 (not HTTPS). While this may be acceptable in an isolated internal network, it introduces risks:

  • Man-in-the-middle (MITM) attacks on image pulls
  • Tampering with base images (e.g., rust:1.88-slim → backdoored image)
  • Supply chain compromise

Mitigation:
Document the risk explicitly in CICD-Pipeline.md:

⚠️ Security Note: The local registry uses HTTP. Ensure it is only accessible from trusted internal networks. For production use, migrate to HTTPS (e.g., via reverse proxy with Let’s Encrypt or internal CA).

Recommend TLS in the future:

  • Use nginx + certbot for reverse proxy
  • Or switch to a private registry with TLS (e.g., registry:2 with self-signed cert)
3.2. curl ... | bash - pattern

File: .docker/Dockerfile.linux-arm64

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- ...

Issue:
While --proto '=https' --tlsv1.2 adds some protection, piping curl output directly to bash is inherently risky:

  • If rustup.rs is compromised, the entire build environment is compromised.
  • No checksum verification.

Best practice:
Download, verify checksum, then execute:

RUN curl --proto '=https' --tlsv1.2 -sSf -o rustup.sh https://sh.rustup.rs \
    && echo "rustup.sh checksum here" | sha256sum -c \
    && sh rustup.sh -y ...
    && rm rustup.sh

🔍 Note: rustup.rs does not publish checksums officially, but you can fetch the script once, hash it, and pin the hash in the Dockerfile. Alternatively, use rustup-init from a known-good image layer.

3.3. ca-certificates missing in Windows cross Dockerfile (revisited)

Revisited:
While rust:1.88-slim includes ca-certificates, if the base image ever changes (e.g., rust:slimrust:bullseye-slim), curl may fail with SSL errors.

Recommendation:
Explicitly install ca-certificates in all Dockerfiles to be explicit and future-proof.


4. Best Practices

4.1. Cache key collisions risk

Files: .gitea/workflows/*.yml

Current cache keys:

  • cargo: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
  • npm: ${{ runner.os }}-npm-${{ hashFiles('**/package-lock.json') }}

Problem:

  • runner.os is Linux for all Linux jobs (AMD64, ARM64, Windows cross).
  • Cross-compile jobs (e.g., windows-cross, arm64) will share the same cargo cache key as linux-amd64 jobs — but they use different toolchains/targets.

This can cause:

  • Cache pollution (e.g., x86_64-unknown-linux-gnu artifacts in aarch64 cache)
  • cargo build failures due to stale artifacts

Fix:
Use target-specific cache keys:

# For all Rust jobs
key: ${{ runner.os }}-cargo-${{ matrix.target || 'native' }}-${{ hashFiles('**/Cargo.lock') }}

But since matrix.target isn’t used, hardcode per job:

key: ${{ runner.os }}-cargo-linux-amd64-${{ hashFiles('**/Cargo.lock') }}
key: ${{ runner.os }}-cargo-arm64-${{ hashFiles('**/Cargo.lock') }}
key: ${{ runner.os }}-cargo-windows-${{ hashFiles('**/Cargo.lock') }}

Already done in build-linux-arm64 and build-windows-amd64 — but not in rust-fmt-check, rust-clippy, rust-tests.

Critical fix: Update test jobs to use target-specific keys:

# In rust-fmt-check, rust-clippy, rust-tests (all linux-amd64)
key: ${{ runner.os }}-cargo-linux-amd64-${{ hashFiles('**/Cargo.lock') }}
4.2. --locked flag missing in cargo test/clippy

File: .gitea/workflows/test.yml

- run: cargo clippy --manifest-path src-tauri/Cargo.toml -- -D warnings

Issue:
Without --locked, cargo may update Cargo.lock or use newer transitive dependencies than tested, leading to:

  • CI passing but prod failing (or vice versa)
  • Non-reproducible builds

Fix:
Add --locked to all cargo commands:

- run: cargo clippy --locked --manifest-path src-tauri/Cargo.toml -- -D warnings
- run: cargo test --locked --manifest-path src-tauri/Cargo.toml ...

Already done in the diff — but verify all cargo commands use it.

4.3. Documentation gaps

File: docs/wiki/CICD-Pipeline.md

  • No mention of how to verify image integrity (e.g., docker pull --platform linux/amd64 ... && docker inspect).
  • No note about cache eviction policies (Gitea caches expire after 7 days by default).
  • No guidance on troubleshooting cache misses (e.g., hashFiles mismatches).

Recommendation:
Add:

  • How to inspect image layers (docker history)
  • How to force cache refresh (e.g., bump Cargo.lock hash)
  • Cache cleanup strategy (e.g., actions/cache@v4 supports retention-days)

Action Checklist Before Merge

Issue Severity Fix
` trueonrustup component add`
DinD failure (docker-cli without daemon) 🔴 High Revert to docker:24-cli
actions/cache@v3@v4 🟡 Medium Upgrade to v4
Cache key collisions (non-target-specific keys) 🟡 Medium Add target suffix to test jobs
--locked missing in cargo commands 🟡 Medium Add --locked everywhere
Insecure HTTP registry 🟠 Medium Document risks + plan for TLS
curl | bash without checksum 🟠 Medium Pin script hash or use sha256sum

Final Verdict

Do not merge yet — critical bugs (DinD, || true, cache key collisions) will break builds.
Once fixes are applied, this is an excellent, well-documented optimization.

Let me know if you'd like a patch file with the suggested fixes!\n\n---\nthis is an automated review from Ollama

🤖 Automated PR Review:\n\n### **Code Review: Pre-baked Images + Cargo/npm Caching** --- #### **1. Summary** This PR significantly improves CI performance by: - Introducing **pre-baked Docker images** (for Linux AMD64, ARM64, and Windows cross) that include all system dependencies (Rust, Node.js, OpenSSL, Tauri libs, cross-compilers). - Adding **cargo registry** and **npm caching** to further accelerate builds. - Updating documentation to reflect the new workflow. ✅ **Positive impact**: ~70% faster builds (as claimed) is realistic — eliminating `apt-get`, `rustup`, and `npm ci` setup steps per job is a major win. ⚠️ **However**, several **security, correctness, and maintainability issues** must be addressed before merging. --- #### **2. Bugs / Correctness Issues** ##### **2.1. `|| true` on `rustup component add` is dangerous** **Files**: `.docker/Dockerfile.linux-amd64`, `.docker/Dockerfile.linux-arm64` ```dockerfile && rustup component add rustfmt clippy || true ``` **Problem**: Using `|| true` silently ignores failures. If `rustfmt`/`clippy` fail to install (e.g., due to toolchain mismatch, network issue, or component rename), the build will proceed *without them*, leading to: - Silent CI test failures (e.g., `cargo fmt` missing in `test.yml`) - Inconsistent developer experience (locally may have components, in CI not) - Hard-to-debug flaky builds **Fix**: ✅ **Remove `|| true`** and ensure the toolchain version supports the components. ✅ Add a comment explaining why `1.88.0` is safe (it does support `rustfmt`/`clippy`): ```dockerfile # rustfmt/clippy are included in rustup 1.88.0 minimal profile && rustup component add rustfmt clippy ``` > 🔍 **Verification**: `rustup component list --installed` in `rust:1.88-slim` shows `rustfmt` and `clippy` are *not* installed by default. But they *are* available for installation in `1.88.0`. So the command is valid — but *must not* be masked. ##### **2.2. Missing `ca-certificates` in Windows cross Dockerfile** **File**: `.docker/Dockerfile.windows-cross` → **Not modified** in the diff, but `build-images.yml` adds `ca-certificates` to Linux Dockerfiles. **Issue**: The Windows cross Dockerfile (`rust:1.88-slim`) is based on `slim` (Debian), which *does* include `ca-certificates` by default. So no bug here — but the PR description and Linux Dockerfiles now explicitly list it, which may cause confusion. **Recommendation**: ✅ Add `ca-certificates` for consistency and future-proofing (e.g., if base image changes): ```dockerfile RUN apt-get update -qq \ && apt-get install -y --no-install-recommends \ ca-certificates curl git gcc g++ make patchelf pkg-config perl jq \ ... ``` ##### **2.3. `actions/cache@v3` is deprecated** **Files**: `.gitea/workflows/*.yml` All cache steps use `uses: actions/cache@v3`. **Issue**: `actions/cache@v3` is deprecated. The current stable version is [`actions/cache@v4`](https://github.com/actions/cache/releases/tag/v4.0.0) (released 2024-03-22), with: - Better performance (parallel uploads) - Support for larger caches - Fixes for race conditions **Fix**: ✅ Upgrade to `actions/cache@v4`: ```yaml uses: actions/cache@v4 ``` > 📌 **Note**: Gitea 1.22+ supports the Actions cache API, but the *client* (`actions/cache`) must be updated to leverage it fully. ##### **2.4. `docker:24-cli` → `alpine:latest` + `docker-cli` may break Docker-in-Docker** **File**: `.gitea/workflows/build-images.yml` **Issue**: The `build-images.yml` workflow builds Docker images *using Docker-in-Docker (DinD)*. Previously, it used `docker:24-cli`, which includes both Docker CLI *and* Docker daemon (via `dockerd`). Now it uses `alpine:latest` + `docker-cli`, which only provides the CLI — **no `dockerd`**. This will cause: ``` Cannot connect to the Docker daemon at unix:///var/run/docker.sock ``` **Fix**: ✅ Either: - Revert to `docker:24-cli` (simplest), **or** - Use `docker:dind` as a sidecar container (requires `services:` config, not shown here). **Suggested fix** (minimal change): ```yaml container: image: docker:24-cli ``` > 🔍 **Why this is critical**: Without a running Docker daemon, `docker build` commands in the workflow will fail. --- #### **3. Security Issues** ##### **3.1. Insecure registry (`172.0.0.29:3000`) over HTTP** **Files**: All workflow files, docs **Issue**: The registry is accessed via `http://172.0.0.29:3000` (not HTTPS). While this may be acceptable in an *isolated internal network*, it introduces risks: - Man-in-the-middle (MITM) attacks on image pulls - Tampering with base images (e.g., `rust:1.88-slim` → backdoored image) - Supply chain compromise **Mitigation**: ✅ **Document the risk explicitly** in `CICD-Pipeline.md`: > ⚠️ **Security Note**: The local registry uses HTTP. Ensure it is only accessible from trusted internal networks. For production use, migrate to HTTPS (e.g., via reverse proxy with Let’s Encrypt or internal CA). ✅ **Recommend TLS in the future**: - Use `nginx` + `certbot` for reverse proxy - Or switch to a private registry with TLS (e.g., `registry:2` with self-signed cert) ##### **3.2. `curl ... | bash -` pattern** **File**: `.docker/Dockerfile.linux-arm64` ```dockerfile curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- ... ``` **Issue**: While `--proto '=https' --tlsv1.2` adds *some* protection, piping `curl` output directly to `bash` is inherently risky: - If `rustup.rs` is compromised, the entire build environment is compromised. - No checksum verification. **Best practice**: ✅ Download, verify checksum, *then* execute: ```dockerfile RUN curl --proto '=https' --tlsv1.2 -sSf -o rustup.sh https://sh.rustup.rs \ && echo "rustup.sh checksum here" | sha256sum -c \ && sh rustup.sh -y ... && rm rustup.sh ``` > 🔍 **Note**: `rustup.rs` does not publish checksums officially, but you can fetch the script once, hash it, and pin the hash in the Dockerfile. Alternatively, use `rustup-init` from a known-good image layer. ##### **3.3. `ca-certificates` missing in Windows cross Dockerfile (revisited)** **Revisited**: While `rust:1.88-slim` includes `ca-certificates`, if the base image ever changes (e.g., `rust:slim` → `rust:bullseye-slim`), `curl` may fail with SSL errors. **Recommendation**: ✅ Explicitly install `ca-certificates` in all Dockerfiles to be explicit and future-proof. --- #### **4. Best Practices** ##### **4.1. Cache key collisions risk** **Files**: `.gitea/workflows/*.yml` Current cache keys: - `cargo`: `${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}` - `npm`: `${{ runner.os }}-npm-${{ hashFiles('**/package-lock.json') }}` **Problem**: - `runner.os` is `Linux` for all Linux jobs (AMD64, ARM64, Windows cross). - **Cross-compile jobs** (e.g., `windows-cross`, `arm64`) will share the *same* cargo cache key as `linux-amd64` jobs — **but they use different toolchains/targets**. This can cause: - Cache pollution (e.g., `x86_64-unknown-linux-gnu` artifacts in `aarch64` cache) - `cargo` build failures due to stale artifacts **Fix**: ✅ Use **target-specific cache keys**: ```yaml # For all Rust jobs key: ${{ runner.os }}-cargo-${{ matrix.target || 'native' }}-${{ hashFiles('**/Cargo.lock') }} ``` But since `matrix.target` isn’t used, hardcode per job: ```yaml key: ${{ runner.os }}-cargo-linux-amd64-${{ hashFiles('**/Cargo.lock') }} key: ${{ runner.os }}-cargo-arm64-${{ hashFiles('**/Cargo.lock') }} key: ${{ runner.os }}-cargo-windows-${{ hashFiles('**/Cargo.lock') }} ``` ✅ Already done in `build-linux-arm64` and `build-windows-amd64` — but **not in `rust-fmt-check`, `rust-clippy`, `rust-tests`**. **Critical fix**: Update test jobs to use target-specific keys: ```yaml # In rust-fmt-check, rust-clippy, rust-tests (all linux-amd64) key: ${{ runner.os }}-cargo-linux-amd64-${{ hashFiles('**/Cargo.lock') }} ``` ##### **4.2. `--locked` flag missing in `cargo test`/`clippy`** **File**: `.gitea/workflows/test.yml` ```yaml - run: cargo clippy --manifest-path src-tauri/Cargo.toml -- -D warnings ``` **Issue**: Without `--locked`, `cargo` may update `Cargo.lock` or use newer transitive dependencies than tested, leading to: - CI passing but prod failing (or vice versa) - Non-reproducible builds **Fix**: ✅ Add `--locked` to all `cargo` commands: ```yaml - run: cargo clippy --locked --manifest-path src-tauri/Cargo.toml -- -D warnings - run: cargo test --locked --manifest-path src-tauri/Cargo.toml ... ``` ✅ Already done in the diff — but verify all `cargo` commands use it. ##### **4.3. Documentation gaps** **File**: `docs/wiki/CICD-Pipeline.md` - ❌ No mention of **how to verify image integrity** (e.g., `docker pull --platform linux/amd64 ... && docker inspect`). - ❌ No note about **cache eviction policies** (Gitea caches expire after 7 days by default). - ❌ No guidance on **troubleshooting cache misses** (e.g., `hashFiles` mismatches). **Recommendation**: Add: - How to inspect image layers (`docker history`) - How to force cache refresh (e.g., bump `Cargo.lock` hash) - Cache cleanup strategy (e.g., `actions/cache@v4` supports `retention-days`) --- ### ✅ **Action Checklist Before Merge** | Issue | Severity | Fix | |-------|----------|-----| | `|| true` on `rustup component add` | 🔴 High | Remove `|| true` | | DinD failure (`docker-cli` without daemon) | 🔴 High | Revert to `docker:24-cli` | | `actions/cache@v3` → `@v4` | 🟡 Medium | Upgrade to v4 | | Cache key collisions (non-target-specific keys) | 🟡 Medium | Add target suffix to test jobs | | `--locked` missing in `cargo` commands | 🟡 Medium | Add `--locked` everywhere | | Insecure HTTP registry | 🟠 Medium | Document risks + plan for TLS | | `curl \| bash` without checksum | 🟠 Medium | Pin script hash or use `sha256sum` | --- ### ✅ **Final Verdict** **Do not merge yet** — critical bugs (DinD, `|| true`, cache key collisions) will break builds. **Once fixes are applied**, this is an excellent, well-documented optimization. Let me know if you'd like a patch file with the suggested fixes!\n\n---\n*this is an automated review from Ollama*
sarman added 1 commit 2026-04-13 00:59:44 +00:00
fix(ci): resolve test.yml failures — Cargo.lock, updated test assertions
All checks were successful
Test / rust-fmt-check (pull_request) Successful in 11s
Test / frontend-typecheck (pull_request) Successful in 1m11s
Test / frontend-tests (pull_request) Successful in 1m16s
PR Review Automation / review (pull_request) Successful in 3m29s
Test / rust-clippy (pull_request) Successful in 4m2s
Test / rust-tests (pull_request) Successful in 5m21s
397cef383d
Cargo.lock:
- Commit the pre-existing version bump (0.1.0 → 0.2.50) so cargo
  --locked does not fail in CI; Cargo.toml already at 0.2.50

releaseWorkflowCrossPlatformArtifacts.test.ts:
- Update test that previously checked for ubuntu:22.04 / ports mirror
  inline in auto-tag.yml; that setup moved to the pre-baked
  trcaa-linux-arm64 image so the test now verifies the image reference
  and cross-compile env vars instead

ciDockerBuilders.test.ts:
- Update test that checked for docker:24-cli; changed to alpine:latest
  + docker-cli to avoid act_runner v0.3.1 duplicate socket mount bug;
  negative assertion on docker:24-cli retained
sarman reviewed 2026-04-13 01:03:11 +00:00
sarman left a comment
Author
Owner

🤖 Automated PR Review:\n\nHere's a comprehensive review of the PR changes, covering correctness, security, and best practices:


1. Summary

This PR significantly improves CI performance by:

  • Pre-baking system dependencies (Rust, Node.js, Tauri libs, cross-compilers) into custom Docker images
  • Adding Cargo and npm caching via actions/cache@v3
  • Updating documentation

The changes are mostly well-structured and beneficial, but contain critical correctness issues, security risks, and suboptimal patterns that must be addressed before merging.


2. Critical Bugs / Correctness Issues

🔴 2.1. ca-certificates missing in linux-arm64 Dockerfile

-       curl git gcc g++ make patchelf pkg-config perl jq \
+       ca-certificates curl git gcc g++ make patchelf pkg-config perl jq \

Good: ca-certificates is needed for curl --proto '=https' to validate TLS certs.

⚠️ BUT: In linux-amd64 and windows-cross Dockerfiles, ca-certificates is not added, yet curl --proto '=https' is used in Rustup install. This can cause silent failures on systems without CA certs (e.g., minimal images like rust:1.88-slim).

➡️ Fix: Add ca-certificates to all Dockerfiles using curl --proto '=https':

RUN apt-get update -qq \
    && apt-get install -y --no-install-recommends \
       ca-certificates curl git ... \
    && rm -rf /var/lib/apt/lists/*

🔴 2.2. rustup component add ... || true is dangerous

RUN rustup component add rustfmt clippy || true

⚠️ This silently ignores failures. If rustfmt/clippy fail to install (e.g., due to toolchain mismatch), the build continues without them, leading to:

  • Silent test failures (e.g., cargo fmt --check passes when it shouldn’t)
  • False confidence in CI

➡️ Fix: Use || echo "Warning: rustfmt/clippy not installed" and fail the build if components are required:

RUN rustup component add rustfmt clippy || { \
    echo "ERROR: Failed to install rustfmt/clippy"; exit 1; \
}

Or, if optional: explicitly document they’re optional and verify installation:

RUN rustup component add rustfmt clippy 2>&1 || \
    { rustup component list --installed | grep -q rustfmt && rustup component list --installed | grep -q clippy; }

🔴 2.3. docker:24-clialpine:latest in build-images.yml is unsafe

- image: docker:24-cli
+ image: alpine:latest

⚠️ docker:24-cli includes Docker CLI and Docker daemon (for build). alpine:latest does not include Docker CLI — only docker-cli is added via apk add, but:

  • docker-cli is a client-only package; it cannot build images (needs dockerd).
  • The workflow likely fails at docker build steps (not shown in diff, but implied by context).

➡️ Fix: Use docker:24-cli-dind (Docker-in-Docker) or docker:24-cli with services: [docker]. If using alpine, install full Docker CLI:

container:
  image: docker:24-cli

Or, if minimizing image size:

# In Dockerfile for build-images.yml
FROM alpine:latest
RUN apk add --no-cache docker-cli

But then you must run with Docker-in-Docker (DinD) or use host Docker socket (⚠️ security risk).

🔴 2.4. git fetch --depth=1 + git checkout FETCH_HEAD is fragile

git fetch --depth=1 origin "$GITHUB_SHA"
git checkout FETCH_HEAD

⚠️ FETCH_HEAD is a file, not a ref. If git fetch fails (e.g., SHA doesn’t exist), FETCH_HEAD may be stale or empty → builds wrong code.

➡️ Fix: Use git fetch with --update-head-ok and checkout explicitly:

git fetch --depth=1 origin "$GITHUB_SHA" --update-head-ok
git checkout FETCH_HEAD

Or better: use git fetch origin "$GITHUB_SHA" && git -c advice.detachedHead=false checkout "$GITHUB_SHA".


3. Security Issues

🟠 3.1. Insecure Registry (HTTP) in Production

image: 172.0.0.29:3000/...

⚠️ Pushing to an HTTP registry (not HTTPS) exposes:

  • Credentials (if used)
  • Build artifacts (MITM)
  • Code leakage

➡️ Fix:

  • Use HTTPS with a valid cert (e.g., via Let’s Encrypt or internal CA).
  • If internal-only, at minimum use http:// only in dev, and document that production requires HTTPS.
  • Add --insecure-registry to Docker daemon config (as noted in docs), but this is not secure for production.

🟠 3.2. OPENSSL_STATIC=1 + system OpenSSL in pre-baked images

# Rebuild when: ... OpenSSL major version changes (used via OPENSSL_STATIC=1)

⚠️ OPENSSL_STATIC=1 implies static linking, but the image still has dynamic OpenSSL dev libs installed. If cargo build fails to link statically (e.g., missing openssl-sys feature), it may link dynamically to the host OpenSSL → security risk if host OpenSSL is outdated.

➡️ Fix:

  • Verify OPENSSL_STATIC=1 actually works (e.g., via ldd target/release/app).
  • Prefer openssl-sys = { version = "...", features = ["vendored"] } in Cargo.toml to ensure vendored OpenSSL.

🟠 3.3. || true masks critical failures

As noted in 2.2, || true hides failures. In security-critical paths (e.g., certificate installation, build verification), this could allow insecure builds.


4. Best Practices Violations

🟡 4.1. Cache keys lack rustup version

key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}

⚠️ If rustup toolchain changes (e.g., 1.88 → 1.89), cached artifacts may be incompatible.

➡️ Fix: Include toolchain in cache key:

key: ${{ runner.os }}-cargo-${{ env.RUST_VERSION }}-${{ hashFiles('**/Cargo.lock') }}

Set env.RUST_VERSION: "1.88" in workflow.

🟡 4.2. actions/cache@v3 is deprecated

⚠️ actions/cache@v3 is deprecated. Use actions/cache@v4 (released 2024-06).

➡️ Fix:

uses: actions/cache@v4

🟡 4.3. Redundant apt-get install git in CI steps

- name: Checkout
  run: |
    apt-get update -qq && apt-get install -y -qq git    

Already removed in new workflow (good!), but the old version was inefficient.

🟡 4.4. npm ci without --frozen-lockfile

npm ci --legacy-peer-deps

⚠️ --legacy-peer-deps bypasses peer dependency checks → may install incompatible versions.

➡️ Fix: If peer deps are truly incompatible, fix them in package.json. Otherwise, use:

npm ci --frozen-lockfile

🟡 4.5. || true in rustup component add breaks idempotency

As noted earlier, || true makes the step always succeed, hiding real issues.


5. Documentation & Maintainability

Good: Updated Dockerfile comments to include OpenSSL/Tauri CLI rebuild triggers.

⚠️ Missing: No mention of how to verify image contents (e.g., docker run --rm <image> rustc --version).

⚠️ Missing: No guidance on rotating credentials if registry requires auth (even if internal).


Recommendations Before Merge

Priority Issue Fix
🔴 Critical ca-certificates missing in some Dockerfiles Add to all curl --proto '=https' builds
🔴 Critical docker:24-clialpine:latest breaks Docker builds Revert to docker:24-cli or fix DinD setup
🔴 Critical `
🟠 High Insecure HTTP registry Use HTTPS or document risks
🟡 Medium actions/cache@v3 deprecated Upgrade to @v4
🟡 Medium Cache keys omit toolchain version Include RUST_VERSION in key
🟡 Medium npm ci --legacy-peer-deps Prefer --frozen-lockfile

Final Verdict

Do not merge as-is. The PR introduces critical correctness and security risks that could lead to:

  • Wrong code being built/tested
  • Insecure binaries (dynamic OpenSSL linkage)
  • CI failures (missing Docker CLI)
  • Silent security regressions

Recommended actions:

  1. Fix all || true usages
  2. Add ca-certificates to all Dockerfiles
  3. Revert build-images.yml to docker:24-cli or fix DinD
  4. Upgrade to actions/cache@v4
  5. Add RUST_VERSION to cache keys
  6. Plan migration to HTTPS registry

Once fixed, this will be a strong performance win with minimal tradeoffs.\n\n---\nthis is an automated review from Ollama

🤖 Automated PR Review:\n\nHere's a comprehensive review of the PR changes, covering correctness, security, and best practices: --- ### **1. Summary** This PR significantly improves CI performance by: - Pre-baking system dependencies (Rust, Node.js, Tauri libs, cross-compilers) into custom Docker images - Adding Cargo and npm caching via `actions/cache@v3` - Updating documentation The changes are **mostly well-structured and beneficial**, but contain **critical correctness issues**, **security risks**, and **suboptimal patterns** that must be addressed before merging. --- ### **2. Critical Bugs / Correctness Issues** #### 🔴 **2.1. `ca-certificates` missing in `linux-arm64` Dockerfile** ```diff - curl git gcc g++ make patchelf pkg-config perl jq \ + ca-certificates curl git gcc g++ make patchelf pkg-config perl jq \ ``` ✅ **Good**: `ca-certificates` is needed for `curl --proto '=https'` to validate TLS certs. ⚠️ **BUT**: In `linux-amd64` and `windows-cross` Dockerfiles, `ca-certificates` is **not added**, yet `curl --proto '=https'` is used in Rustup install. This can cause **silent failures** on systems without CA certs (e.g., minimal images like `rust:1.88-slim`). ➡️ **Fix**: Add `ca-certificates` to all Dockerfiles using `curl --proto '=https'`: ```dockerfile RUN apt-get update -qq \ && apt-get install -y --no-install-recommends \ ca-certificates curl git ... \ && rm -rf /var/lib/apt/lists/* ``` #### 🔴 **2.2. `rustup component add ... || true` is dangerous** ```dockerfile RUN rustup component add rustfmt clippy || true ``` ⚠️ This silently **ignores failures**. If `rustfmt`/`clippy` fail to install (e.g., due to toolchain mismatch), the build continues *without them*, leading to: - Silent test failures (e.g., `cargo fmt --check` passes when it shouldn’t) - False confidence in CI ➡️ **Fix**: Use `|| echo "Warning: rustfmt/clippy not installed"` and fail the build if components are required: ```dockerfile RUN rustup component add rustfmt clippy || { \ echo "ERROR: Failed to install rustfmt/clippy"; exit 1; \ } ``` Or, if optional: explicitly document they’re optional and verify installation: ```dockerfile RUN rustup component add rustfmt clippy 2>&1 || \ { rustup component list --installed | grep -q rustfmt && rustup component list --installed | grep -q clippy; } ``` #### 🔴 **2.3. `docker:24-cli` → `alpine:latest` in `build-images.yml` is unsafe** ```diff - image: docker:24-cli + image: alpine:latest ``` ⚠️ `docker:24-cli` includes Docker CLI *and* Docker daemon (for build). `alpine:latest` **does not include Docker CLI** — only `docker-cli` is added via `apk add`, but: - `docker-cli` is a *client-only* package; it **cannot build images** (needs `dockerd`). - The workflow likely fails at `docker build` steps (not shown in diff, but implied by context). ➡️ **Fix**: Use `docker:24-cli-dind` (Docker-in-Docker) or `docker:24-cli` with `services: [docker]`. If using `alpine`, install full Docker CLI: ```yaml container: image: docker:24-cli ``` Or, if minimizing image size: ```dockerfile # In Dockerfile for build-images.yml FROM alpine:latest RUN apk add --no-cache docker-cli ``` But then you *must* run with Docker-in-Docker (DinD) or use host Docker socket (⚠️ security risk). #### 🔴 **2.4. `git fetch --depth=1` + `git checkout FETCH_HEAD` is fragile** ```yaml git fetch --depth=1 origin "$GITHUB_SHA" git checkout FETCH_HEAD ``` ⚠️ `FETCH_HEAD` is a *file*, not a ref. If `git fetch` fails (e.g., SHA doesn’t exist), `FETCH_HEAD` may be stale or empty → **builds wrong code**. ➡️ **Fix**: Use `git fetch` with `--update-head-ok` and checkout explicitly: ```yaml git fetch --depth=1 origin "$GITHUB_SHA" --update-head-ok git checkout FETCH_HEAD ``` Or better: use `git fetch origin "$GITHUB_SHA" && git -c advice.detachedHead=false checkout "$GITHUB_SHA"`. --- ### **3. Security Issues** #### 🟠 **3.1. Insecure Registry (HTTP) in Production** ```yaml image: 172.0.0.29:3000/... ``` ⚠️ Pushing to an **HTTP registry** (not HTTPS) exposes: - Credentials (if used) - Build artifacts (MITM) - Code leakage ➡️ **Fix**: - Use HTTPS with a valid cert (e.g., via Let’s Encrypt or internal CA). - If internal-only, at minimum use `http://` *only* in dev, and document that production requires HTTPS. - Add `--insecure-registry` to Docker daemon config (as noted in docs), but **this is not secure for production**. #### 🟠 **3.2. `OPENSSL_STATIC=1` + system OpenSSL in pre-baked images** ```dockerfile # Rebuild when: ... OpenSSL major version changes (used via OPENSSL_STATIC=1) ``` ⚠️ `OPENSSL_STATIC=1` implies static linking, but the image still has *dynamic* OpenSSL dev libs installed. If `cargo build` fails to link statically (e.g., missing `openssl-sys` feature), it may link dynamically to the *host* OpenSSL → **security risk if host OpenSSL is outdated**. ➡️ **Fix**: - Verify `OPENSSL_STATIC=1` actually works (e.g., via `ldd target/release/app`). - Prefer `openssl-sys = { version = "...", features = ["vendored"] }` in `Cargo.toml` to ensure vendored OpenSSL. #### 🟠 **3.3. `|| true` masks critical failures** As noted in 2.2, `|| true` hides failures. In security-critical paths (e.g., certificate installation, build verification), this could allow insecure builds. --- ### **4. Best Practices Violations** #### 🟡 **4.1. Cache keys lack `rustup` version** ```yaml key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} ``` ⚠️ If `rustup` toolchain changes (e.g., 1.88 → 1.89), cached artifacts may be incompatible. ➡️ **Fix**: Include toolchain in cache key: ```yaml key: ${{ runner.os }}-cargo-${{ env.RUST_VERSION }}-${{ hashFiles('**/Cargo.lock') }} ``` Set `env.RUST_VERSION: "1.88"` in workflow. #### 🟡 **4.2. `actions/cache@v3` is deprecated** ⚠️ `actions/cache@v3` is deprecated. Use `actions/cache@v4` (released 2024-06). ➡️ **Fix**: ```yaml uses: actions/cache@v4 ``` #### 🟡 **4.3. Redundant `apt-get install git` in CI steps** ```yaml - name: Checkout run: | apt-get update -qq && apt-get install -y -qq git ``` ✅ Already removed in new workflow (good!), but the old version was inefficient. #### 🟡 **4.4. `npm ci` without `--frozen-lockfile`** ```yaml npm ci --legacy-peer-deps ``` ⚠️ `--legacy-peer-deps` bypasses peer dependency checks → may install incompatible versions. ➡️ **Fix**: If peer deps are truly incompatible, fix them in `package.json`. Otherwise, use: ```yaml npm ci --frozen-lockfile ``` #### 🟡 **4.5. `|| true` in `rustup component add` breaks idempotency** As noted earlier, `|| true` makes the step always succeed, hiding real issues. --- ### **5. Documentation & Maintainability** #### ✅ **Good**: Updated `Dockerfile` comments to include OpenSSL/Tauri CLI rebuild triggers. #### ⚠️ **Missing**: No mention of **how to verify image contents** (e.g., `docker run --rm <image> rustc --version`). #### ⚠️ **Missing**: No guidance on **rotating credentials** if registry requires auth (even if internal). --- ### **Recommendations Before Merge** | Priority | Issue | Fix | |--------|-------|-----| | 🔴 Critical | `ca-certificates` missing in some Dockerfiles | Add to all `curl --proto '=https'` builds | | 🔴 Critical | `docker:24-cli` → `alpine:latest` breaks Docker builds | Revert to `docker:24-cli` or fix DinD setup | | 🔴 Critical | `|| true` hides failures | Remove `|| true`; fail on error | | 🟠 High | Insecure HTTP registry | Use HTTPS or document risks | | 🟡 Medium | `actions/cache@v3` deprecated | Upgrade to `@v4` | | 🟡 Medium | Cache keys omit toolchain version | Include `RUST_VERSION` in key | | 🟡 Medium | `npm ci --legacy-peer-deps` | Prefer `--frozen-lockfile` | --- ### **Final Verdict** **Do not merge as-is.** The PR introduces **critical correctness and security risks** that could lead to: - Wrong code being built/tested - Insecure binaries (dynamic OpenSSL linkage) - CI failures (missing Docker CLI) - Silent security regressions **Recommended actions:** 1. Fix all `|| true` usages 2. Add `ca-certificates` to all Dockerfiles 3. Revert `build-images.yml` to `docker:24-cli` or fix DinD 4. Upgrade to `actions/cache@v4` 5. Add `RUST_VERSION` to cache keys 6. Plan migration to HTTPS registry Once fixed, this will be a **strong performance win** with minimal tradeoffs.\n\n---\n*this is an automated review from Ollama*
sarman added 1 commit 2026-04-13 01:07:23 +00:00
fix(ci): address second AI review — || true, ca-certs, cache@v4, key suffixes
All checks were successful
Test / frontend-typecheck (pull_request) Successful in 2m35s
Test / frontend-tests (pull_request) Successful in 2m39s
PR Review Automation / review (pull_request) Successful in 2m49s
Test / rust-clippy (pull_request) Successful in 4m7s
Test / rust-fmt-check (pull_request) Successful in 13s
Test / rust-tests (pull_request) Successful in 3m37s
30d26ed0c1
Dockerfiles:
- Remove || true from rustup component add in all three Linux images;
  rust:1.88-slim default profile already includes both components so the
  command is a clean no-op, not a failure risk — silencing errors served
  no purpose and only hid potential toolchain issues
- Add ca-certificates explicitly to Dockerfile.linux-amd64 and
  Dockerfile.windows-cross (rust:1.88-slim includes it, but being
  explicit is consistent with the arm64 fix and future-proofs against
  base image changes)

Workflows:
- Upgrade actions/cache@v3 → @v4 across test.yml and auto-tag.yml
  (v3 deprecated; v4 has parallel uploads and better large-cache support)
- Add linux-amd64 suffix to cargo cache keys in test.yml Rust jobs and
  auto-tag.yml build-linux-amd64 job; all four jobs target the same
  architecture and now share a cache, benefiting from cross-job hits
  (registry cache is source tarballs, not compiled artifacts — no
  pollution risk between targets)

Not changed:
- alpine:latest + docker-cli in build-images.yml is correct; the reviewer
  confused DinD with socket passthrough — docker:24-cli also has no daemon,
  both use the host socket; the builds already proved alpine works
- curl|bash for rustup is the official install method; rustup.rs publishes
  no checksums for the installer script itself
sarman reviewed 2026-04-13 01:10:08 +00:00
sarman left a comment
Author
Owner

🤖 Automated PR Review:\n\nHere's a comprehensive review of the PR changes:


1. Summary

This PR significantly improves CI performance by:

  • Introducing pre-baked Docker images (for Linux/amd64, Linux/arm64, and Windows cross) that include all system dependencies (Rust, Node.js, dev libs, cross-compilers), eliminating repeated apt-get install and toolchain setup in CI.
  • Adding cargo and npm caching via actions/cache@v4 to further speed up builds.
  • Updating documentation to reflect the new architecture.

Overall direction is excellent — pre-baked images + caching is a well-established CI optimization pattern.

⚠️ However, several correctness, security, and maintainability issues need addressing before merging.


2. Bugs & Correctness Issues

2.1. ca-certificates added but ca-certificates may be missing in base image

  • In .docker/Dockerfile.linux-amd64, ca-certificates is added explicitly:
    RUN apt-get update -qq && apt-get install -y -qq --no-install-recommends \
        ca-certificates \
        ...
    
    This is good practice (especially for curl --proto '=https' and npm ci), but:
    • rust:1.88-slim is based on Debian Bookworm, which does include ca-certificates by default. However, slim variants sometimes strip it. Adding it explicitly is safe and defensive.

2.2. curl and jq missing in build-images.yml

  • In .gitea/workflows/build-images.yml, the docker CLI is installed:

    apk add --no-cache git docker-cli
    

    But docker-cli (v24) no longer includes curl or jq, which are used in the Dockerfiles:

    RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs ...
    RUN jq ...
    

    Bug: curl and jq will be missing in the build-images.yml container, causing docker build to fail.

    Fix:

    apk add --no-cache git docker-cli curl jq
    

2.3. rustup component add in Dockerfiles uses rustup, but PATH may be wrong

  • In Dockerfile.linux-arm64, rustup is installed via rustup.rs, but the PATH is set after the rustup commands:
    RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- ... \
        && /root/.cargo/bin/rustup target add ...
    ENV PATH="/root/.cargo/bin:${PATH}"
    
    This is safe because /root/.cargo/bin/rustup is called explicitly — no reliance on PATH.

2.4. OPENSSL_STATIC=1 usage is inconsistent

  • All Dockerfiles mention OpenSSL in comments:

    OpenSSL major version changes (used via OPENSSL_STATIC=1)

  • But libssl-dev is installed in all Dockerfiles — not libssl-static or openssl-dev-static.

  • OPENSSL_STATIC=1 tells openssl-sys to link OpenSSL statically, but it still needs static OpenSSL dev libs (e.g., libssl.a, libcrypto.a).
    Bug: libssl-dev provides only shared libs (libssl.so, libcrypto.so). Static linking will fail unless static libs are installed.

    Fix:

    • For Debian/Ubuntu: install libssl-dev + libssl-static (if available) or openssl-dev-static.
      But: libssl-static is not available in Debian Bookworm (1.88-slim is based on Bookworm).
      Alternative: Use OPENSSL_DIR with a pre-built static OpenSSL (e.g., via vcpkg or openssl-src), or switch to dynamic linking.

    🔍 Recommendation:

    • If OPENSSL_STATIC=1 is critical (e.g., for reproducibility or avoiding glibc version issues), consider using openssl-src in Cargo.toml, or provide a custom static OpenSSL build.
    • Otherwise, remove OPENSSL_STATIC=1 and use dynamic linking (simpler, and libssl-dev is sufficient).

2.5. actions/cache@v4 used, but Gitea 1.22 may only support v3

  • The PR uses actions/cache@v4, but:

    • Gitea 1.22’s Actions implementation is based on Woodpecker, which currently supports actions/cache@v3.
    • @v4 introduces breaking changes (e.g., path must be absolute, restore-keys behavior changed).
    • Risk: Caching may silently fail or behave unexpectedly.

    Fix: Use actions/cache@v3 unless you’ve confirmed Gitea 1.22 supports @v4.


3. Security Issues

3.1. Insecure registry (172.0.0.29:3000)

  • All jobs pull from 172.0.0.29:3000, which is an HTTP (not HTTPS) registry.

  • This exposes:

    • Man-in-the-middle (MITM) attacks on image pulls.
    • Image tampering (no integrity verification beyond Docker’s layer checksums).
    • Credential leakage (if auth is used, credentials are sent in plaintext).

    Fixes:

    1. Mandatory: Use HTTPS with a valid certificate (e.g., via Let’s Encrypt or internal CA).
    2. If internal CA is used, ensure all runners trust the CA cert (documented in CICD-Pipeline.md).
    3. Add --digests to docker push to pin digests in CI (not in Dockerfiles, but in workflows).
    4. Never use insecure-registries in production — it’s a security anti-pattern.

    📝 Update CICD-Pipeline.md:

    **⚠️ Security Note**: The current setup uses an HTTP registry. This is acceptable only in isolated, trusted networks (e.g., CI server on a private subnet). For production, switch to HTTPS with TLS.
    

3.2. curl ... | bash - in Dockerfiles

  • All Dockerfiles use:

    RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- ...
    

    --proto '=https' --tlsv1.2 is good, but:

    • Risk: If rustup.rs is compromised, all images are backdoored.
    • Mitigation: Pin the rustup.rs script hash (not currently done).

    Fix: Download and verify hash:

    RUN curl -sSf https://sh.rustup.rs -o /tmp/rustup.sh \
        && echo "sha256:$(sha256sum /tmp/rustup.sh | cut -d' ' -f1)" \
        && sh /tmp/rustup.sh -y ...
    

    But note: rustup.rs changes with each toolchain release — this requires updating the hash in the Dockerfile.

    🔁 Alternative: Use official rust images (e.g., rust:1.88-slim) and avoid rustup.rs entirely. Since rust:1.88-slim already has Rust 1.88, you can skip rustup installation.


4. Best Practices

4.1. Dockerfile layer optimization

  • Good: --no-install-recommends, rm -rf /var/lib/apt/lists/*
  • Missed opportunity: Combine apt-get update and apt-get install into a single RUN layer (already done ), but consider:
    • Using apt-get clean instead of rm -rf /var/lib/apt/lists/* (more thorough).
    • Using --no-install-suggests (already implied by --no-install-recommends).

4.2. Rustfmt/clippy in Dockerfiles

  • Adding rustup component add rustfmt clippy is great for CI consistency.
  • ⚠️ But: These components increase image size (~100MB). If only used in test jobs (not builds), consider:
    • Moving them to a separate *-dev image (e.g., trcaa-linux-amd64-dev).
    • Or using cargo +1.88 fmt/clippy (uses toolchain from rustup but doesn’t require permanent component install).

4.3. Cache key strategy

  • Cache keys use hashFiles('**/Cargo.lock'), which is correct.
  • Restore keys (${{ runner.os }}-cargo-) provide fallbacks.
  • ⚠️ Risk: If Cargo.lock is updated but dependencies haven’t changed (e.g., cargo update), cache is invalidated unnecessarily.
    • Better: Use hashFiles('**/Cargo.toml', '**/Cargo.lock') to avoid cache misses from cargo update alone.

4.4. build-images.yml uses alpine:latest

  • Dangerous: alpine:latest is not pinned to a digest. It may pull a different Alpine version over time → non-reproducible builds.
  • Fix: Use a pinned digest:
    image: alpine:3.19@sha256:...
    
    Get digest via:
    docker pull alpine:3.19
    docker inspect alpine:3.19 --format='{{index .Digest}}'
    

4.5. Documentation gaps

  • CICD-Pipeline.md doesn’t mention:

    • How to trigger image rebuilds when dependencies change (e.g., Rust 1.89 → update tag to rust1.89-node22).
    • How to verify image contents (e.g., docker run --rm <image> rustc --version).
    • Rollback plan if an image is broken.

    Add:

    ## Updating Images
    When Rust/Node.js/openssl versions change:
    1. Update the `FROM` tag in Dockerfiles (e.g., `rust:1.89-slim`).
    2. Update image tag in `build-images.yml` (e.g., `rust1.89-node22`).
    3. Rebuild via `workflow_dispatch`.
    

5. Other Minor Issues

File Issue Fix
.docker/Dockerfile.linux-arm64 ARG DEBIAN_FRONTEND=noninteractive is redundant in ubuntu:22.04 (already set) Remove
.gitea/workflows/test.yml rustup component add clippy removed in rust-clippy job, but Dockerfile already adds it Correct — no need to add again.
.gitea/workflows/auto-tag.yml git init + git fetch + git checkout is redundant; actions/checkout@v4 would be simpler But acceptable for Gitea-specific auth.
docs/wiki/CICD-Pipeline.md Uses actions/cache@v3 in examples, but PR uses @v4 Align to @v4 (if confirmed supported) or revert to @v3.

Recommendations Before Merge

  1. Critical:

    • Add curl and jq to build-images.yml.
    • Fix OPENSSL_STATIC=1 issue (remove or add static libs).
    • Pin alpine image in build-images.yml.
    • Downgrade actions/cache@v4@v3 unless Gitea 1.22 supports @v4.
  2. High Priority:

    • Add TLS to the registry (https://172.0.0.29:3000).
    • Pin rustup.rs hash or switch to official rust image layers.
  3. Medium Priority:

    • Improve cache key strategy (hashFiles('Cargo.toml', 'Cargo.lock')).
    • Document image update/rollback process.
  4. Nice-to-Have:

    • Consider splitting dev and build images to reduce build image size.
    • Add RUN rustup show to Dockerfiles for debugging.

Final Verdict

Strong performance gains — this is a high-value optimization.
⚠️ Merge only after fixing critical bugs and security gaps.
🎯 Once fixed, this PR is production-ready.

Let me know if you'd like a revised diff with suggested fixes!\n\n---\nthis is an automated review from Ollama

🤖 Automated PR Review:\n\nHere's a comprehensive review of the PR changes: --- ### **1. Summary** This PR significantly improves CI performance by: - Introducing **pre-baked Docker images** (for Linux/amd64, Linux/arm64, and Windows cross) that include all system dependencies (Rust, Node.js, dev libs, cross-compilers), eliminating repeated `apt-get install` and toolchain setup in CI. - Adding **cargo and npm caching** via `actions/cache@v4` to further speed up builds. - Updating documentation to reflect the new architecture. ✅ **Overall direction is excellent** — pre-baked images + caching is a well-established CI optimization pattern. ⚠️ **However, several correctness, security, and maintainability issues need addressing before merging.** --- ### **2. Bugs & Correctness Issues** #### **2.1. `ca-certificates` added but `ca-certificates` may be missing in base image** - In `.docker/Dockerfile.linux-amd64`, `ca-certificates` is added explicitly: ```dockerfile RUN apt-get update -qq && apt-get install -y -qq --no-install-recommends \ ca-certificates \ ... ``` ✅ This is **good practice** (especially for `curl --proto '=https'` and `npm ci`), but: - `rust:1.88-slim` is based on Debian Bookworm, which *does* include `ca-certificates` by default. However, `slim` variants sometimes strip it. Adding it explicitly is safe and defensive. #### **2.2. `curl` and `jq` missing in `build-images.yml`** - In `.gitea/workflows/build-images.yml`, the `docker` CLI is installed: ```yaml apk add --no-cache git docker-cli ``` But `docker-cli` (v24) **no longer includes `curl` or `jq`**, which are used in the Dockerfiles: ```dockerfile RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs ... RUN jq ... ``` ❌ **Bug**: `curl` and `jq` will be missing in the `build-images.yml` container, causing `docker build` to fail. ✅ **Fix**: ```yaml apk add --no-cache git docker-cli curl jq ``` #### **2.3. `rustup component add` in Dockerfiles uses `rustup`, but PATH may be wrong** - In `Dockerfile.linux-arm64`, `rustup` is installed via `rustup.rs`, but the `PATH` is set *after* the `rustup` commands: ```dockerfile RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- ... \ && /root/.cargo/bin/rustup target add ... ENV PATH="/root/.cargo/bin:${PATH}" ``` ✅ This is **safe** because `/root/.cargo/bin/rustup` is called explicitly — no reliance on `PATH`. #### **2.4. `OPENSSL_STATIC=1` usage is inconsistent** - All Dockerfiles mention OpenSSL in comments: > `OpenSSL major version changes (used via OPENSSL_STATIC=1)` - But `libssl-dev` is installed in all Dockerfiles — **not** `libssl-static` or `openssl-dev-static`. - `OPENSSL_STATIC=1` tells `openssl-sys` to link OpenSSL statically, but it still needs *static* OpenSSL dev libs (e.g., `libssl.a`, `libcrypto.a`). ❌ **Bug**: `libssl-dev` provides only *shared* libs (`libssl.so`, `libcrypto.so`). Static linking will fail unless static libs are installed. ✅ **Fix**: - For Debian/Ubuntu: install `libssl-dev` + `libssl-static` (if available) or `openssl-dev-static`. **But**: `libssl-static` is **not available in Debian Bookworm** (1.88-slim is based on Bookworm). → **Alternative**: Use `OPENSSL_DIR` with a pre-built static OpenSSL (e.g., via `vcpkg` or `openssl-src`), or switch to dynamic linking. 🔍 **Recommendation**: - If `OPENSSL_STATIC=1` is critical (e.g., for reproducibility or avoiding glibc version issues), consider using [`openssl-src`](https://crates.io/crates/openssl-src) in `Cargo.toml`, or provide a custom static OpenSSL build. - Otherwise, **remove `OPENSSL_STATIC=1`** and use dynamic linking (simpler, and `libssl-dev` is sufficient). #### **2.5. `actions/cache@v4` used, but Gitea 1.22 may only support v3** - The PR uses `actions/cache@v4`, but: - Gitea 1.22’s Actions implementation is based on [Woodpecker](https://woodpecker-ci.org/), which currently supports `actions/cache@v3`. - `@v4` introduces breaking changes (e.g., `path` must be absolute, `restore-keys` behavior changed). - ❌ **Risk**: Caching may silently fail or behave unexpectedly. ✅ **Fix**: Use `actions/cache@v3` unless you’ve confirmed Gitea 1.22 supports `@v4`. --- ### **3. Security Issues** #### **3.1. Insecure registry (`172.0.0.29:3000`)** - All jobs pull from `172.0.0.29:3000`, which is an **HTTP (not HTTPS)** registry. - This exposes: - **Man-in-the-middle (MITM) attacks** on image pulls. - **Image tampering** (no integrity verification beyond Docker’s layer checksums). - **Credential leakage** (if auth is used, credentials are sent in plaintext). ✅ **Fixes**: 1. **Mandatory**: Use HTTPS with a valid certificate (e.g., via Let’s Encrypt or internal CA). 2. If internal CA is used, ensure all runners trust the CA cert (documented in `CICD-Pipeline.md`). 3. Add `--digests` to `docker push` to pin digests in CI (not in Dockerfiles, but in workflows). 4. **Never use `insecure-registries` in production** — it’s a security anti-pattern. 📝 **Update `CICD-Pipeline.md`**: ```markdown **⚠️ Security Note**: The current setup uses an HTTP registry. This is acceptable only in isolated, trusted networks (e.g., CI server on a private subnet). For production, switch to HTTPS with TLS. ``` #### **3.2. `curl ... | bash -` in Dockerfiles** - All Dockerfiles use: ```dockerfile RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- ... ``` ✅ `--proto '=https' --tlsv1.2` is good, but: - **Risk**: If `rustup.rs` is compromised, all images are backdoored. - **Mitigation**: Pin the `rustup.rs` script hash (not currently done). ✅ **Fix**: Download and verify hash: ```dockerfile RUN curl -sSf https://sh.rustup.rs -o /tmp/rustup.sh \ && echo "sha256:$(sha256sum /tmp/rustup.sh | cut -d' ' -f1)" \ && sh /tmp/rustup.sh -y ... ``` But note: `rustup.rs` changes with each toolchain release — this requires updating the hash in the Dockerfile. 🔁 **Alternative**: Use official `rust` images (e.g., `rust:1.88-slim`) and avoid `rustup.rs` entirely. Since `rust:1.88-slim` already has Rust 1.88, you can skip `rustup` installation. --- ### **4. Best Practices** #### **4.1. Dockerfile layer optimization** - ✅ Good: `--no-install-recommends`, `rm -rf /var/lib/apt/lists/*` - ❌ **Missed opportunity**: Combine `apt-get update` and `apt-get install` into a single `RUN` layer (already done ✅), but consider: - Using `apt-get clean` instead of `rm -rf /var/lib/apt/lists/*` (more thorough). - Using `--no-install-suggests` (already implied by `--no-install-recommends`). #### **4.2. Rustfmt/clippy in Dockerfiles** - ✅ Adding `rustup component add rustfmt clippy` is great for CI consistency. - ⚠️ **But**: These components increase image size (~100MB). If only used in test jobs (not builds), consider: - Moving them to a separate `*-dev` image (e.g., `trcaa-linux-amd64-dev`). - Or using `cargo +1.88 fmt/clippy` (uses toolchain from `rustup` but doesn’t require permanent component install). #### **4.3. Cache key strategy** - Cache keys use `hashFiles('**/Cargo.lock')`, which is correct. - ✅ Restore keys (`${{ runner.os }}-cargo-`) provide fallbacks. - ⚠️ **Risk**: If `Cargo.lock` is updated but dependencies haven’t changed (e.g., `cargo update`), cache is invalidated unnecessarily. - **Better**: Use `hashFiles('**/Cargo.toml', '**/Cargo.lock')` to avoid cache misses from `cargo update` alone. #### **4.4. `build-images.yml` uses `alpine:latest`** - ❌ **Dangerous**: `alpine:latest` is not pinned to a digest. It may pull a different Alpine version over time → non-reproducible builds. - ✅ **Fix**: Use a pinned digest: ```yaml image: alpine:3.19@sha256:... ``` Get digest via: ```sh docker pull alpine:3.19 docker inspect alpine:3.19 --format='{{index .Digest}}' ``` #### **4.5. Documentation gaps** - `CICD-Pipeline.md` doesn’t mention: - How to **trigger image rebuilds** when dependencies change (e.g., Rust 1.89 → update tag to `rust1.89-node22`). - How to **verify image contents** (e.g., `docker run --rm <image> rustc --version`). - **Rollback plan** if an image is broken. ✅ **Add**: ```markdown ## Updating Images When Rust/Node.js/openssl versions change: 1. Update the `FROM` tag in Dockerfiles (e.g., `rust:1.89-slim`). 2. Update image tag in `build-images.yml` (e.g., `rust1.89-node22`). 3. Rebuild via `workflow_dispatch`. ``` --- ### **5. Other Minor Issues** | File | Issue | Fix | |------|-------|-----| | `.docker/Dockerfile.linux-arm64` | `ARG DEBIAN_FRONTEND=noninteractive` is redundant in `ubuntu:22.04` (already set) | Remove | | `.gitea/workflows/test.yml` | `rustup component add clippy` removed in `rust-clippy` job, but Dockerfile already adds it | ✅ Correct — no need to add again. | | `.gitea/workflows/auto-tag.yml` | `git init` + `git fetch` + `git checkout` is redundant; `actions/checkout@v4` would be simpler | ✅ But acceptable for Gitea-specific auth. | | `docs/wiki/CICD-Pipeline.md` | Uses `actions/cache@v3` in examples, but PR uses `@v4` | Align to `@v4` (if confirmed supported) or revert to `@v3`. | --- ### **Recommendations Before Merge** 1. **Critical**: - Add `curl` and `jq` to `build-images.yml`. - Fix `OPENSSL_STATIC=1` issue (remove or add static libs). - Pin `alpine` image in `build-images.yml`. - Downgrade `actions/cache@v4` → `@v3` unless Gitea 1.22 supports `@v4`. 2. **High Priority**: - Add TLS to the registry (`https://172.0.0.29:3000`). - Pin `rustup.rs` hash or switch to official `rust` image layers. 3. **Medium Priority**: - Improve cache key strategy (`hashFiles('Cargo.toml', 'Cargo.lock')`). - Document image update/rollback process. 4. **Nice-to-Have**: - Consider splitting `dev` and `build` images to reduce build image size. - Add `RUN rustup show` to Dockerfiles for debugging. --- ### **Final Verdict** ✅ **Strong performance gains** — this is a high-value optimization. ⚠️ **Merge only after fixing critical bugs and security gaps.** 🎯 **Once fixed, this PR is production-ready.** Let me know if you'd like a revised diff with suggested fixes!\n\n---\n*this is an automated review from Ollama*
sarman force-pushed feat/pr-review-workflow from 30d26ed0c1 to a365cba30e 2026-04-13 01:17:28 +00:00 Compare
sarman reviewed 2026-04-13 01:21:14 +00:00
sarman left a comment
Author
Owner

🤖 Automated PR Review:\n\n### Code Review Summary

This PR introduces significant CI performance improvements by:

  • Using pre-baked Docker images (with system deps, Rust, Node.js, cross-compilers baked in) instead of installing dependencies per-job.
  • Adding cargo registry + npm caching to further accelerate builds.
  • Updating documentation accordingly.

Overall direction is excellent — the changes align well with modern CI/CD best practices for reproducibility, speed, and maintainability. However, there are several correctness, security, and operational concerns that must be addressed before merging.


🔴 1. Critical Bugs / Correctness Issues

A. rustup component add in Dockerfiles is redundant / may fail

In all three Dockerfiles (linux-amd64, linux-arm64, windows-cross), you add rustfmt and clippy via rustup component add. While this usually works, the rust:1.88-slim image already includes rustfmt and clippy by default (see Docker Hub rust image docs).

However, the --profile minimal flag used in the ARM64 Dockerfile (rustup ... --profile minimal) excludes rustfmt and clippy — so the rustup component add is necessary there.

But in the linux-amd64 and windows-cross Dockerfiles, the base image is rust:1.88-slim, which uses the default profile (default), which does include rustfmt and clippy. So:

  • rustup component add rustfmt clippy is redundant there.
  • Potential failure: If the image is not the default profile (e.g., due to future changes), the command may fail. Also, rustup component add without --toolchain may use the default toolchain — but if 1.88.0 is not the default (e.g., after rustup default was changed), it may fail or install into the wrong toolchain.

🔧 Fix:

  • For linux-amd64 and windows-cross, either:
    • Remove the rustup component add (since slim uses default profile), or
    • Explicitly specify the toolchain:
      RUN rustup component add rustfmt clippy --toolchain 1.88.0
      
  • For linux-arm64, keep as-is (since --profile minimal excludes them), but add --toolchain 1.88.0 for safety.

💡 Bonus: Consider using rustup target add ... --toolchain 1.88.0 consistently for clarity and future-proofing.


B. docker:24-clialpine:latest + docker-cli is unsafe

In build-images.yml, the jobs now use:

container:
  image: alpine:latest
...
apk add --no-cache git docker-cli

⚠️ Problem: alpine:latest is not pinned, and docker-cli is not guaranteed to be present in Alpine’s repos (it's in community repo, which may not be enabled by default). Also, alpine:latest may change unexpectedly (e.g., breaking changes in future releases), causing CI flakiness.

🔧 Fix:

  1. Pin the Alpine version (e.g., alpine:3.20).
  2. Enable community repo before installing docker-cli:
    RUN sed -i 's/^#.*community/community/' /etc/apk/repositories \
      && apk add --no-cache git docker-cli
    
    Or better: use docker:dind (Docker-in-Docker) image for building Docker images, e.g.:
    container:
      image: docker:dind
    
    This is the standard pattern for building Docker images in CI.

C. Missing --locked in cargo test / cargo clippy in test.yml

In test.yml, cargo clippy and cargo test now use --locked, but cargo fmt does not.

--locked is correct for clippy/test (ensures dependencies match Cargo.lock), but
cargo fmt should not use --locked (formatting doesn’t depend on dependency versions), and it’s harmless either way.

However, the more important issue:
⚠️ cargo test should not be run with --locked unless you intend to test against the exact locked dependency versions — but if Cargo.lock is outdated (e.g., after a PR that updated Cargo.toml but not Cargo.lock), tests may fail or run against stale code.

🔧 Recommendation:

  • Keep --locked for clippy (static analysis should use locked deps).
  • For cargo test, omit --locked unless you have a strong reason to enforce lockfile consistency (e.g., reproducibility in release builds).
    → In CI, it’s usually better to test against the current dependency set in Cargo.toml, so remove --locked from cargo test.

🛡️ 2. Security Issues

A. Insecure Registry (172.0.0.29:3000) over HTTP

All Docker images are pulled from 172.0.0.29:3000, which is clearly an internal registry over HTTP (not HTTPS).

This is acceptable only in an air-gapped, trusted internal network (as implied by 172.0.0.x), but:

  • The PR’s documentation says:

    This must be configured on every machine running an act_runner for the runner's Docker daemon to pull from the local HTTP registry.

  • ⚠️ Risk: If this setup ever leaks to a public network (e.g., misconfigured firewall), man-in-the-middle attacks could inject malicious images.

🔧 Fixes:

  1. Add a security note in CICD-Pipeline.md:

    🔒 Security Warning: This registry uses HTTP and is intended for internal use only. Never expose 172.0.0.29:3000 to untrusted networks. Consider upgrading to HTTPS with a self-signed cert (and adding it to Docker’s trusted CAs) for production environments.

  2. Add --insecure-registry to dockerd config in docs, but also suggest:

    # Safer alternative: use self-signed cert + `--add-registry`
    # (Not required now, but strongly recommended for future-proofing)
    
  3. Add a CI guard: In build-images.yml, add a step to verify image signatures (if you later adopt Notary or cosign), but for now, just document the risk.


B. curl ... | bash - in Dockerfiles

In linux-arm64 Dockerfile:

RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- ...

⚠️ Risk: Piping curl directly to sh is a known anti-pattern (even with --proto/--tlsv1.2). If the rustup.rs domain is compromised, arbitrary code runs in the container build.

🔧 Fix:

  • Download and verify checksums (if available), or at least:
    RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs -o /tmp/rustup.sh \
      && sh /tmp/rustup.sh -y ...
    
  • Better yet: use the official rust image’s pre-installed rustup (e.g., rust:1.88-slim already has rustup), so you don’t need to download it at all.

For linux-amd64 and windows-cross, you already use FROM rust:1.88-slim, so no need to download rustup.
Only linux-arm64 needs rustup installation — but it could still be avoided by using a base image like rust:1.88-cross (if available) or pre-baking rustup in the image.


📚 3. Best Practices & Maintainability

A. Cache keys should include toolchain version

Current cache keys:

key: ${{ runner.os }}-cargo-linux-amd64-${{ hashFiles('**/Cargo.lock') }}

⚠️ If the Rust toolchain changes (e.g., 1.881.89), cached artifacts may be incompatible (e.g., cargo metadata format changes). This could cause subtle build failures.

🔧 Fix: Include toolchain in cache key:

key: ${{ runner.os }}-cargo-${{ env.RUST_TOOLCHAIN }}-${{ hashFiles('**/Cargo.lock') }}

→ Set RUST_TOOLCHAIN: "1.88" in the job’s env, or use ${{ matrix.rust }} if using a matrix.

Same for npm cache: include Node.js version in key.


B. Redundant git init / git fetch in CI

All jobs do:

git init
git remote add origin ...
git fetch --depth=1 origin "$GITHUB_SHA"
git checkout FETCH_HEAD

⚠️ This is redundant if the runner is already checking out the repo (which Gitea Actions typically does automatically). The git init + remote add pattern is only needed if you’re not using the default checkout action.

🔧 Fix: Replace with standard checkout:

- uses: actions/checkout@v4
  with:
    fetch-depth: 1
    ref: ${{ github.sha }}

→ This is simpler, more robust, and avoids potential issues with detached HEAD or missing tags.

💡 If you must use custom git commands (e.g., for Gitea-specific auth), document why — but most CI systems support checkout natively.


C. Missing --no-verify in git checkout FETCH_HEAD?

In all jobs:

git checkout FETCH_HEAD

⚠️ If the commit has a GPG signature, git checkout may prompt for verification (in interactive mode), but since this is non-interactive CI, it might fail or hang.

🔧 Fix: Use --no-gpg-sign or --no-verify:

git checkout --no-verify FETCH_HEAD

D. Documentation: Incomplete build-images.yml explanation

The CICD-Pipeline.md update doesn’t explain:

  • How to trigger build-images.yml (you mention workflow_dispatch, but not how to do it via CLI/Gitea UI).
  • How to verify the image was built (e.g., docker pull 172.0.0.29:3000/...).
  • How to test the image locally (e.g., docker run --rm 172.0.0.29:3000/... rustc --version).

🔧 Add:

### Testing a pre-baked image locally
```sh
docker pull 172.0.0.29:3000/sarman/trcaa-linux-amd64:rust1.88-node22
docker run --rm 172.0.0.29:3000/sarman/trcaa-linux-amd64:rust1.88-node22 rustc --version

---

## ✅ **Final Recommendations**

| Priority | Issue | Fix |
|--------|-------|-----|
| 🔴 Critical | `docker-cli` in `alpine:latest` may not exist | Use `docker:dind` instead |
| 🔴 Critical | `rustup component add` may fail due to toolchain mismatch | Add `--toolchain 1.88.0` |
| 🟠 High | `curl \| bash` in Dockerfile | Download first, then run |
| 🟠 High | Insecure HTTP registry | Document security risks + suggest HTTPS upgrade path |
| 🟡 Medium | Cache keys don’t include toolchain version | Add `RUST_TOOLCHAIN` to key |
| 🟡 Medium | Redundant `git init`/`fetch` | Use `actions/checkout@v4` |
| 🟡 Medium | Missing `--no-verify` in `git checkout` | Add flag |
| 🟢 Low | `cargo test --locked` may be too strict | Remove `--locked` from test jobs |

---

## ✅ **Approve with Conditions**

**Status**: **Approve pending fixes for critical/high issues.**  
This PR is a **major win for CI performance** and shows strong engineering judgment — just needs the above fixes to be production-ready.

Let me know if you'd like a revised diff with the fixes applied!\n\n---\n*this is an automated review from Ollama*
🤖 Automated PR Review:\n\n### **Code Review Summary** This PR introduces **significant CI performance improvements** by: - Using **pre-baked Docker images** (with system deps, Rust, Node.js, cross-compilers baked in) instead of installing dependencies per-job. - Adding **cargo registry + npm caching** to further accelerate builds. - Updating documentation accordingly. ✅ **Overall direction is excellent** — the changes align well with modern CI/CD best practices for reproducibility, speed, and maintainability. However, there are **several correctness, security, and operational concerns** that must be addressed before merging. --- ## 🔴 **1. Critical Bugs / Correctness Issues** ### **A. `rustup component add` in Dockerfiles is redundant / may fail** In all three Dockerfiles (`linux-amd64`, `linux-arm64`, `windows-cross`), you add `rustfmt` and `clippy` via `rustup component add`. While this *usually* works, **the `rust:1.88-slim` image already includes `rustfmt` and `clippy` by default** (see [Docker Hub `rust` image docs](https://hub.docker.com/_/rust)). However, the `--profile minimal` flag used in the ARM64 Dockerfile (`rustup ... --profile minimal`) **excludes `rustfmt` and `clippy`** — so the `rustup component add` is *necessary* there. But in the `linux-amd64` and `windows-cross` Dockerfiles, the base image is `rust:1.88-slim`, which uses the **default profile** (`default`), which *does* include `rustfmt` and `clippy`. So: - ✅ `rustup component add rustfmt clippy` is **redundant** there. - ❌ **Potential failure**: If the image is *not* the default profile (e.g., due to future changes), the command may fail. Also, `rustup component add` without `--toolchain` may use the *default* toolchain — but if `1.88.0` is not the default (e.g., after `rustup default` was changed), it may fail or install into the wrong toolchain. 🔧 **Fix**: - For `linux-amd64` and `windows-cross`, either: - Remove the `rustup component add` (since `slim` uses `default` profile), **or** - Explicitly specify the toolchain: ```Dockerfile RUN rustup component add rustfmt clippy --toolchain 1.88.0 ``` - For `linux-arm64`, keep as-is (since `--profile minimal` excludes them), but add `--toolchain 1.88.0` for safety. > 💡 **Bonus**: Consider using `rustup target add ... --toolchain 1.88.0` consistently for clarity and future-proofing. --- ### **B. `docker:24-cli` → `alpine:latest` + `docker-cli` is unsafe** In `build-images.yml`, the jobs now use: ```yaml container: image: alpine:latest ... apk add --no-cache git docker-cli ``` ⚠️ **Problem**: `alpine:latest` is **not pinned**, and `docker-cli` is **not guaranteed to be present** in Alpine’s repos (it's in `community` repo, which may not be enabled by default). Also, `alpine:latest` may change unexpectedly (e.g., breaking changes in future releases), causing CI flakiness. 🔧 **Fix**: 1. Pin the Alpine version (e.g., `alpine:3.20`). 2. Enable `community` repo before installing `docker-cli`: ```Dockerfile RUN sed -i 's/^#.*community/community/' /etc/apk/repositories \ && apk add --no-cache git docker-cli ``` Or better: use `docker:dind` (Docker-in-Docker) image for building Docker images, e.g.: ```yaml container: image: docker:dind ``` This is the **standard pattern** for building Docker images in CI. --- ### **C. Missing `--locked` in `cargo test` / `cargo clippy` in `test.yml`** In `test.yml`, `cargo clippy` and `cargo test` now use `--locked`, but `cargo fmt` does **not**. ✅ `--locked` is correct for clippy/test (ensures dependencies match `Cargo.lock`), but ❌ `cargo fmt` **should not use `--locked`** (formatting doesn’t depend on dependency versions), and it’s harmless either way. However, the more important issue: ⚠️ **`cargo test` should not be run with `--locked` unless you *intend* to test against the exact locked dependency versions** — but if `Cargo.lock` is outdated (e.g., after a PR that updated `Cargo.toml` but not `Cargo.lock`), tests may fail or run against stale code. 🔧 **Recommendation**: - Keep `--locked` for clippy (static analysis should use locked deps). - For `cargo test`, **omit `--locked`** unless you have a strong reason to enforce lockfile consistency (e.g., reproducibility in release builds). → In CI, it’s usually better to test against the *current* dependency set in `Cargo.toml`, so remove `--locked` from `cargo test`. --- ## 🛡️ **2. Security Issues** ### **A. Insecure Registry (`172.0.0.29:3000`) over HTTP** All Docker images are pulled from `172.0.0.29:3000`, which is clearly an **internal registry over HTTP (not HTTPS)**. ✅ This is acceptable *only* in an **air-gapped, trusted internal network** (as implied by `172.0.0.x`), but: - ❌ The PR’s documentation says: > This must be configured on every machine running an act_runner for the runner's Docker daemon to pull from the local HTTP registry. - ⚠️ **Risk**: If this setup ever leaks to a public network (e.g., misconfigured firewall), **man-in-the-middle attacks** could inject malicious images. 🔧 **Fixes**: 1. **Add a security note** in `CICD-Pipeline.md`: > 🔒 **Security Warning**: This registry uses HTTP and is intended for internal use only. Never expose `172.0.0.29:3000` to untrusted networks. Consider upgrading to HTTPS with a self-signed cert (and adding it to Docker’s trusted CAs) for production environments. 2. **Add `--insecure-registry` to `dockerd` config in docs**, but also suggest: ```sh # Safer alternative: use self-signed cert + `--add-registry` # (Not required now, but strongly recommended for future-proofing) ``` 3. **Add a CI guard**: In `build-images.yml`, add a step to verify image signatures (if you later adopt Notary or cosign), but for now, just document the risk. --- ### **B. `curl ... | bash -` in Dockerfiles** In `linux-arm64` Dockerfile: ```Dockerfile RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- ... ``` ⚠️ **Risk**: Piping `curl` directly to `sh` is a known anti-pattern (even with `--proto`/`--tlsv1.2`). If the `rustup.rs` domain is compromised, arbitrary code runs in the container build. 🔧 **Fix**: - Download and verify checksums (if available), or at least: ```Dockerfile RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs -o /tmp/rustup.sh \ && sh /tmp/rustup.sh -y ... ``` - Better yet: use the official `rust` image’s pre-installed `rustup` (e.g., `rust:1.88-slim` already has `rustup`), so you don’t need to download it at all. > ✅ For `linux-amd64` and `windows-cross`, you already use `FROM rust:1.88-slim`, so no need to download `rustup`. > ❌ Only `linux-arm64` needs `rustup` installation — but it could still be avoided by using a base image like `rust:1.88-cross` (if available) or pre-baking `rustup` in the image. --- ## 📚 **3. Best Practices & Maintainability** ### **A. Cache keys should include toolchain version** Current cache keys: ```yaml key: ${{ runner.os }}-cargo-linux-amd64-${{ hashFiles('**/Cargo.lock') }} ``` ⚠️ If the Rust toolchain changes (e.g., `1.88` → `1.89`), cached artifacts may be incompatible (e.g., `cargo` metadata format changes). This could cause subtle build failures. 🔧 **Fix**: Include toolchain in cache key: ```yaml key: ${{ runner.os }}-cargo-${{ env.RUST_TOOLCHAIN }}-${{ hashFiles('**/Cargo.lock') }} ``` → Set `RUST_TOOLCHAIN: "1.88"` in the job’s `env`, or use `${{ matrix.rust }}` if using a matrix. Same for npm cache: include Node.js version in key. --- ### **B. Redundant `git init` / `git fetch` in CI** All jobs do: ```yaml git init git remote add origin ... git fetch --depth=1 origin "$GITHUB_SHA" git checkout FETCH_HEAD ``` ⚠️ This is redundant if the runner is already checking out the repo (which Gitea Actions typically does automatically). The `git init` + `remote add` pattern is only needed if you’re *not* using the default checkout action. 🔧 **Fix**: Replace with standard checkout: ```yaml - uses: actions/checkout@v4 with: fetch-depth: 1 ref: ${{ github.sha }} ``` → This is simpler, more robust, and avoids potential issues with detached HEAD or missing tags. > 💡 If you *must* use custom git commands (e.g., for Gitea-specific auth), document why — but most CI systems support `checkout` natively. --- ### **C. Missing `--no-verify` in `git checkout FETCH_HEAD`?** In all jobs: ```yaml git checkout FETCH_HEAD ``` ⚠️ If the commit has a GPG signature, `git checkout` may prompt for verification (in interactive mode), but since this is non-interactive CI, it might fail or hang. 🔧 **Fix**: Use `--no-gpg-sign` or `--no-verify`: ```yaml git checkout --no-verify FETCH_HEAD ``` --- ### **D. Documentation: Incomplete `build-images.yml` explanation** The `CICD-Pipeline.md` update doesn’t explain: - How to *trigger* `build-images.yml` (you mention `workflow_dispatch`, but not how to do it via CLI/Gitea UI). - How to *verify* the image was built (e.g., `docker pull 172.0.0.29:3000/...`). - How to *test* the image locally (e.g., `docker run --rm 172.0.0.29:3000/... rustc --version`). 🔧 **Add**: ```markdown ### Testing a pre-baked image locally ```sh docker pull 172.0.0.29:3000/sarman/trcaa-linux-amd64:rust1.88-node22 docker run --rm 172.0.0.29:3000/sarman/trcaa-linux-amd64:rust1.88-node22 rustc --version ``` ``` --- ## ✅ **Final Recommendations** | Priority | Issue | Fix | |--------|-------|-----| | 🔴 Critical | `docker-cli` in `alpine:latest` may not exist | Use `docker:dind` instead | | 🔴 Critical | `rustup component add` may fail due to toolchain mismatch | Add `--toolchain 1.88.0` | | 🟠 High | `curl \| bash` in Dockerfile | Download first, then run | | 🟠 High | Insecure HTTP registry | Document security risks + suggest HTTPS upgrade path | | 🟡 Medium | Cache keys don’t include toolchain version | Add `RUST_TOOLCHAIN` to key | | 🟡 Medium | Redundant `git init`/`fetch` | Use `actions/checkout@v4` | | 🟡 Medium | Missing `--no-verify` in `git checkout` | Add flag | | 🟢 Low | `cargo test --locked` may be too strict | Remove `--locked` from test jobs | --- ## ✅ **Approve with Conditions** **Status**: **Approve pending fixes for critical/high issues.** This PR is a **major win for CI performance** and shows strong engineering judgment — just needs the above fixes to be production-ready. Let me know if you'd like a revised diff with the fixes applied!\n\n---\n*this is an automated review from Ollama*
sarman merged commit 21de93174c into master 2026-04-13 01:23:50 +00:00
Sign in to join this conversation.
No reviewers
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: sarman/tftsr-devops_investigation#36
No description provided.