Skip to content

ci: refresh pnpm lockfile before merge#707

Merged
cryppadotta merged 4 commits intomasterfrom
nm/premerge-lockfile-refresh
Mar 12, 2026
Merged

ci: refresh pnpm lockfile before merge#707
cryppadotta merged 4 commits intomasterfrom
nm/premerge-lockfile-refresh

Conversation

@cryppadotta
Copy link
Copy Markdown
Contributor

Summary

  • move lockfile refresh from post-merge master repair to pull-request time
  • auto-commit refreshed pnpm-lock.yaml for same-repo PRs when dependency manifests change
  • fail fork PRs with explicit lockfile refresh instructions and verify PR installs with --frozen-lockfile

Context

The old flow allowed package manifest changes to merge to master before pnpm-lock.yaml was updated, which broke Docker and any other frozen-lockfile build until a follow-up bot PR was merged. This change enforces lockfile freshness before merge and removes the old chore/refresh-lockfile branch flow.

cryppadotta and others added 4 commits March 12, 2026 08:42
* public-gh/master:
  Drop pnpm lockfile from PR
  Update ui/src/components/OnboardingWizard.tsx
  Update ui/src/components/OnboardingWizard.tsx
  Fix onboarding manual debug JSX
  Improve onboarding defaults and issue goal fallback
  Simplify adapter environment check: animate pass, show debug only on fail
  Show Claude Code and Codex as recommended, collapse other adapter types
  Animate onboarding layout when switching between Company and Agent steps
  Make onboarding wizard steps clickable tabs for easier dev navigation
  Add agent chat architecture plan
  Style tweaks for onboarding wizard step 1
  Add direct onboarding routes
* public-gh/master:
  Raise default max turns to 300
@cryppadotta cryppadotta merged commit 56df8d3 into master Mar 12, 2026
4 checks passed
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Mar 12, 2026

Greptile Summary

This PR shifts lockfile freshness enforcement from a post-merge repair flow (a bot PR against master) to PR time, ensuring pnpm-lock.yaml is always up-to-date before merge. The approach is sound and well-structured, but two bugs in the new workflows need to be fixed before this is safe to land.

Key changes:

  • refresh-lockfile.yml (deleted): removed the post-merge flow that created chore/refresh-lockfile bot PRs after stale merges.
  • refresh-lockfile-pr.yml (new): triggers on PR events, auto-commits a refreshed lockfile to same-repo PRs, and fails fork PRs that need a manual refresh.
  • pr-policy.yml: merged the two old steps into one using the GitHub API for file detection, and now validates lockfile freshness in-situ by running pnpm install --lockfile-only and checking git diff.
  • pr-verify.yml: switches from --no-frozen-lockfile to --frozen-lockfile — correct now that the lockfile is guaranteed current before CI runs.

Issues found:

  • pr-policy.yml checkout will always fail: The new permissions block sets only pull-requests: read. In GitHub Actions, unlisted permissions at the job level are set to none, so contents becomes none and actions/checkout@v4 will fail with a permission error. contents: read must be added.
  • refresh-lockfile-pr.yml "Fail on unexpected file changes" step can spuriously fail: When only pnpm-lock.yaml is modified, grep -Fvq ' pnpm-lock.yaml' finds no matching lines and returns exit code 1. Because the if block is skipped, the step exits with that 1, failing the step even on a clean lockfile refresh. An explicit exit 0 after the guard if is needed.

Confidence Score: 2/5

  • Not safe to merge — two bugs will prevent both the policy check and the lockfile refresh from functioning correctly on any PR with manifest changes.
  • The overall design is solid and the intent is clearly correct, but the missing contents: read permission in pr-policy.yml means the checkout step will always fail (breaking the gating check entirely), and the grep exit-code leak in refresh-lockfile-pr.yml means the bot commit step can never be reached even when the refresh is clean. Both issues are in the critical path of the new enforcement mechanism.
  • .github/workflows/pr-policy.yml (missing contents: read) and .github/workflows/refresh-lockfile-pr.yml (grep exit code leak in "Fail on unexpected file changes" step).

Important Files Changed

Filename Overview
.github/workflows/pr-policy.yml Consolidated lockfile policy check using GitHub API for file detection; missing contents: read in the new permissions block will cause the checkout step to fail entirely.
.github/workflows/refresh-lockfile-pr.yml New workflow that auto-commits a refreshed lockfile to same-repo PRs and fails fork PRs that need a refresh; the "Fail on unexpected file changes" step can spuriously exit 1 when only pnpm-lock.yaml is dirty due to the grep exit code leaking out.
.github/workflows/pr-verify.yml Single-line change switching pnpm install from --no-frozen-lockfile to --frozen-lockfile; correct and expected now that the lockfile is guaranteed fresh before CI runs.
.github/workflows/refresh-lockfile.yml Old post-merge lockfile refresh workflow removed; replaced by the new PR-time refresh-lockfile-pr.yml.
doc/DEVELOPING.md Documentation updated to reflect the new PR-time lockfile ownership model; changes are accurate and clear.
Prompt To Fix All With AI
This is a comment left during a code review.
Path: .github/workflows/pr-policy.yml
Line: 16-17

Comment:
**Missing `contents: read` permission breaks checkout**

When a `permissions` block is defined at the job level in GitHub Actions, any permission not explicitly listed is set to `none`. Only `pull-requests: read` is listed here, which means `contents` will default to `none`. The `actions/checkout@v4` step that immediately follows requires `contents: read` to clone the repository — without it, the checkout will fail with a permission error and the entire policy job will be broken.

```suggestion
    permissions:
      contents: read
      pull-requests: read
```

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: .github/workflows/refresh-lockfile-pr.yml
Line: 72-84

Comment:
**"Fail on unexpected file changes" step never explicitly exits 0 for the dirty case**

When `changed` is non-empty and all changed files are `pnpm-lock.yaml`, the `grep -Fvq ' pnpm-lock.yaml'` command returns exit code `1` (no non-lockfile lines found). The `if` block is skipped, and the step exits with the last command's exit code — which is `1` from `grep`. This will fail the step even when the lockfile refresh is clean, blocking the subsequent commit step.

Add an explicit `exit 0` after the guard `if` block so the step succeeds when only `pnpm-lock.yaml` is dirty:

```suggestion
      - name: Fail on unexpected file changes
        if: steps.changes.outputs.manifest_changed == 'true'
        run: |
          changed="$(git status --porcelain)"
          if [ -z "$changed" ]; then
            echo "Lockfile is already up to date."
            exit 0
          fi
          if printf '%s\n' "$changed" | grep -Fvq ' pnpm-lock.yaml'; then
            echo "Unexpected files changed during lockfile refresh:"
            echo "$changed"
            exit 1
          fi
          exit 0
```

How can I resolve this? If you propose a fix, please make it concise.

Last reviewed commit: 8808a33

Comment on lines +16 to +17
permissions:
pull-requests: read
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.

Missing contents: read permission breaks checkout

When a permissions block is defined at the job level in GitHub Actions, any permission not explicitly listed is set to none. Only pull-requests: read is listed here, which means contents will default to none. The actions/checkout@v4 step that immediately follows requires contents: read to clone the repository — without it, the checkout will fail with a permission error and the entire policy job will be broken.

Suggested change
permissions:
pull-requests: read
permissions:
contents: read
pull-requests: read
Prompt To Fix With AI
This is a comment left during a code review.
Path: .github/workflows/pr-policy.yml
Line: 16-17

Comment:
**Missing `contents: read` permission breaks checkout**

When a `permissions` block is defined at the job level in GitHub Actions, any permission not explicitly listed is set to `none`. Only `pull-requests: read` is listed here, which means `contents` will default to `none`. The `actions/checkout@v4` step that immediately follows requires `contents: read` to clone the repository — without it, the checkout will fail with a permission error and the entire policy job will be broken.

```suggestion
    permissions:
      contents: read
      pull-requests: read
```

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +72 to +84
- name: Fail on unexpected file changes
if: steps.changes.outputs.manifest_changed == 'true'
run: |
changed="$(git status --porcelain)"
if [ -z "$changed" ]; then
echo "Lockfile is already up to date."
exit 0
fi
if printf '%s\n' "$changed" | grep -Fvq ' pnpm-lock.yaml'; then
echo "Unexpected files changed during lockfile refresh:"
echo "$changed"
exit 1
fi
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.

"Fail on unexpected file changes" step never explicitly exits 0 for the dirty case

When changed is non-empty and all changed files are pnpm-lock.yaml, the grep -Fvq ' pnpm-lock.yaml' command returns exit code 1 (no non-lockfile lines found). The if block is skipped, and the step exits with the last command's exit code — which is 1 from grep. This will fail the step even when the lockfile refresh is clean, blocking the subsequent commit step.

Add an explicit exit 0 after the guard if block so the step succeeds when only pnpm-lock.yaml is dirty:

Suggested change
- name: Fail on unexpected file changes
if: steps.changes.outputs.manifest_changed == 'true'
run: |
changed="$(git status --porcelain)"
if [ -z "$changed" ]; then
echo "Lockfile is already up to date."
exit 0
fi
if printf '%s\n' "$changed" | grep -Fvq ' pnpm-lock.yaml'; then
echo "Unexpected files changed during lockfile refresh:"
echo "$changed"
exit 1
fi
- name: Fail on unexpected file changes
if: steps.changes.outputs.manifest_changed == 'true'
run: |
changed="$(git status --porcelain)"
if [ -z "$changed" ]; then
echo "Lockfile is already up to date."
exit 0
fi
if printf '%s\n' "$changed" | grep -Fvq ' pnpm-lock.yaml'; then
echo "Unexpected files changed during lockfile refresh:"
echo "$changed"
exit 1
fi
exit 0
Prompt To Fix With AI
This is a comment left during a code review.
Path: .github/workflows/refresh-lockfile-pr.yml
Line: 72-84

Comment:
**"Fail on unexpected file changes" step never explicitly exits 0 for the dirty case**

When `changed` is non-empty and all changed files are `pnpm-lock.yaml`, the `grep -Fvq ' pnpm-lock.yaml'` command returns exit code `1` (no non-lockfile lines found). The `if` block is skipped, and the step exits with the last command's exit code — which is `1` from `grep`. This will fail the step even when the lockfile refresh is clean, blocking the subsequent commit step.

Add an explicit `exit 0` after the guard `if` block so the step succeeds when only `pnpm-lock.yaml` is dirty:

```suggestion
      - name: Fail on unexpected file changes
        if: steps.changes.outputs.manifest_changed == 'true'
        run: |
          changed="$(git status --porcelain)"
          if [ -z "$changed" ]; then
            echo "Lockfile is already up to date."
            exit 0
          fi
          if printf '%s\n' "$changed" | grep -Fvq ' pnpm-lock.yaml'; then
            echo "Unexpected files changed during lockfile refresh:"
            echo "$changed"
            exit 1
          fi
          exit 0
```

How can I resolve this? If you propose a fix, please make it concise.

@cryppadotta cryppadotta deleted the nm/premerge-lockfile-refresh branch March 12, 2026 16:23
cryppadotta added a commit that referenced this pull request Mar 12, 2026
…-refresh"

This reverts commit 56df8d3, reversing
changes made to ac82cae.
@cryppadotta cryppadotta mentioned this pull request Mar 12, 2026
cryppadotta added a commit that referenced this pull request Mar 12, 2026
cryppadotta added a commit that referenced this pull request Mar 13, 2026
* 'master' of github.com-dotta:paperclipai/paperclip:
  fix: resolve type errors in process-lost-reaper PR
  fix(heartbeat): prevent false process_lost failures on queued and non-child-process runs
  Revert "Merge pull request #707 from paperclipai/nm/premerge-lockfile-refresh"
  fix: ensure embedded PostgreSQL databases use UTF-8 encoding
cryppadotta added a commit that referenced this pull request Mar 13, 2026
* public-gh/master: (33 commits)
  fix: align embedded postgres ctor types with initdbFlags usage
  docs: add dated plan naming rule and align workspace plan
  Expand workspace plan for migration and cloud execution
  Add workspace product model plan
  docs: add token optimization plan
  docs: organize plans into doc/plans with date prefixes
  fix: keep runtime skills scoped to ./skills
  fix: prefer .agents skills and repair codex symlink targets\n\nCo-Authored-By: Paperclip <[email protected]>
  Change sidebar Documentation link to external docs.paperclip.ing
  Fix local-cli skill install for moved .agents skills
  docs: update PRODUCT.md and add 2026-03-13 features plan
  feat(worktree): add worktree:cleanup command, env var defaults, and auto-prefix
  fix: resolve type errors in process-lost-reaper PR
  fix(heartbeat): prevent false process_lost failures on queued and non-child-process runs
  Revert "Merge pull request #707 from paperclipai/nm/premerge-lockfile-refresh"
  ci: refresh pnpm lockfile before merge
  fix(docker): include gemini adapter manifest in deps stage
  chore(lockfile): refresh pnpm-lock.yaml
  Raise default max turns to 300
  Drop pnpm lockfile from PR
  ...
liamvinberg pushed a commit to devosurf/paperclip that referenced this pull request Mar 23, 2026
…ge-lockfile-refresh"

This reverts commit 56df8d3, reversing
changes made to ac82cae.
tr00x pushed a commit to tr00x/paperclip that referenced this pull request Mar 26, 2026
…ile-refresh

ci: refresh pnpm lockfile before merge
tr00x pushed a commit to tr00x/paperclip that referenced this pull request Mar 26, 2026
…ge-lockfile-refresh"

This reverts commit 56df8d3, reversing
changes made to ac82cae.
tr00x pushed a commit to tr00x/paperclip that referenced this pull request Mar 26, 2026
tr00x pushed a commit to tr00x/paperclip that referenced this pull request Mar 26, 2026
* 'master' of github.com-dotta:paperclipai/paperclip:
  fix: resolve type errors in process-lost-reaper PR
  fix(heartbeat): prevent false process_lost failures on queued and non-child-process runs
  Revert "Merge pull request paperclipai#707 from paperclipai/nm/premerge-lockfile-refresh"
  fix: ensure embedded PostgreSQL databases use UTF-8 encoding
tr00x pushed a commit to tr00x/paperclip that referenced this pull request Mar 26, 2026
* public-gh/master: (33 commits)
  fix: align embedded postgres ctor types with initdbFlags usage
  docs: add dated plan naming rule and align workspace plan
  Expand workspace plan for migration and cloud execution
  Add workspace product model plan
  docs: add token optimization plan
  docs: organize plans into doc/plans with date prefixes
  fix: keep runtime skills scoped to ./skills
  fix: prefer .agents skills and repair codex symlink targets\n\nCo-Authored-By: Paperclip <[email protected]>
  Change sidebar Documentation link to external docs.paperclip.ing
  Fix local-cli skill install for moved .agents skills
  docs: update PRODUCT.md and add 2026-03-13 features plan
  feat(worktree): add worktree:cleanup command, env var defaults, and auto-prefix
  fix: resolve type errors in process-lost-reaper PR
  fix(heartbeat): prevent false process_lost failures on queued and non-child-process runs
  Revert "Merge pull request paperclipai#707 from paperclipai/nm/premerge-lockfile-refresh"
  ci: refresh pnpm lockfile before merge
  fix(docker): include gemini adapter manifest in deps stage
  chore(lockfile): refresh pnpm-lock.yaml
  Raise default max turns to 300
  Drop pnpm lockfile from PR
  ...
hhhhansel pushed a commit to hhhhansel/paperclip that referenced this pull request Mar 27, 2026
…ile-refresh

ci: refresh pnpm lockfile before merge
hhhhansel pushed a commit to hhhhansel/paperclip that referenced this pull request Mar 27, 2026
…ge-lockfile-refresh"

This reverts commit b572ca6, reversing
changes made to 512b675.
hhhhansel pushed a commit to hhhhansel/paperclip that referenced this pull request Mar 27, 2026
hhhhansel pushed a commit to hhhhansel/paperclip that referenced this pull request Mar 27, 2026
* 'master' of github.com-dotta:paperclipai/paperclip:
  fix: resolve type errors in process-lost-reaper PR
  fix(heartbeat): prevent false process_lost failures on queued and non-child-process runs
  Revert "Merge pull request paperclipai#707 from paperclipai/nm/premerge-lockfile-refresh"
  fix: ensure embedded PostgreSQL databases use UTF-8 encoding
hhhhansel pushed a commit to hhhhansel/paperclip that referenced this pull request Mar 27, 2026
* public-gh/master: (33 commits)
  fix: align embedded postgres ctor types with initdbFlags usage
  docs: add dated plan naming rule and align workspace plan
  Expand workspace plan for migration and cloud execution
  Add workspace product model plan
  docs: add token optimization plan
  docs: organize plans into doc/plans with date prefixes
  fix: keep runtime skills scoped to ./skills
  fix: prefer .agents skills and repair codex symlink targets\n\nCo-Authored-By: Paperclip <[email protected]>
  Change sidebar Documentation link to external docs.paperclip.ing
  Fix local-cli skill install for moved .agents skills
  docs: update PRODUCT.md and add 2026-03-13 features plan
  feat(worktree): add worktree:cleanup command, env var defaults, and auto-prefix
  fix: resolve type errors in process-lost-reaper PR
  fix(heartbeat): prevent false process_lost failures on queued and non-child-process runs
  Revert "Merge pull request paperclipai#707 from paperclipai/nm/premerge-lockfile-refresh"
  ci: refresh pnpm lockfile before merge
  fix(docker): include gemini adapter manifest in deps stage
  chore(lockfile): refresh pnpm-lock.yaml
  Raise default max turns to 300
  Drop pnpm lockfile from PR
  ...
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