Skip to content

Guard the vendored linter include so tarball builds don't break - #80

Merged
jnasbyupgrade merged 2 commits into
Postgres-Extensions:masterfrom
jnasbyupgrade:guard-vendored-lint-include-tarball
Aug 4, 2026
Merged

Guard the vendored linter include so tarball builds don't break#80
jnasbyupgrade merged 2 commits into
Postgres-Extensions:masterfrom
jnasbyupgrade:guard-vendored-lint-include-tarball

Conversation

@jnasbyupgrade

Copy link
Copy Markdown
Contributor

The top-level Makefile's include lint.mk is unconditional, so Make tries to satisfy every include this file pulls in before running any target at all, for any target. lint.mk auto-initializes the .vendor/linter submodule via a rule for .vendor/linter/lint.mk, then includes it. git archive (what make dist uses, and what PGXN ships to real consumers) never includes submodule content and strips .git entirely, so in a tarball extracted from a release archive, git submodule update --init fails immediately (not a git repository), aborting the include and the entire Makefile parse -- breaking make, make install, everything, not just make lint.

Wrap the auto-init rule and the vendored include in ifneq ($(wildcard .git),), so a tarball build (no .git at all) never even asks Make to look for .vendor/linter/lint.mk, and the auto-remake rule never fires. $(wildcard .git) matches both a real .git directory (plain clone) and the .git file pointer used inside a git worktree, so normal checkouts are unaffected and make lint keeps working exactly as before. make lint becoming unavailable in a tarball build is expected -- PGXN consumers don't need the linter.

Verification

  • Confirmed the bug by hand: extracted the real cat_tools-0.3.0.zip release archive (git archive of tag 0.3.0) into a directory with no .git at all, and make failed immediately with the submodule init error, before doing anything else.
  • With this fix: git archive --prefix=cat_tools-test/ -o /tmp/cat_tools-test.zip HEAD, extracted into a clean directory outside any git repo -- make and make install both succeed with no .git present.
  • In a normal checkout (this worktree), make lint still works exactly as before.
  • make verify-results passes, confirming the normal test suite is unaffected.

No HISTORY.asc entry -- this is purely internal build tooling, not a user-facing behavior change.

The top-level Makefile's `include lint.mk` is unconditional, so Make tries to
satisfy every include this file pulls in before running any target at all,
for any target. lint.mk auto-initializes the .vendor/linter submodule via a
rule for .vendor/linter/lint.mk, then includes it. git archive (what `make
dist` uses, and what PGXN ships to real consumers) never includes submodule
content and strips .git entirely, so in a tarball extracted from a release
archive, `git submodule update --init` fails immediately (not a git
repository), aborting the include and the entire Makefile parse -- breaking
`make`, `make install`, everything, not just `make lint`.

Wrap the auto-init rule and the vendored include in
`ifneq ($(wildcard .git),)`, so a tarball build (no .git at all) never even
asks Make to look for .vendor/linter/lint.mk, and the auto-remake rule never
fires. $(wildcard .git) matches both a real .git directory (plain clone) and
the .git file pointer used inside a git worktree, so normal checkouts are
unaffected and `make lint` keeps working exactly as before. `make lint`
becoming unavailable in a tarball build is expected -- PGXN consumers don't
need the linter.
@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 93fc9800-607a-4dfc-bcbc-a1b61394b210

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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.

@github-actions

github-actions Bot commented Aug 4, 2026

Copy link
Copy Markdown

Claude finished @jnasbyupgrade's task in 1m 49s —— View job


Review: Guard the vendored linter include so tarball builds don't break

  • Gather context (PR body, diff, CLAUDE.md guidance)
  • Read lint.mk changes in full
  • Verify the ifneq ($(wildcard .git),) guard logic (worktree .git file vs .git dir, submodule init, etc.)
  • Check for edge cases (e.g. .git present but submodule not initialized, CI still running make lint)
  • Post review feedback

Verdict: LGTM. The fix is correct, minimal, and well-targeted.

What I checked

  • Confirmed via git show c7a9b68:lint.mk that the prior version unconditionally defined the .vendor/linter/lint.mk: rule and included it — exactly the bug described: Makefile:107 does an unconditional include lint.mk, so Make must satisfy lint.mk's own nested include before running any target, including plain make/make install.
  • $(wildcard .git) is the right primitive here: it's non-empty for both a real .git directory (plain clone) and the .git file pointer used in a worktree, and empty only when neither exists — which is exactly the git archive/tarball case (.git is stripped entirely). The ifneq (...,) wrapping both the auto-init rule and the include means Make never even looks for .vendor/linter/lint.mk in that case, so the parse can't abort.
  • Checked Makefile:96-107 — the include lint.mk is standalone; no other target in the top-level Makefile depends on anything defined inside lint.mk/.vendor/linter/lint.mk, so wrapping the whole file in the guard doesn't risk breaking unrelated targets when .git is absent.
  • Checked .github/workflows/ci.yml (the lint job at line 389, run: make lint) — CI checks out via actions/checkout which always leaves a real .git, so the guard is a no-op there; make lint keeps working exactly as before, matching the PR's stated verification.
  • The intentional non-goal — make lint silently becoming unavailable when .git is absent (tarball builds) — is correct and consistent with "PGXN consumers don't need the linter."
  • No HISTORY.asc entry needed: checked existing entries and confirmed that file tracks user-facing extension/SQL changes only, not build tooling, so omitting an entry here matches convention.
  • The comment is a bit long (10 lines) for a 6-line functional change, but per CLAUDE.md's guidance to comment fixes "where it isn't self-evident," the underlying interaction is genuinely non-obvious (an unconditional top-level include forces Make to satisfy a nested include's own remake rule before running any target at all) — each sentence in the comment carries distinct, load-bearing information, so I don't think it needs trimming.

No functional, security, or style issues found.

lint.mk's vendored include is now guarded on $(wildcard .git) so a source
tarball with no .git can still build. If that guard ever went false in CI
(checkout somehow left no .git), `lint` wouldn't exist as a make target, and
`make lint` fails loudly rather than silently skipping -- but only if CI
actually invokes that exact command with nothing swallowing its exit code.
Document that constraint at the call site so it isn't accidentally routed
through a wrapper or a different entry point later.
@github-actions

github-actions Bot commented Aug 4, 2026

Copy link
Copy Markdown

Claude finished @jnasbyupgrade's task in 1m 59s —— View job


Code Review: Guard the vendored linter include so tarball builds don't break

  • Gather context (PR body, diff, CLAUDE.md guidance)
  • Review lint.mk and .github/workflows/ci.yml changes (both commits, including the new ci.yml documentation commit added since the last automated review)
  • Check guard logic edge cases
  • Post final review feedback

Verdict: LGTM.

This review covers both commits, including 9382144 (the ci.yml comment) added after the previous automated review of e1a0c7a.

lint.mk (unchanged since last review)

  • ifneq ($(wildcard .git),) correctly wraps both the .vendor/linter/lint.mk: auto-init rule and the include. Since the top-level Makefile:107's include lint.mk is unconditional, Make must satisfy any nested include before running any target — wrapping the whole block means a tarball checkout (no .git) never asks Make to look for .vendor/linter/lint.mk, so the auto-remake rule never fires and the parse can't abort.
  • $(wildcard .git) is the right primitive: non-empty for a real .git directory (plain clone) and the .git file pointer used in a worktree, empty only when neither exists — exactly the git archive/tarball case, since .git is stripped entirely from archives.
  • Recipe line uses a real tab (verified with cat -A), so the rule is syntactically valid Make.
  • No other Makefile targets depend on anything defined inside lint.mk/.vendor/linter/lint.mk, so gating the whole file behind the guard doesn't risk breaking unrelated targets when .git is absent.

.github/workflows/ci.yml (new since last review)

  • The added comment on the lint job's run: make lint step documents a real, distinct constraint: it's not re-explaining the .git wildcard mechanism (that's already covered in lint.mk's own comment) — it's warning that this exact call site must not be wrapped by a script or routed through a different entry point, because if the guard ever went false in CI, a missing lint target should fail loudly (No rule to make target 'lint') rather than being silently swallowed. That's a genuinely new point, not a duplicate of the lint.mk comment, so it doesn't run afoul of the "don't repeat the same comment verbatim" guidance.
  • Verified actions/checkout@v6 (used by this job) always leaves a real .git, so the guard is a no-op in current CI — the comment is correctly framed as a hypothetical/defensive note ("if that guard ever went false"), not describing current behavior.
  • No indentation/YAML issues — the comment sits between - name: Lint SQL and run: make lint, which is valid YAML.

Other checks

  • No HISTORY.asc entry needed — this is internal build tooling, not user-facing extension behavior, consistent with existing entries.
  • Attempted to reproduce the tarball scenario locally (git archive + extract outside a git repo) but sandbox restrictions blocked writing outside the working directory and blocked non-trivial git subcommands, so I relied on static analysis + the PR's own documented manual verification (which matches the code as written) rather than re-running it myself.

No functional, security, or style issues found in either commit.

@jnasbyupgrade
jnasbyupgrade merged commit 5fa8083 into Postgres-Extensions:master Aug 4, 2026
30 checks passed
@jnasbyupgrade
jnasbyupgrade deleted the guard-vendored-lint-include-tarball branch August 4, 2026 22:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant