Skip to content

feat(packaging): Add local packaging workflow with caching. - #25

Merged
jackluo923 merged 16 commits into
mainfrom
feat/add-cached-local-build
Jul 20, 2026
Merged

jackluo923 merged 16 commits into
mainfrom
feat/add-cached-local-build

Conversation

@jackluo923

@jackluo923 jackluo923 commented Jul 17, 2026 •

Copy link
Copy Markdown
Member

Summary

Adds a user-facing local packaging entry point (tools/build-packages/build-packages.sh) that resolves the hash-tagged build-env image and runs the same container-side artifact build (internal/container/build-artifacts.sh) used by CI. Brings persistent, shared build caching to local builds, cutting incremental local builds from ~15 minutes down to 15–30 seconds.

What's included

  • build-packages.sh — host-side entry point: resolves output dir, initializes submodules, resolves the build-env image (build-dependency-image.sh), prepares the build cache, and runs the artifact build inside the image.
  • internal/build-cache/ — host- and container-side cache configuration (maven/, ccache/, fetchcontent/<hash>/) keyed by the build-env image hash, so cached CMake state stays compatible with the image inputs.
  • README updates describing local usage, the build-env image, cache layout, and prerequisites.

Known follow-up (not in this PR)

  • Proxy / host network env support: docker run only forwards BUILD_CACHE_KEY, so builds behind a corporate proxy (or other environments needing host network/proxy config inherited by the container) are not yet supported. This will be addressed in a separate follow-up PR.

Summary by CodeRabbit

  • New Features

    • Added a local packaging command for building .deb, .rpm, and .tar.gz packages.
    • Added support for custom output directories and package versions.
    • Added reusable build caching to improve subsequent build times.
    • Added macOS-compatible SHA-256 tool detection.
  • Documentation

    • Updated packaging instructions with local usage, prerequisites, caching, and output details.
  • Improvements

    • Added configurable dependency and build-cache locations.
    • Improved package-build artifact handling and ownership consistency.

@jackluo923
jackluo923 requested review from a team and 20001020ycx as code owners July 17, 2026 00:02
@coderabbitai

coderabbitai Bot commented Jul 17, 2026 •

Copy link
Copy Markdown

Review Change Stack

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

The PR adds a local package-build entry point, shared host/container build caches, configurable CMake and Maven cache paths, cache-enabled dependency images, and documentation for local packaging workflows.

Changes

Packaging and build-cache flow

Layer / File(s) Summary
Shared cache foundation
tools/build-packages/internal/build-cache/*, tools/build-packages/dependency-image/*, taskfiles/velox-connector/main.yaml, .dockerignore, .gitignore
Host and container cache helpers, ccache support, configurable dependency paths, FetchContent wiring, and cache-directory exclusions are added.
Local packaging entry point
tools/build-packages/build-packages.sh, tools/build-packages/build-dependency-image.sh, tools/build-packages/dependency-image/utils.sh, taskfile.yaml, README.md, tools/build-packages/README.md
Local packaging options, Docker execution, build-environment resolution, artifact staging, hash-tool fallback, task integration, and local-build documentation are added.
Container build cache integration
tools/build-packages/internal/container/build-artifacts.sh
Container builds conditionally configure caches, use a caller-controlled Maven repository, stage outputs under the project build directory, and update local-build help text.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Developer
  participant BuildScript as build-packages.sh
  participant Docker
  participant Builder as build-artifacts.sh
  participant Output as packages directory
  Developer->>BuildScript: Run package command with options
  BuildScript->>Docker: Mount repository, cache, and staging paths
  Docker->>Builder: Run container-side packaging
  Builder-->>Docker: Produce staged artifacts
  Docker-->>BuildScript: Return build result
  BuildScript->>Output: Copy generated packages
Loading

Possibly related PRs

Suggested reviewers: 20001020ycx

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: a local packaging workflow with caching support.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/add-cached-local-build

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

❤️ Share

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tools/build-packages/build-packages.sh`:
- Line 123: Update the artifact copy command to use the POSIX-compatible -f
option instead of GNU-specific --remove-destination, preserving the existing
source and destination behavior in the build script.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 9e855e29-f090-4e47-839c-bf6294242c7e

📥 Commits

Reviewing files that changed from the base of the PR and between 0ffe312 and 3e01ce0.

📒 Files selected for processing (11)
  • .dockerignore
  • .gitignore
  • README.md
  • taskfiles/velox-connector/main.yaml
  • tools/build-packages/README.md
  • tools/build-packages/build-packages.sh
  • tools/build-packages/dependency-image/Dockerfile
  • tools/build-packages/internal/build-cache/README.md
  • tools/build-packages/internal/build-cache/container.sh
  • tools/build-packages/internal/build-cache/host.sh
  • tools/build-packages/internal/container/build-artifacts.sh

Comment thread tools/build-packages/build-packages.sh Outdated
jackluo923 and others added 5 commits July 16, 2026 17:33
--remove-destination is a GNU cp extension absent on BSD/macOS cp; -f is
POSIX-specified and behaves equivalently for copying staged artifacts into
the user-owned output directory.
The top-level README replaced the CI-build reference with a local-build
one; both paths exist, so restore the CI mention and add the local one.
Tighten prose (intro, Container API, Lifecycle) while keeping every
contract and integration note. Use one prose paragraph per line instead
of manual hard wraps.
…d build tree

Local builds previously ran the container build as root and wrote the project
build tree to the disposable container layer, so every invocation recompiled
the C++ connector from scratch and left root-owned files in the repo.

Changes:
* build-packages.sh: run `docker run` as the host uid/gid and set
  CLP_PLUGIN_BUILD_DIR to a path under the persistent .cache/build/<hash>
  cache, so the CMake build tree survives across runs (incremental rebuilds).
* dependency-image/Dockerfile: pin CLP_PLUGIN_DEPS_CPP_DIR to the image's
  installed deps so the deps dir is not derived from the overridden build dir.
* taskfiles/velox-connector/main.yaml: make G_DEPS_CPP_DIR env-overridable
  via CLP_PLUGIN_DEPS_CPP_DIR (mirrors the existing FETCHCONTENT_BASE_DIR
  pattern).
* internal/build-cache/{host,container}.sh: create the build/<key> cache
  subdir; document it in internal/build-cache/README.md.
* internal/container/build-artifacts.sh: place packaging staging under
  project_build_dir so it lives in the cache for local builds (CI still
  resolves to the image's /opt).

Result: a no-op rebuild completes in under 30 seconds (C++ compile is a
cache hit) and produces host-owned .deb/.rpm/.tar.gz with no root-owned
files in the repo.
Reverts the behavior-neutral formatting changes that came over with the
host-user/cached-build port so the diff is purely functional:
* .github/workflows/build-packages.yaml: restore the two-line ::error:: echo.
* taskfiles/velox-connector/main.yaml: restore the quoted `desc:`.
* tools/build-packages/internal/container/build-artifacts.sh: restore the
  MAVEN_OPTS/mvnw line wrapping and the submodule-init comment wording.
* tools/build-packages/build-packages.sh: restore the defensive
  ${build_args[@]+"${build_args[@]}"} quoting.

Functional changes (host-user run, CLP_PLUGIN_BUILD_DIR env, CLP_PLUGIN_DEPS_CPP_DIR
pin, cache build/<key> helpers + README, build_root relocation) are unchanged.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Caution

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

⚠️ Outside diff range comments (1)
tools/build-packages/build-packages.sh (1)

78-82: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Validate that the extracted image hash is non-empty.

This check only verifies that :env- exists. A malformed value such as repo:env- passes with an empty image_hash, causing the cache to be prepared without a real image key and potentially sharing unscoped build/FetchContent state. Match and extract a non-empty env-<hash> tag instead.

Proposed fix
-image_hash="${image##*:env-}"
-if [[ "${image_hash}" == "${image}" ]]; then
+if [[ "${image}" =~ :env-([[:alnum:]][[:alnum:]._-]*)$ ]]; then
+    image_hash="${BASH_REMATCH[1]}"
+else
     echo >&2 "ERROR: build-env image lacks an env-<hash> tag: ${image}"
     exit 1
 fi
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tools/build-packages/build-packages.sh` around lines 78 - 82, Update the
image tag validation around image_hash to require a non-empty hash after the
env- prefix, rejecting malformed values such as repo:env-. Match and extract
only a valid env-<hash> tag before proceeding with cache preparation, while
preserving the existing error-and-exit behavior for invalid image values.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@tools/build-packages/build-packages.sh`:
- Around line 78-82: Update the image tag validation around image_hash to
require a non-empty hash after the env- prefix, rejecting malformed values such
as repo:env-. Match and extract only a valid env-<hash> tag before proceeding
with cache preparation, while preserving the existing error-and-exit behavior
for invalid image values.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 6b5da872-6533-4ff2-9e6e-46b59333854f

📥 Commits

Reviewing files that changed from the base of the PR and between 681a345 and d79bb83.

📒 Files selected for processing (3)
  • taskfiles/velox-connector/main.yaml
  • tools/build-packages/build-packages.sh
  • tools/build-packages/internal/container/build-artifacts.sh

Jack added 3 commits July 16, 2026 23:39
Fold the inline bash setup (cache wiring, HOME/TASK_TEMP_DIR scratch dirs,
umask) that build-packages.sh ran before build-artifacts.sh into a
BUILD_CACHE_DIR-guarded block at the top of build-artifacts.sh itself.

Local builds set BUILD_CACHE_DIR (via build-packages.sh's --env flags), so
they run that setup. CI invokes build-artifacts.sh directly without it, so
the block is skipped and CI inherits the image's /opt layout unchanged.

Removes the inline 'bash -c' block from build-packages.sh in favor of a
direct 'bash /repo/.../build-artifacts.sh' invocation. No new file needed.
…uild-artifacts.sh

Comment-only: name the BUILD_CACHE_DIR/HOME/TASK_TEMP_DIR env contract in
build-artifacts.sh and reword the docker-run comment in build-packages.sh so
the --env flags aren't orphaned from the setup they drive.
derive_build_env_hash called sha256sum directly, which stock macOS
doesn't ship (it provides shasum -a 256). Resolve a sha256_cmd that
falls back to shasum -a 256 and use it in both stages of the hash
pipeline. Both tools emit the same <hash>  <file> format, so the
resulting tag is identical on either host.

Also update the Requires: header in build-packages.sh and
build-dependency-image.sh and the README prerequisites to list both.

@20001020ycx 20001020ycx left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

As discussed offline, the high level goal is clear. This PR will promote local package build with ccache. However, for the sake of UX, let's add a task as the interface exposed rather a plain bash script

Comment thread tools/build-packages/README.md
Comment thread tools/build-packages/internal/build-cache/README.md Outdated
Jack added 2 commits July 17, 2026 02:04
Add a 'package' task to the root taskfile as a thin wrapper over
tools/build-packages/build-packages.sh, so local package builds use the
same 'task ...' ergonomics as 'task clean' / 'task velox-connector:build'.
Args forward via CLI_ARGS (use '--' to pass flags). Document it as the
recommended local entry point in tools/build-packages/README.md.
20001020ycx
20001020ycx previously approved these changes Jul 17, 2026

@20001020ycx 20001020ycx left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Once the changes discussed offline are addressed, e.g. README and taskfile, I am okay with the merge

Comment thread taskfiles/velox-connector/main.yaml Outdated
Per reviewer request. Drop the internal build-cache README and the link to
it from tools/build-packages/README.md.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@taskfile.yaml`:
- Around line 31-32: Update the command under cmds to quote the rendered
build-packages.sh path, while keeping {{.CLI_ARGS}} outside the quotes so
arguments continue to split normally.
- Around line 28-30: Update the precondition command to validate Buildx
specifically by invoking docker buildx version. In the package-build task, quote
the ROOT_DIR-based build-packages.sh path while preserving CLI argument
forwarding so workspace paths containing spaces work correctly.

In `@tools/build-packages/README.md`:
- Around line 36-37: Update the cache layout documentation near the build-state
description to include .cache/build/<hash>/ for persisted CMake/build state, and
explicitly distinguish it from the repository’s separate build/ directory.
- Around line 38-39: Update the ownership guidance near the container execution
description to state that the local wrapper runs with the invoking host UID/GID,
so it does not create root-owned files; explain that root-owned files in
.cache/, build/, or presto-connector/target/ may instead remain from earlier
privileged or CI builds, while packages/ remains owned by the invoking user.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 3cbb292c-d2ac-4954-966e-4cb0efa26005

📥 Commits

Reviewing files that changed from the base of the PR and between ad63380 and 29c97ce.

📒 Files selected for processing (2)
  • taskfile.yaml
  • tools/build-packages/README.md

Comment thread taskfile.yaml
Comment thread taskfile.yaml Outdated
Comment thread tools/build-packages/README.md Outdated
Comment thread tools/build-packages/README.md Outdated
…age'

Precondition now runs 'docker buildx version' instead of 'command -v docker'
so it actually verifies buildx, not just docker. Quote the ROOT_DIR-based
build-packages.sh path so workspace paths containing spaces invoke the script
correctly; CLI_ARGS stays unquoted to preserve argument forwarding.
@jackluo923
jackluo923 requested a review from 20001020ycx July 20, 2026 13:59
…epo build/

Add build/<hash>/ to the cache layout list in the packaging README and
clarify that it is the container's build output dir, distinct from the
repo's top-level build/ used by non-container local dev builds.
The local wrapper runs the build container with the invoking host UID/GID
(--user flag) and refuses sudo, so it does not create root-owned files.
Reword the ownership note to reflect that: any root-owned files in .cache/,
build/, or presto-connector/target/ are leftovers from earlier privileged
or CI builds, while packages/ stays owned by the invoking user.
…d dirs

Switch G_BUILD_DIR, G_DEPS_CPP_DIR, and G_FETCHCONTENT_BASE_DIR from
{{env "VAR"}} to {{.VAR | default ...}}. In Task v3 both forms read the
shell environment ({{.VAR}} falls back to env as its last lookup step), and
since no Taskfile scope defines these names they behave identically.
Adopted for consistency with the Taskfile docs idiom.

Validated via task --dry: G_BUILD_DIR and G_DEPS_CPP_DIR fallback and
env-override both resolve correctly in the real Taskfiles, and the
G_FETCHCONTENT_BASE_DIR override resolves in an isolated probe using the
same pattern.
@jackluo923 jackluo923 changed the title feat(packaging): Add cached local package builds feat(packaging): Add cached local build packaging workflow. Jul 20, 2026
@jackluo923 jackluo923 changed the title feat(packaging): Add cached local build packaging workflow. feat(packaging): Add local build packaging workflow with caching. Jul 20, 2026
@jackluo923 jackluo923 changed the title feat(packaging): Add local build packaging workflow with caching. feat(packaging): Add local packaging workflow with caching. Jul 20, 2026
@jackluo923
jackluo923 merged commit 4faf29f into main Jul 20, 2026
18 checks passed
@jackluo923
jackluo923 deleted the feat/add-cached-local-build branch July 20, 2026 16:10
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.

2 participants