Skip to content

chore(ci): rebrand and streamline the release pipeline#66

Merged
imajes merged 10 commits into
mainfrom
feat/improve-ci-process
Mar 19, 2026
Merged

chore(ci): rebrand and streamline the release pipeline#66
imajes merged 10 commits into
mainfrom
feat/improve-ci-process

Conversation

@imajes

@imajes imajes commented Mar 19, 2026

Copy link
Copy Markdown
Contributor
  • CI/CD:

    • replace the old develop/master pipelines with explicit validation, nightly, preview, and release workflows
    • switch stable releases to main, keep develop for nightly builds, and make preview image builds manual-only
    • update the reusable migration check so callers pass explicit refs and validation works correctly across PRs, pushes, and release flows
  • Packaging:

    • consolidate container packaging onto the root Dockerfile and remove Dockerfile.ci
    • stop mutating tracked source files during image builds by building frontend and backend assets inside the container pipeline
    • remove vendored unrar binaries and build the upstream CLI from source during the image build
    • keep runtime compatibility for existing Booklore deployments by preserving env vars, ports, mount paths, and legacy internal user defaults
  • Deploy Surface:

    • move deployment examples under deploy/ and Docker runtime assets under packaging/docker
    • rebrand image, chart, and helper-script references from Booklore to Grimmory on the build and release surfaces only
    • update Compose, Helm, and Podman examples to reflect Grimmory image names and the stable/nightly tag model
  • Docs:

    • add the implementation plan under docs/plans/ci-cd-rebrand-main-nightly.md
    • refresh README, contributing guidance, PR template, and operational docs to match the new branch, image, and upgrade story
    • document the Booklore-to-Grimmory image swap path so existing self-hosted installs can upgrade by changing only the image reference
  • Validation:

    • pass git diff --check
    • parse all workflow YAML successfully
    • pass shellcheck on the touched shell scripts

Summary by CodeRabbit

  • New Features

    • Added reusable CI workflows (PR validation, semantic PR title check, test suite, preview, nightly, semantic stable, release preview) and image publish flows.
  • Documentation

    • Rebranded Booklore → Grimmory across docs, README, and deploy examples; added CI/CD and semantic-release plans and a new CHANGELOG.
  • Chores

    • Consolidated Docker build, updated images/entrypoint, tightened dockerignore, added release tooling/scripts, deploy manifests, and Dependabot config.

- CI/CD:
  - replace the old `develop`/`master` pipelines with explicit validation, nightly, preview, and release workflows
  - switch stable releases to `main`, keep `develop` for nightly builds, and make preview image builds manual-only
  - update the reusable migration check so callers pass explicit refs and validation works correctly across PRs, pushes, and release flows

- Packaging:
  - consolidate container packaging onto the root `Dockerfile` and remove `Dockerfile.ci`
  - stop mutating tracked source files during image builds by building frontend and backend assets inside the container pipeline
  - remove vendored `unrar` binaries and build the upstream CLI from source during the image build
  - keep runtime compatibility for existing Booklore deployments by preserving env vars, ports, mount paths, and legacy internal user defaults

- Deploy Surface:
  - move deployment examples under `deploy/` and Docker runtime assets under `packaging/docker`
  - rebrand image, chart, and helper-script references from Booklore to Grimmory on the build and release surfaces only
  - update Compose, Helm, and Podman examples to reflect Grimmory image names and the stable/nightly tag model

- Docs:
  - add the implementation plan under `docs/plans/ci-cd-rebrand-main-nightly.md`
  - refresh README, contributing guidance, PR template, and operational docs to match the new branch, image, and upgrade story
  - document the Booklore-to-Grimmory image swap path so existing self-hosted installs can upgrade by changing only the image reference

- Validation:
  - pass `git diff --check`
  - parse all workflow YAML successfully
  - pass `shellcheck` on the touched shell scripts
@coderabbitai

coderabbitai Bot commented Mar 19, 2026

Copy link
Copy Markdown
Contributor

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Rebrands Booklore → Grimmory across docs, scripts, CI, Helm/chart and deploy examples; replaces Release Drafter with semantic-release tooling and workflows; adds reusable test and migration-check workflows, preview/nightly/release image pipelines; consolidates Docker builds, tightens .dockerignore, and adds packaging entrypoint plus Podman/Compose manifests.

Changes

Cohort / File(s) Summary
CI: workflows (new & updated)
.github/workflows/ci-validate.yml, .github/workflows/test-suite.yml, .github/workflows/migrations-check.yml, .github/workflows/preview-image.yml, .github/workflows/publish-nightly.yml, .github/workflows/publish-release.yml, .github/workflows/release-main.yml, .github/workflows/release-preview.yml, .github/workflows/semantic-pr-title.yml
Added validation and semantic PR title checks; introduced reusable test-suite and normalized migrations-check inputs/outputs; added preview/nightly/release/semantic-release pipelines and Buildx publishing steps. Review ref normalization, workflow_call inputs, permissions, and build/publish credentials.
Release tooling
tools/release/*, CHANGELOG.md, .github/release-drafter.yml (deleted)
Added tools/release/package.json and release.config.cjs for semantic-release, created CHANGELOG.md, removed Release Drafter config. Review plugin rules, tag format, and dry-run settings.
Docker build & packaging
Dockerfile, Dockerfile.ci (deleted), packaging/docker/entrypoint.sh
Consolidated Dockerfiles (removed Dockerfile.ci), renamed build stages, embedded unrar build stage, updated labels/entrypoint and APP_VERSION/APP_REVISION handling, and added runtime entrypoint that manages UID/GID. Check stage outputs, ARG/ENV defaults, and entrypoint user logic.
.dockerignore & build context
.dockerignore
Switched to deny-all (**) with explicit unignores for Dockerfile/.dockerignore and project dirs; expanded API ignores to booklore-api/build and booklore-api/.gradle. Verify included build context paths.
Branding & metadata
CONTRIBUTING.md, README.md, .github/pull_request_template.md, scripts/*, docs/*, booklore-api/src/main/resources/application.yaml, booklore-api/src/main/java/.../VersionService.java, booklore-ui/...
Rebranded Booklore → Grimmory in docs, templates, scripts, UI and backend; updated PR template links and app.version to ${APP_VERSION:development}. Review external URLs and version propagation.
Deploy examples (added)
deploy/compose/docker-compose.yml, deploy/helm/grimmory/..., deploy/podman/quadlet/*
Added Docker Compose example, Helm chart renamed to grimmory (helpers/values updated), and Podman Quadlet units/volumes. Validate Helm helper renames, values defaults, Compose envs, healthchecks and image names.
Deprecated examples (removed)
example-docker/docker-compose.yml, example-podman/*
Removed legacy example deployments (moved under deploy/). Check for stale references.
Docs & plans
docs/plans/ci-cd-rebrand-main-nightly.md, additional docs/* updates
Added CI/CD rebrand and semantic-release migration plans; updated docs to Grimmory naming, images, and ports. Review operational instructions and links.
Scripts & notifications
scripts/release/docker-buildx-push.sh, scripts/release/notify-discord.sh, scripts/i18n/weblate-setup.sh
Updated scripts to use Grimmory image/repo names and messaging; confirm publish targets and token usage.
Tests integration
.github/workflows/test-suite.yml, booklore-ui/..., booklore-api/...
New reusable test-suite workflow exposing checkout_ref with backend/frontend jobs, artifact publishing, and explicit failure gating. Verify artifact globs, report paths, cache keys, and continue-on-error semantics.
sequenceDiagram
participant PR as "PR / Push"
participant CI as "CI - Validate"
participant MIG as "Migrations Check (reusable)"
participant TEST as "Test Suite (reusable)"
participant BUILD as "Packaging / Buildx"
participant REG as "Registry (GHCR / Docker Hub)"

PR->>CI: trigger validation/workflows
CI->>MIG: call migrations-check (pass base_ref/head_ref/checkout_ref)
MIG-->>CI: return normalized base_ref & head_ref
CI->>TEST: invoke test-suite (checkout_ref = resolved ref)
TEST-->>CI: upload test artifacts & results
CI->>BUILD: run packaging-smoke-test / buildx (multi-arch, cache)
BUILD->>REG: push images (when publishing)
REG-->>BUILD: acknowledge tags
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Poem

🐰 I hopped from Booklore to Grimmory's glen,

I stitched Docker, Helm, and CI again.
Pipelines hum and images glide,
Docs and scripts in tidy stride.
A rabbit cheers this rebrand den.

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description is largely incomplete. It lacks the linked issue reference, mandatory testing section, screenshots/recordings, and pre-submission checklist that are required by the template. Add a linked issue reference (Fixes #issue-number), fill out the mandatory Testing section with manual steps and actual test output, provide screen recordings or screenshots proving the change works, and complete the pre-submission checklist.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: rebranding and streamlining the CI/CD release pipeline, which is the primary objective of this large pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/improve-ci-process
📝 Coding Plan
  • Generate coding plan for human review comments

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

@github-actions

Copy link
Copy Markdown
Contributor

Frontend Test Results

419 tests   419 ✅  2s ⏱️
  8 suites    0 💤
  1 files      0 ❌

Results for commit 0baa9a1.

@github-actions

Copy link
Copy Markdown
Contributor

Backend Test Results

  472 files    472 suites   2m 39s ⏱️
3 463 tests 3 448 ✅ 15 💤 0 ❌
3 520 runs  3 505 ✅ 15 💤 0 ❌

Results for commit 0baa9a1.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 6

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
CONTRIBUTING.md (2)

384-390: ⚠️ Potential issue | 🟡 Minor

Inconsistent branding in License and closing sections.

The License section and closing message still reference "Booklore" instead of "Grimmory", which is inconsistent with the rebranding applied elsewhere in the document.

📝 Proposed fix
 ## License

-Booklore is licensed under the [AGPL-3.0 License](./LICENSE). By contributing, you agree that your contributions will be licensed under the same terms.
+Grimmory is licensed under the [AGPL-3.0 License](./LICENSE). By contributing, you agree that your contributions will be licensed under the same terms.

 ---

-Thank you for being part of the Booklore community!
+Thank you for being part of the Grimmory community!
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@CONTRIBUTING.md` around lines 384 - 390, The License section header "##
License" and the lines referencing "Booklore" should be updated to the new brand
"Grimmory": replace the string "Booklore" with "Grimmory" in the License
paragraph and in the closing message so they read "Grimmory is licensed under
the [AGPL-3.0 License](./LICENSE). By contributing, you agree that your
contributions will be licensed under the same terms." and "Thank you for being
part of the Grimmory community!" respectively, ensuring consistent branding
across the document.

337-337: ⚠️ Potential issue | 🟡 Minor

Inconsistent branding: "Booklore version" should be "Grimmory version".

The bug report example still references "Booklore 1.2.0" which is inconsistent with the rebrand to Grimmory throughout the rest of the document.

📝 Proposed fix
-Environment: Chrome 120, macOS 14.2, Booklore 1.2.0
+Environment: Chrome 120, macOS 14.2, Grimmory 1.2.0
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@CONTRIBUTING.md` at line 337, Replace the inconsistent "Booklore" branding in
the bug report example by changing the string "Booklore version" (and any
instance like "Booklore 1.2.0") to "Grimmory version" and update the example
version text accordingly; locate and edit the line containing the bullet
"Environment details (OS, browser, Booklore version)" in CONTRIBUTING.md and
ensure any other occurrences of "Booklore" in that bug report example are
renamed to "Grimmory" to match the rest of the document.
.github/workflows/migrations-check.yml (1)

96-102: ⚠️ Potential issue | 🟡 Minor

Update Flyway to the latest version.

The workflow uses flyway/flyway:11.19.0-alpine, but the latest version is 12.1.1. Update to the latest stable version to benefit from bug fixes, security patches, and improvements.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/migrations-check.yml around lines 96 - 102, Update the
Flyway container image reference used in the CI migration step: replace the
hardcoded image tag "flyway/flyway:11.19.0-alpine" in the docker run invocation
with the latest stable image "flyway/flyway:12.1.1" so the workflow pulls Flyway
12.1.1 when running the migrate command; ensure the rest of the docker run flags
(-url, -user, -password, -locations, migrate) and the mounted volume remain
unchanged.
🧹 Nitpick comments (10)
deploy/podman/quadlet/grimmory-db.container (1)

16-17: Use separate secrets for root and application DB passwords.

Line 16 and Line 17 currently bind the same secret to both root and app credentials, which reduces blast-radius isolation.

🔐 Suggested hardening diff
-Secret=grimmory_db_pass,type=env,target=MYSQL_ROOT_PASSWORD
-Secret=grimmory_db_pass,type=env,target=MYSQL_PASSWORD
+Secret=grimmory_db_root_pass,type=env,target=MYSQL_ROOT_PASSWORD
+Secret=grimmory_db_app_pass,type=env,target=MYSQL_PASSWORD
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@deploy/podman/quadlet/grimmory-db.container` around lines 16 - 17, The two
Secret entries bind the same secret name (grimmory_db_pass) to both
MYSQL_ROOT_PASSWORD and MYSQL_PASSWORD, so create and use distinct secrets
(e.g., grimmory_db_root_pass and grimmory_db_app_pass) and update the two Secret
lines so the target=MYSQL_ROOT_PASSWORD uses the root secret and
target=MYSQL_PASSWORD uses the app secret; also ensure any secret creation/CI
manifests that currently create grimmory_db_pass are updated to create both
unique secrets and any code/config that reads those env vars is left unchanged.
.github/workflows/preview-image.yml (2)

71-76: Dual cache-to targets may cause redundant writes.

Writing to both type=gha and type=registry caches on every preview build could increase build times and storage costs. For preview builds (which are ephemeral), consider using only the GHA cache, reserving registry cache writes for release/nightly workflows.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/preview-image.yml around lines 71 - 76, The workflow
writes cache-to entries for both type=gha and type=registry in the
preview-image.yml (the cache-to block), causing redundant registry writes for
ephemeral preview builds; change the preview workflow to only write the GHA
cache (remove or conditionally disable the registry cache-to entry) so
preview-image.yml uses type=gha,mode=max cache-to while reserving the registry
cache-to (type=registry,ref=...,mode=max) for release/nightly workflows or
behind a conditional check.

33-44: Potential shell injection via workflow input.

The inputs.pr_number is directly interpolated into the shell script without sanitization. While workflow_dispatch inputs are manually triggered by authorized users, a malicious or careless input like "; rm -rf /; " could cause unintended behavior.

Consider validating the input or using environment variables to avoid direct interpolation:

♻️ Proposed fix using environment variable
      - name: Generate Preview Tag
+       env:
+         PR_NUMBER: ${{ inputs.pr_number }}
        run: |
          short_sha=$(git rev-parse --short HEAD)

-         if [ -n "${{ inputs.pr_number }}" ]; then
-           preview_tag="pr-${{ inputs.pr_number }}-${short_sha}"
+         if [ -n "$PR_NUMBER" ]; then
+           # Validate pr_number is numeric
+           if ! [[ "$PR_NUMBER" =~ ^[0-9]+$ ]]; then
+             echo "Invalid PR number: $PR_NUMBER"
+             exit 1
+           fi
+           preview_tag="pr-${PR_NUMBER}-${short_sha}"
          else
            preview_tag="preview-${short_sha}"
          fi

          echo "preview_tag=$preview_tag" >> "$GITHUB_ENV"
          echo "commit_sha=$(git rev-parse HEAD)" >> "$GITHUB_ENV"
          echo "Preview tag: $preview_tag"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/preview-image.yml around lines 33 - 44, The workflow
directly interpolates inputs.pr_number into the shell and assigns preview_tag,
which allows shell injection; instead, capture the input into a safe environment
variable (e.g., PR_NUMBER) and validate/sanitize it in the shell before using it
to build preview_tag (for example allow only digits or alphanumerics, reject or
strip anything else), always quote expansions (use "$PR_NUMBER") and use a safe
fallback path when validation fails so preview_tag is never constructed from
unsanitized input; update the logic that sets preview_tag and the uses of
inputs.pr_number to reference the sanitized PR_NUMBER variable and ensure
commit_sha/preview_tag are echoed from the sanitized values.
.github/workflows/publish-release.yml (1)

48-167: Significant code duplication with ci-validate.yml test jobs.

The backend-tests and frontend-tests jobs here are near-identical copies of those in ci-validate.yml. This creates maintenance burden—any fix must be applied in both places.

Consider extracting these into reusable workflows (similar to migrations-check.yml), or verify that the commit being released has already passed CI validation on main.

♻️ Alternative: Verify CI status instead of re-running tests

If the release workflow requires that the ref already passed CI on main, you could use the GitHub API to verify the commit status instead of re-running all tests:

  verify-ci-passed:
    name: Verify CI Status
    needs: [resolve_ref]
    runs-on: ubuntu-latest
    steps:
      - name: Check commit status
        env:
          GH_TOKEN: ${{ github.token }}
        run: |
          status=$(gh api repos/${{ github.repository }}/commits/${{ needs.resolve_ref.outputs.commit_sha }}/status --jq '.state')
          if [ "$status" != "success" ]; then
            echo "CI has not passed for this commit"
            exit 1
          fi
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/publish-release.yml around lines 48 - 167, The
backend-tests and frontend-tests jobs duplicate the same test logic already
present in ci-validate.yml; refactor by extracting these jobs into a reusable
workflow or calling an existing reusable workflow (similar to
migrations-check.yml) instead of duplicating steps, or replace them with a
Verify CI Status job that checks the commit status using the GitHub API; update
the workflow to remove the duplicated job definitions (backend-tests,
frontend-tests) and either reference the reusable workflow or add a
verify-ci-passed job that queries the commit status for
needs.resolve_ref.outputs.commit_sha and fails if not "success".
.github/workflows/ci-validate.yml (2)

101-103: npm audit may cause spurious CI failures on transitive dependency issues.

The npm audit --audit-level=high step will fail the job if any high-severity vulnerabilities are detected in dependencies, even if they're transitive and not directly exploitable in this codebase. Consider adding continue-on-error: true with a separate advisory step, or use --audit-level=critical for blocking failures.

♻️ Option: Make audit advisory rather than blocking
      - name: Audit Frontend Dependencies
        working-directory: ./booklore-ui
-       run: npm audit --audit-level=high
+       run: npm audit --audit-level=high || echo "::warning::npm audit found high-severity vulnerabilities"
+       continue-on-error: true
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/ci-validate.yml around lines 101 - 103, The CI step named
"Audit Frontend Dependencies" currently runs npm audit with "--audit-level=high"
which can cause spurious failures on transitive issues; update that step (the
block containing the name "Audit Frontend Dependencies" and the run command "npm
audit --audit-level=high") to either add "continue-on-error: true" so the audit
is advisory, or lower its strictness by changing the run to "npm audit
--audit-level=critical" so only critical issues fail the job; implement one of
these two fixes to avoid blocking CI on non-actionable transitive
vulnerabilities.

17-20: Verify base_ref fallback handles edge cases correctly.

The complex expression for base_ref uses format('{0}^', github.sha) as a fallback when github.event.before is the null SHA (new branch push). However, the migrations-check.yml workflow already has normalization logic (lines 44-50) that handles the null SHA case by deriving the parent.

This creates redundant fallback logic in two places. Consider simplifying by always passing the raw values and letting the reusable workflow handle normalization:

♻️ Simplify by delegating normalization to reusable workflow
      base_ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.base.sha || (github.event.before != '0000000000000000000000000000000000000000' && github.event.before || format('{0}^', github.sha)) }}
+     # Could simplify to:
+     # base_ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.base.sha || github.event.before }}
+     # The reusable workflow already handles null SHA normalization
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/ci-validate.yml around lines 17 - 20, The base_ref
expression includes a redundant fallback (format('{0}^', github.sha)) that
duplicates normalization logic performed in the reusable workflow; remove the
complex ternary and pass the raw event values so the called workflow handles
null-SHA normalization. Concretely, set base_ref to use the raw PR base or the
event.before (e.g. base_ref: ${{ github.event.pull_request.base.sha ||
github.event.before }}), and simplify head_ref and checkout_ref to use the raw
PR head or github.sha (e.g. head_ref: ${{ github.event.pull_request.head.sha ||
github.sha }} and checkout_ref: ${{ github.event.pull_request.head.sha ||
github.sha }}), leaving normalization to the reusable migrations-check.yml
logic.
deploy/podman/quadlet/grimmory.container (1)

8-20: Duplicated version in image tag and APP_VERSION environment variable.

The version v0.38.2 is hardcoded in both the Image= directive (line 8) and the APP_VERSION environment variable (line 20). This duplication creates maintenance overhead and risk of version drift.

Consider documenting that users should update both values together, or note that APP_VERSION can be derived at runtime if the application supports it.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@deploy/podman/quadlet/grimmory.container` around lines 8 - 20, The Image= and
Environment=APP_VERSION entries duplicate the same hardcoded version (v0.38.2);
remove the drift risk by either deleting the hardcoded APP_VERSION env var and
letting the application derive its version at runtime, or implement a single
source of truth (e.g., templating/replacement that sets both Image= and
APP_VERSION from one variable) so they cannot diverge; update the
grimmory.container manifest to use only one authoritative version source and add
a short comment explaining which approach is used.
.github/workflows/publish-nightly.yml (2)

33-36: Unnecessary pull-requests: write permission for nightly workflow.

This workflow runs on schedule and workflow_dispatch triggers only—there's no PR context to post comments to. The pull-requests: write permission can be removed to follow least-privilege principles.

♻️ Proposed fix
     permissions:
       contents: read
       checks: write
-      pull-requests: write
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/publish-nightly.yml around lines 33 - 36, Remove the
unnecessary pull-requests write permission from the GitHub Actions permissions
block to follow least-privilege principles: edit the permissions mapping where
keys are "contents", "checks", and "pull-requests" and delete the
"pull-requests: write" entry so the workflow only grants the required "contents:
read" and "checks: write" permissions for the scheduled/workflow_dispatch
nightly run.

88-91: Same unnecessary permission in frontend-tests job.

Same issue as backend-tests—remove pull-requests: write since there's no PR context in schedule/dispatch triggers.

♻️ Proposed fix
     permissions:
       contents: read
       checks: write
-      pull-requests: write
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/publish-nightly.yml around lines 88 - 91, In the
frontend-tests job remove the unnecessary pull-requests: write permission from
the permissions block (i.e., delete the "pull-requests: write" entry) because
this workflow runs on schedule/dispatch and has no PR context; update the
permissions list so it only contains contents: read and checks: write to match
the backend-tests fix.
Dockerfile (1)

6-7: Consider removing --force flag from npm ci.

The --force flag bypasses peer dependency validation, which can mask legitimate compatibility issues. If this is needed for specific peer dependency conflicts, consider documenting the reason in a comment or resolving the underlying conflicts.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfile` around lines 6 - 7, The Dockerfile RUN step uses "npm ci --force
--no-audit --no-fund" which bypasses peer dependency validation; remove the
"--force" flag from that npm ci invocation in the RUN command (or if you must
keep it for a documented reason, add an inline comment above the RUN explaining
the specific peer-dependency conflict and why --force is required). Update the
RUN line that contains the npm ci command accordingly and ensure any CI docs
mention the chosen approach.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@deploy/podman/quadlet/grimmory.container`:
- Around line 1-28: The unit file for the Quadlet container
(ContainerName=grimmory, Image=ghcr.io/grimmory-tools/grimmory:v0.38.2) is
missing an [Install] section so it can't be enabled to start at boot; add an
[Install] section with a WantedBy target (e.g., WantedBy=multi-user.target) so
users can run systemctl enable grimmory.container (or enable the pod) and have
it started automatically; ensure the section is appended to the file and matches
the unit name used by Podman/ systemd integration.

In `@Dockerfile`:
- Around line 44-46: The Dockerfile RUN step that downloads and compiles unrar
(uses UNRAR_VERSION, unrarsrc.tar.gz, and make -C unrar) must verify the tarball
integrity before extraction/compilation: fetch or embed the expected SHA256 for
the corresponding UNRAR_VERSION, download the tarball and its checksum (or echo
the expected SHA256), validate via sha256sum -c (or echo "<sha> 
unrarsrc.tar.gz" | sha256sum -c -), and only proceed to tar -xzf and make -C
unrar if the checksum verification succeeds; on failure, abort the build with a
non-zero exit so compromised artifacts are not used.

In `@docs/forward-auth-with-proxy.md`:
- Line 7: Fix the invalid emphasis in the warning line by removing the spaces
inside the bold markers so the markdown renders and satisfies MD037; update the
text `** Important**: Enabling forward auth...` to `**Important**: Enabling
forward auth...` (ensure both opening and closing `**` surround the word
"Important" with no extra spaces) in docs/forward-auth-with-proxy.md.

In `@docs/OIDC-Setup-With-PocketID.md`:
- Line 56: Update the user-facing documentation string that currently reads
"Github" to the correct capitalization "GitHub" in the sentence after "Save
Settings" (the line that also references raising an issue on the [Github] link);
change the link text to "GitHub" while leaving the URL intact so the display
name is corrected without affecting the link target.

In `@packaging/docker/entrypoint.sh`:
- Around line 10-13: Before calling adduser, detect if a user with the name in
APP_USER already exists (use getent passwd "$APP_USER"); if it exists compare
its UID to USER_ID and handle a mismatch by failing fast with a clear error or
choosing a different username instead of blindly running adduser. Update the
branch that currently checks getent passwd "$USER_ID" and then runs adduser to
first check getent passwd "$APP_USER", compare the existing UID to "$USER_ID"
and only call adduser (and addgroup) when no conflicting username/UID mapping
exists; ensure to reference the variables APP_USER, USER_ID, GROUP_ID and the
commands addgroup/adduser/getent in your changes.

In `@README.md`:
- Around line 106-113: The README uses a hardcoded APP_VERSION=v0.38.2 while the
convenience image tag above is grimmory/grimmory:latest, causing mismatched
runtime metadata; update the documentation so APP_VERSION matches the chosen
image tag (either set APP_VERSION to v0.38.2 when using
grimmory/grimmory:v0.38.2 or change it to vLATEST/ latest when using
grimmory/grimmory:latest), and add a short note next to the image and
APP_VERSION lines (referencing the image tag and APP_VERSION entries)
instructing maintainers to keep these values in sync or to remove APP_VERSION
when relying on the image tag.

---

Outside diff comments:
In @.github/workflows/migrations-check.yml:
- Around line 96-102: Update the Flyway container image reference used in the CI
migration step: replace the hardcoded image tag "flyway/flyway:11.19.0-alpine"
in the docker run invocation with the latest stable image "flyway/flyway:12.1.1"
so the workflow pulls Flyway 12.1.1 when running the migrate command; ensure the
rest of the docker run flags (-url, -user, -password, -locations, migrate) and
the mounted volume remain unchanged.

In `@CONTRIBUTING.md`:
- Around line 384-390: The License section header "## License" and the lines
referencing "Booklore" should be updated to the new brand "Grimmory": replace
the string "Booklore" with "Grimmory" in the License paragraph and in the
closing message so they read "Grimmory is licensed under the [AGPL-3.0
License](./LICENSE). By contributing, you agree that your contributions will be
licensed under the same terms." and "Thank you for being part of the Grimmory
community!" respectively, ensuring consistent branding across the document.
- Line 337: Replace the inconsistent "Booklore" branding in the bug report
example by changing the string "Booklore version" (and any instance like
"Booklore 1.2.0") to "Grimmory version" and update the example version text
accordingly; locate and edit the line containing the bullet "Environment details
(OS, browser, Booklore version)" in CONTRIBUTING.md and ensure any other
occurrences of "Booklore" in that bug report example are renamed to "Grimmory"
to match the rest of the document.

---

Nitpick comments:
In @.github/workflows/ci-validate.yml:
- Around line 101-103: The CI step named "Audit Frontend Dependencies" currently
runs npm audit with "--audit-level=high" which can cause spurious failures on
transitive issues; update that step (the block containing the name "Audit
Frontend Dependencies" and the run command "npm audit --audit-level=high") to
either add "continue-on-error: true" so the audit is advisory, or lower its
strictness by changing the run to "npm audit --audit-level=critical" so only
critical issues fail the job; implement one of these two fixes to avoid blocking
CI on non-actionable transitive vulnerabilities.
- Around line 17-20: The base_ref expression includes a redundant fallback
(format('{0}^', github.sha)) that duplicates normalization logic performed in
the reusable workflow; remove the complex ternary and pass the raw event values
so the called workflow handles null-SHA normalization. Concretely, set base_ref
to use the raw PR base or the event.before (e.g. base_ref: ${{
github.event.pull_request.base.sha || github.event.before }}), and simplify
head_ref and checkout_ref to use the raw PR head or github.sha (e.g. head_ref:
${{ github.event.pull_request.head.sha || github.sha }} and checkout_ref: ${{
github.event.pull_request.head.sha || github.sha }}), leaving normalization to
the reusable migrations-check.yml logic.

In @.github/workflows/preview-image.yml:
- Around line 71-76: The workflow writes cache-to entries for both type=gha and
type=registry in the preview-image.yml (the cache-to block), causing redundant
registry writes for ephemeral preview builds; change the preview workflow to
only write the GHA cache (remove or conditionally disable the registry cache-to
entry) so preview-image.yml uses type=gha,mode=max cache-to while reserving the
registry cache-to (type=registry,ref=...,mode=max) for release/nightly workflows
or behind a conditional check.
- Around line 33-44: The workflow directly interpolates inputs.pr_number into
the shell and assigns preview_tag, which allows shell injection; instead,
capture the input into a safe environment variable (e.g., PR_NUMBER) and
validate/sanitize it in the shell before using it to build preview_tag (for
example allow only digits or alphanumerics, reject or strip anything else),
always quote expansions (use "$PR_NUMBER") and use a safe fallback path when
validation fails so preview_tag is never constructed from unsanitized input;
update the logic that sets preview_tag and the uses of inputs.pr_number to
reference the sanitized PR_NUMBER variable and ensure commit_sha/preview_tag are
echoed from the sanitized values.

In @.github/workflows/publish-nightly.yml:
- Around line 33-36: Remove the unnecessary pull-requests write permission from
the GitHub Actions permissions block to follow least-privilege principles: edit
the permissions mapping where keys are "contents", "checks", and "pull-requests"
and delete the "pull-requests: write" entry so the workflow only grants the
required "contents: read" and "checks: write" permissions for the
scheduled/workflow_dispatch nightly run.
- Around line 88-91: In the frontend-tests job remove the unnecessary
pull-requests: write permission from the permissions block (i.e., delete the
"pull-requests: write" entry) because this workflow runs on schedule/dispatch
and has no PR context; update the permissions list so it only contains contents:
read and checks: write to match the backend-tests fix.

In @.github/workflows/publish-release.yml:
- Around line 48-167: The backend-tests and frontend-tests jobs duplicate the
same test logic already present in ci-validate.yml; refactor by extracting these
jobs into a reusable workflow or calling an existing reusable workflow (similar
to migrations-check.yml) instead of duplicating steps, or replace them with a
Verify CI Status job that checks the commit status using the GitHub API; update
the workflow to remove the duplicated job definitions (backend-tests,
frontend-tests) and either reference the reusable workflow or add a
verify-ci-passed job that queries the commit status for
needs.resolve_ref.outputs.commit_sha and fails if not "success".

In `@deploy/podman/quadlet/grimmory-db.container`:
- Around line 16-17: The two Secret entries bind the same secret name
(grimmory_db_pass) to both MYSQL_ROOT_PASSWORD and MYSQL_PASSWORD, so create and
use distinct secrets (e.g., grimmory_db_root_pass and grimmory_db_app_pass) and
update the two Secret lines so the target=MYSQL_ROOT_PASSWORD uses the root
secret and target=MYSQL_PASSWORD uses the app secret; also ensure any secret
creation/CI manifests that currently create grimmory_db_pass are updated to
create both unique secrets and any code/config that reads those env vars is left
unchanged.

In `@deploy/podman/quadlet/grimmory.container`:
- Around line 8-20: The Image= and Environment=APP_VERSION entries duplicate the
same hardcoded version (v0.38.2); remove the drift risk by either deleting the
hardcoded APP_VERSION env var and letting the application derive its version at
runtime, or implement a single source of truth (e.g., templating/replacement
that sets both Image= and APP_VERSION from one variable) so they cannot diverge;
update the grimmory.container manifest to use only one authoritative version
source and add a short comment explaining which approach is used.

In `@Dockerfile`:
- Around line 6-7: The Dockerfile RUN step uses "npm ci --force --no-audit
--no-fund" which bypasses peer dependency validation; remove the "--force" flag
from that npm ci invocation in the RUN command (or if you must keep it for a
documented reason, add an inline comment above the RUN explaining the specific
peer-dependency conflict and why --force is required). Update the RUN line that
contains the npm ci command accordingly and ensure any CI docs mention the
chosen approach.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 61eb6001-ee95-4c9c-b02e-72c83abc6a10

📥 Commits

Reviewing files that changed from the base of the PR and between 6b0c4aa and 0baa9a1.

📒 Files selected for processing (43)
  • .dockerignore
  • .github/pull_request_template.md
  • .github/release-drafter.yml
  • .github/workflows/ci-validate.yml
  • .github/workflows/migrations-check.yml
  • .github/workflows/preview-image.yml
  • .github/workflows/publish-nightly.yml
  • .github/workflows/publish-release.yml
  • CONTRIBUTING.md
  • Dockerfile
  • Dockerfile.ci
  • README.md
  • booklore-api/src/main/resources/application.yaml
  • deploy/compose/docker-compose.yml
  • deploy/helm/grimmory/Chart.yaml
  • deploy/helm/grimmory/templates/_helpers.tpl
  • deploy/helm/grimmory/templates/deployment.yaml
  • deploy/helm/grimmory/templates/ingress.yaml
  • deploy/helm/grimmory/templates/pvc.yaml
  • deploy/helm/grimmory/templates/service.yaml
  • deploy/helm/grimmory/templates/serviceaccount.yaml
  • deploy/helm/grimmory/values.yaml
  • deploy/podman/quadlet/README.md
  • deploy/podman/quadlet/grimmory-data.volume
  • deploy/podman/quadlet/grimmory-db.container
  • deploy/podman/quadlet/grimmory-db.volume
  • deploy/podman/quadlet/grimmory.container
  • deploy/podman/quadlet/grimmory.pod
  • docker/unrar/unrar-amd64
  • docker/unrar/unrar-arm64
  • docs/Komga-API.md
  • docs/OIDC-Setup-With-PocketID.md
  • docs/forward-auth-with-proxy.md
  • docs/plans/ci-cd-rebrand-main-nightly.md
  • example-docker/docker-compose.yml
  • example-podman/booklore-data.volume
  • example-podman/booklore-db.container
  • example-podman/booklore-db.volume
  • example-podman/booklore.container
  • packaging/docker/entrypoint.sh
  • scripts/i18n/weblate-setup.sh
  • scripts/release/docker-buildx-push.sh
  • scripts/release/notify-discord.sh
💤 Files with no reviewable changes (6)
  • example-podman/booklore-db.volume
  • example-podman/booklore-data.volume
  • example-podman/booklore-db.container
  • Dockerfile.ci
  • example-docker/docker-compose.yml
  • example-podman/booklore.container

Comment thread deploy/podman/quadlet/grimmory.container
Comment thread Dockerfile Outdated
Comment thread docs/forward-auth-with-proxy.md Outdated
Comment thread docs/OIDC-Setup-With-PocketID.md Outdated
Comment thread packaging/docker/entrypoint.sh
Comment thread README.md Outdated
Comment thread Dockerfile Outdated
Comment thread Dockerfile Outdated
Comment thread Dockerfile
Comment thread README.md Outdated
Comment thread deploy/compose/docker-compose.yml Outdated
Comment thread Dockerfile Outdated
Comment thread .github/workflows/publish-release.yml Outdated
Comment thread .github/workflows/publish-release.yml Outdated
- Workflows:
  - extract backend and frontend test execution into a shared reusable workflow used by validation, nightly, and release pipelines
  - simplify migration ref handling, sanitize manual preview PR inputs, reduce preview cache writes, and update Flyway to the current image tag
  - remove unnecessary duplicated job definitions so the test path has one source of truth

- Packaging:
  - verify the downloaded UnRAR source tarball with SHA256 before extraction
  - remove the unnecessary forced npm install path from the production Docker build
  - harden container startup by failing clearly when APP_USER collides with an unexpected UID or GID

- Versioning and deploy docs:
  - keep app version metadata embedded in the built image instead of asking operators to set APP_VERSION in deploy examples
  - update runtime release links and support links to the Grimmory repository
  - add the Quadlet install section and finish the remaining review-targeted doc fixes and branding cleanup

- Validation:
  - pass git diff --check
  - pass shellcheck on packaging/docker/entrypoint.sh
  - parse all GitHub workflow YAML successfully

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (7)
README.md (1)

5-5: Make the predecessor name explicit for migration clarity.

Consider naming Booklore directly instead of “original project” so users can find migration context faster.

Suggested wording
-> Grimmory is the successor of the original project.
+> Grimmory is the successor of Booklore.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@README.md` at line 5, Update the README sentence that currently reads
"Grimmory is the successor of the original project." to explicitly name the
predecessor by replacing "original project" with "Booklore" so it reads
something like "Grimmory is the successor to Booklore." This change should be
made where the project intro mentions Grimmory to help users locate migration
and compatibility information faster.
.github/workflows/publish-nightly.yml (1)

1-6: LGTM on the nightly workflow triggers.

The 4 AM UTC schedule is reasonable for nightly builds, and workflow_dispatch allows manual triggering when needed. Consider adding a concurrency block if simultaneous manual dispatches could cause issues:

concurrency:
  group: nightly-build
  cancel-in-progress: false
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/publish-nightly.yml around lines 1 - 6, Add a top-level
concurrency block to the workflow to prevent simultaneous runs: insert a
concurrency key with group set to "nightly-build" and cancel-in-progress set to
false (i.e., use concurrency, group: nightly-build, cancel-in-progress: false)
so manual dispatches don't trigger overlapping runs.
Dockerfile (2)

69-73: Acknowledge Trivy DS-0002: Consider documenting the runtime user model.

Trivy flags that no USER directive is specified. However, the use of su-exec (installed on line 69) indicates the entrypoint handles privilege dropping at runtime—a common pattern when the container needs to match host UID/GID for volume permissions.

Consider adding a comment in the Dockerfile explaining this design choice, which helps future maintainers understand why USER isn't set statically.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfile` around lines 69 - 73, Add a brief explanatory comment in the
Dockerfile near the installation of su-exec and the COPY of entrypoint.sh
indicating that user privileges are dropped at runtime by the entrypoint
(entrypoint.sh) using su-exec to allow matching host UID/GID for mounted
volumes, which is why no static USER directive is set in the image; reference
the su-exec installation and entrypoint.sh to make the runtime user model
explicit for future maintainers.

32-34: JAR discovery could be more robust.

The find | head -n 1 pattern will return an empty string if no JAR is found, which could lead to cp "" /workspace/booklore-api/app.jar failing with a confusing error. While set -eux will catch this, adding an explicit check would improve error messaging.

♻️ Proposed improvement for clearer failure
 RUN set -eux; \
     jar_path="$(find build/libs -maxdepth 1 -name '*.jar' ! -name '*plain.jar' | head -n 1)"; \
+    [ -n "$jar_path" ] || { echo "ERROR: No JAR found in build/libs"; exit 1; }; \
     cp "$jar_path" /workspace/booklore-api/app.jar
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfile` around lines 32 - 34, The RUN shell block that sets jar_path and
copies it is fragile: after jar_path="$(find build/libs -maxdepth 1 -name
'*.jar' ! -name '*plain.jar' | head -n 1)" add an explicit check that jar_path
is non-empty before running cp (e.g., test -n "$jar_path" || { echo "No JAR
found in build/libs" >&2; exit 1; }) so the COPY step fails with a clear error;
update the RUN sequence around set -eux, jar_path and cp to perform this
validation and emit a descriptive error message if no JAR is discovered.
.github/workflows/publish-release.yml (1)

35-41: Branch containment check may have edge cases.

The check git branch -r --contains HEAD | grep -q 'origin/main' verifies the commit is reachable from origin/main. However, git branch -r --contains can be slow on large repositories and may produce unexpected results if origin/main hasn't been fully fetched.

Consider using git merge-base --is-ancestor HEAD origin/main for a more direct ancestry check:

♻️ Alternative ancestry check
       - name: Confirm Release Ref Is On Main
         run: |
           git fetch origin main --tags --force
-          if ! git branch -r --contains HEAD | grep -q 'origin/main'; then
+          if ! git merge-base --is-ancestor HEAD origin/main; then
             echo "Selected ref is not contained by origin/main"
             exit 1
           fi
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/publish-release.yml around lines 35 - 41, Replace the
current slow/fragile containment check in the "Confirm Release Ref Is On Main"
step (which uses `git branch -r --contains HEAD | grep -q 'origin/main'`) with a
direct ancestry test using `git merge-base --is-ancestor HEAD origin/main`;
update the step to ensure `origin/main` is fetched first (e.g., `git fetch
origin main --tags --force`) and then call `git merge-base --is-ancestor HEAD
origin/main` and fail if it returns non-zero so the job exits when HEAD is not
an ancestor of origin/main.
.github/workflows/test-suite.yml (1)

24-25: Consider shallow clone for test jobs.

fetch-depth: 0 fetches full history, which adds overhead for jobs that only run tests. A shallow clone (fetch-depth: 1) would be faster. However, if the test suite or any tooling requires git history, keep the current setting.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/test-suite.yml around lines 24 - 25, The workflow
currently sets fetch-depth: 0 which performs a full git clone; change this to
fetch-depth: 1 in the job checkout step to perform a shallow clone for faster
test runs (unless your tests or tooling require full history), i.e., update the
checkout action configuration that contains fetch-depth and ref (the keys shown
as fetch-depth and ref: ${{ inputs.checkout_ref }}) to use fetch-depth: 1 or
document/guard the full-clone behavior when history is required.
.github/workflows/ci-validate.yml (1)

42-43: QEMU setup is unnecessary for amd64-only builds.

Since the smoke test only builds for linux/amd64 (line 53) and runs on ubuntu-latest (which is amd64), the QEMU setup step adds overhead without benefit. Consider removing it for faster CI runs.

♻️ Remove unnecessary QEMU step
-      - name: Set Up QEMU for Multi-Arch Builds
-        uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3
-
       - name: Set Up Docker Buildx
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/ci-validate.yml around lines 42 - 43, Remove the
unnecessary QEMU setup step named "Set Up QEMU for Multi-Arch Builds" (the use
of docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130) because
the workflow only targets linux/amd64 and runs on ubuntu-latest; delete that
step so the job that builds for linux/amd64 (the smoke test) no longer runs the
QEMU action, reducing CI overhead and runtime.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/migrations-check.yml:
- Line 98: Replace the non-existent Docker image tag "flyway/flyway:12.1.1" with
a valid patch release (e.g., "flyway/flyway:12.1.0" or
"flyway/flyway:12.1.0-alpine") wherever it appears in the workflow; search for
the exact string "flyway/flyway:12.1.1" in the workflow steps and update both
occurrences (the two lines referencing the Flyway image) to the chosen valid tag
so the CI uses an existing image.

In `@docs/OIDC-Setup-With-PocketID.md`:
- Line 29: Rewrite the run-on sentence into two concise sentences and fix
capitalization/punctuation: change “PassKey” to “passkey” (or “Passkey”), add a
comma after “configured,” and replace “dialogue” with “dialog” (or “settings
dialog”). For example, split into one sentence about logging in and configuring
a passkey and a second sentence explaining creation of an OIDC client and that
it provides keys for the Grimmory settings dialog; update the existing sentence
accordingly.
- Line 56: The final test-step is a run-on sentence; split it into clear
sequential steps: 1) "Click Save Settings." 2) "Click the Enabled radio button
to activate PocketID." 3) "Log out and log back in to confirm the integration is
working." End with a short troubleshooting sentence pointing to the existing
GitHub issue link for reporting problems, preserving the current URL.

---

Nitpick comments:
In @.github/workflows/ci-validate.yml:
- Around line 42-43: Remove the unnecessary QEMU setup step named "Set Up QEMU
for Multi-Arch Builds" (the use of
docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130) because the
workflow only targets linux/amd64 and runs on ubuntu-latest; delete that step so
the job that builds for linux/amd64 (the smoke test) no longer runs the QEMU
action, reducing CI overhead and runtime.

In @.github/workflows/publish-nightly.yml:
- Around line 1-6: Add a top-level concurrency block to the workflow to prevent
simultaneous runs: insert a concurrency key with group set to "nightly-build"
and cancel-in-progress set to false (i.e., use concurrency, group:
nightly-build, cancel-in-progress: false) so manual dispatches don't trigger
overlapping runs.

In @.github/workflows/publish-release.yml:
- Around line 35-41: Replace the current slow/fragile containment check in the
"Confirm Release Ref Is On Main" step (which uses `git branch -r --contains HEAD
| grep -q 'origin/main'`) with a direct ancestry test using `git merge-base
--is-ancestor HEAD origin/main`; update the step to ensure `origin/main` is
fetched first (e.g., `git fetch origin main --tags --force`) and then call `git
merge-base --is-ancestor HEAD origin/main` and fail if it returns non-zero so
the job exits when HEAD is not an ancestor of origin/main.

In @.github/workflows/test-suite.yml:
- Around line 24-25: The workflow currently sets fetch-depth: 0 which performs a
full git clone; change this to fetch-depth: 1 in the job checkout step to
perform a shallow clone for faster test runs (unless your tests or tooling
require full history), i.e., update the checkout action configuration that
contains fetch-depth and ref (the keys shown as fetch-depth and ref: ${{
inputs.checkout_ref }}) to use fetch-depth: 1 or document/guard the full-clone
behavior when history is required.

In `@Dockerfile`:
- Around line 69-73: Add a brief explanatory comment in the Dockerfile near the
installation of su-exec and the COPY of entrypoint.sh indicating that user
privileges are dropped at runtime by the entrypoint (entrypoint.sh) using
su-exec to allow matching host UID/GID for mounted volumes, which is why no
static USER directive is set in the image; reference the su-exec installation
and entrypoint.sh to make the runtime user model explicit for future
maintainers.
- Around line 32-34: The RUN shell block that sets jar_path and copies it is
fragile: after jar_path="$(find build/libs -maxdepth 1 -name '*.jar' ! -name
'*plain.jar' | head -n 1)" add an explicit check that jar_path is non-empty
before running cp (e.g., test -n "$jar_path" || { echo "No JAR found in
build/libs" >&2; exit 1; }) so the COPY step fails with a clear error; update
the RUN sequence around set -eux, jar_path and cp to perform this validation and
emit a descriptive error message if no JAR is discovered.

In `@README.md`:
- Line 5: Update the README sentence that currently reads "Grimmory is the
successor of the original project." to explicitly name the predecessor by
replacing "original project" with "Booklore" so it reads something like
"Grimmory is the successor to Booklore." This change should be made where the
project intro mentions Grimmory to help users locate migration and compatibility
information faster.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e3d0a984-e186-4080-840f-1057b114194d

📥 Commits

Reviewing files that changed from the base of the PR and between 0baa9a1 and ca152c1.

📒 Files selected for processing (17)
  • .github/workflows/ci-validate.yml
  • .github/workflows/migrations-check.yml
  • .github/workflows/preview-image.yml
  • .github/workflows/publish-nightly.yml
  • .github/workflows/publish-release.yml
  • .github/workflows/test-suite.yml
  • CONTRIBUTING.md
  • Dockerfile
  • README.md
  • booklore-api/src/main/java/org/booklore/service/VersionService.java
  • booklore-ui/src/app/shared/components/github-support-dialog/github-support-dialog.html
  • booklore-ui/src/app/shared/layout/component/layout-menu/app.menu.component.ts
  • deploy/compose/docker-compose.yml
  • deploy/podman/quadlet/grimmory.container
  • docs/OIDC-Setup-With-PocketID.md
  • docs/forward-auth-with-proxy.md
  • packaging/docker/entrypoint.sh
✅ Files skipped from review due to trivial changes (6)
  • booklore-api/src/main/java/org/booklore/service/VersionService.java
  • docs/forward-auth-with-proxy.md
  • booklore-ui/src/app/shared/components/github-support-dialog/github-support-dialog.html
  • deploy/compose/docker-compose.yml
  • .github/workflows/preview-image.yml
  • deploy/podman/quadlet/grimmory.container
🚧 Files skipped from review as they are similar to previous changes (2)
  • packaging/docker/entrypoint.sh
  • CONTRIBUTING.md

Comment thread .github/workflows/migrations-check.yml Outdated
Comment thread docs/OIDC-Setup-With-PocketID.md
Comment thread docs/OIDC-Setup-With-PocketID.md

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/migrations-check.yml:
- Around line 44-49: The fallback that rewrites an all-zero base_ref to
head_ref^ (the if block handling base_ref and head_ref) can miss migrations on
multi-commit pushes and produce an empty diff for root commits; instead update
the script to detect an all-zero base_ref and abort with a non-zero exit (or
require the caller to supply a real comparison base before proceeding), removing
the implicit base_ref="$(git rev-parse "${head_ref}^")" fallback; apply the same
change to the other identical fallback logic that collapses zero base refs so
migrations checks never silently skip files.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 78b39465-0f03-4a6c-a66b-8738100f328d

📥 Commits

Reviewing files that changed from the base of the PR and between ca152c1 and 2529dd5.

📒 Files selected for processing (1)
  • .github/workflows/migrations-check.yml

Comment thread .github/workflows/migrations-check.yml Outdated
Comment thread docs/forward-auth-with-proxy.md
Comment thread README.md Outdated
Comment thread README.md Outdated
Comment thread README.md Outdated
imajes added 2 commits March 19, 2026 15:53
- Release automation:
  - replace the manual stable bump flow and Release Drafter with semantic-release on `main`
  - split stable delivery into a semantic-release workflow that computes version, changelog, tag, and draft GitHub release plus a tag-driven workflow that publishes container images
  - add a maintainer-run dry-run workflow to preview the next stable version and release notes before publishing

- Release tooling:
  - add a dedicated `tools/release` package with semantic-release configuration and lockfile
  - encode Grimmory's release policy so `feat` triggers minor releases, `fix`/`perf`/`refactor` trigger patch releases, and `docs`/`ci`/`build`/`chore`/`test`/`style` are changelog-only
  - maintain a committed `CHANGELOG.md` and draft GitHub releases from the same release notes source

- Contributor workflow:
  - enforce conventional PR titles for PRs targeting `develop` and `main`
  - document that feature work is squash-merged into `develop` and that stable releases are computed from the preserved conventional commit history promoted to `main`
  - update README, contributing guidance, and the PR template to match the new release process

- Bootstrap:
  - add the semantic-release migration plan under `docs/plans/semantic-release-migration.md`
  - seed the local release baseline with `v2.2.1` on commit `384512534fe5a2f42d8482a0646337e28ef54e52`
  - configure the stable image publish workflow to ignore the bootstrap tag so the first semantic-release-managed release can be `v2.2.2`

- Validation:
  - pass `git diff --check`
  - parse all workflow YAML successfully
  - verify the semantic-release config loads correctly
  - verify the local bootstrap tag is present as `v2.2.1`

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/release-main.yml:
- Around line 1-8: Add a top-level concurrency stanza to the workflow that
serializes runs for this release workflow so pushes to main don't run in
parallel; under the existing "name: Release - Semantic Stable" / "on: push:
branches: - main" block insert a "concurrency" block (before "jobs:") with a
stable group identifier such as group: "release-main" or group: "release-${{
github.ref }}" and set cancel-in-progress: false so new runs queue instead of
cancelling in-progress runs; this ensures the workflow named "Release - Semantic
Stable" serializes release executions and avoids semantic-release tag/changelog
races.

In @.github/workflows/release-preview.yml:
- Around line 27-35: The containment check currently uses a substring grep ('git
branch -r --contains HEAD | grep -q 'origin/main'') which can match branches
like origin/main-*; change it to an exact ancestry check by replacing that line
with either a strict exact-match grep (e.g., use grep -qx 'origin/main') or,
preferably, use Git's ancestry check (git merge-base --is-ancestor HEAD
origin/main) and fail if it returns non-zero; update the run block that contains
the git fetch/git branch/g?checkout commands and the grep line to use one of
these exact checks so only origin/main (true ancestor) passes.

In `@README.md`:
- Line 89: The sentence "Stable images are published from semantic-release tags
on `main` as `vX.Y.Z` plus `latest`. Nightly images are published as `nightly`
from `develop`." repeats "published" and should be tightened for
readability—replace that line (the sentence starting with "Stable images") with
a single clearer sentence such as: "Stable images are published from
semantic-release tags on `main` as `vX.Y.Z` and `latest`, while nightly images
are published from `develop` as `nightly`." Ensure the revised sentence
preserves the same tag names and branches.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: d42eca99-6501-4294-9e64-2d2f0f573589

📥 Commits

Reviewing files that changed from the base of the PR and between 2529dd5 and 99a5189.

⛔ Files ignored due to path filters (1)
  • tools/release/package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (14)
  • .github/dependabot.yml
  • .github/pull_request_template.md
  • .github/release-drafter.yml
  • .github/workflows/ci-validate.yml
  • .github/workflows/publish-release.yml
  • .github/workflows/release-main.yml
  • .github/workflows/release-preview.yml
  • .github/workflows/semantic-pr-title.yml
  • CHANGELOG.md
  • CONTRIBUTING.md
  • README.md
  • docs/plans/semantic-release-migration.md
  • tools/release/package.json
  • tools/release/release.config.cjs
💤 Files with no reviewable changes (1)
  • .github/release-drafter.yml
✅ Files skipped from review due to trivial changes (7)
  • CHANGELOG.md
  • .github/dependabot.yml
  • .github/pull_request_template.md
  • tools/release/package.json
  • tools/release/release.config.cjs
  • .github/workflows/publish-release.yml
  • CONTRIBUTING.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • .github/workflows/ci-validate.yml

Comment thread .github/workflows/release-main.yml
Comment thread .github/workflows/release-preview.yml Outdated
Comment thread README.md Outdated
imajes and others added 4 commits March 19, 2026 18:33
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
…gin/head

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
- Migration checks:
  - remove the implicit fallback that rewrote an all-zero base ref to `head^`
  - fail fast when callers provide the all-zero sentinel instead of a real comparison base so multi-commit pushes and root-history cases do not silently skip migration files

- Validation:
  - pass `git diff --check`
  - parse `.github/workflows/migrations-check.yml` successfully

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
.github/workflows/migrations-check.yml (1)

83-99: Consider cleaning MariaDB state between base and head migration runs.

After applying base migrations, the workflow checks out the head ref and applies head migrations on top. This correctly validates that head migrations apply cleanly over base. However, if a head migration modifies or removes an object created by a base migration in an incompatible way, this won't catch that until production. The current approach is reasonable for incremental migration validation but won't detect full schema drift from scratch.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/migrations-check.yml around lines 83 - 99, The workflow
applies base migrations then checks out head and runs head migrations without
resetting the MariaDB state; add an explicit DB reset between the "Apply
Migrations from Base Branch" step and the step that checks out/applies head
migrations so head runs start from a clean slate. Implement the reset by
invoking a Flyway clean (or issuing a DROP/CREATE for the test database) against
the same JDBC URL used in the "Apply Migrations from Base Branch" docker run,
ensuring the Flyway container/image (flyway/flyway:12.1.0) or a mysql client is
used with the same -url, -user and -password to remove the base-state before
running head migrations. Ensure the new reset step references the same migration
paths and credentials so the subsequent head migration run validates applying
migrations onto a fresh DB.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In @.github/workflows/migrations-check.yml:
- Around line 83-99: The workflow applies base migrations then checks out head
and runs head migrations without resetting the MariaDB state; add an explicit DB
reset between the "Apply Migrations from Base Branch" step and the step that
checks out/applies head migrations so head runs start from a clean slate.
Implement the reset by invoking a Flyway clean (or issuing a DROP/CREATE for the
test database) against the same JDBC URL used in the "Apply Migrations from Base
Branch" docker run, ensuring the Flyway container/image (flyway/flyway:12.1.0)
or a mysql client is used with the same -url, -user and -password to remove the
base-state before running head migrations. Ensure the new reset step references
the same migration paths and credentials so the subsequent head migration run
validates applying migrations onto a fresh DB.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: db7498a8-4ca3-4126-b646-8f0bf9a895f9

📥 Commits

Reviewing files that changed from the base of the PR and between 99a5189 and 19b3fc2.

📒 Files selected for processing (4)
  • .github/workflows/migrations-check.yml
  • .github/workflows/release-main.yml
  • .github/workflows/release-preview.yml
  • README.md
✅ Files skipped from review due to trivial changes (1)
  • .github/workflows/release-preview.yml
🚧 Files skipped from review as they are similar to previous changes (1)
  • README.md

- Container packaging:
  - replace the custom UnRAR source build stage with the published `linuxserver/unrar` image layer
  - copy the provided `/usr/bin/unrar-alpine` binary into the final runtime image as `/usr/local/bin/unrar`
  - remove the checksum, tarball, and local compile path from the Dockerfile

- Validation:
  - pass `git diff --check`
@imajes imajes merged commit 1bc45da into main Mar 19, 2026
2 checks passed
@imajes imajes deleted the feat/improve-ci-process branch March 19, 2026 23:46
github-actions Bot added a commit that referenced this pull request Mar 19, 2026
## [2.2.2](v2.2.1...v2.2.2) (2026-03-19)

### Bug Fixes

* **ci:** forward checks permission to reusable test jobs ([e3b3e7c](e3b3e7c))

### Chores

* **ci:** rebrand and streamline the release pipeline ([#66](#66)) ([1bc45da](1bc45da))
* Update README to use new links, and clean up formatting ([6b0c4aa](6b0c4aa))
dinosmm pushed a commit to dinosmm/booklore that referenced this pull request Mar 21, 2026
## [2.2.2](grimmory-tools/grimmory@v2.2.1...v2.2.2) (2026-03-19)

### Bug Fixes

* **ci:** forward checks permission to reusable test jobs ([e3b3e7c](grimmory-tools/grimmory@e3b3e7c))

### Chores

* **ci:** rebrand and streamline the release pipeline ([#66](grimmory-tools/grimmory#66)) ([1bc45da](grimmory-tools/grimmory@1bc45da))
* Update README to use new links, and clean up formatting ([6b0c4aa](grimmory-tools/grimmory@6b0c4aa))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants