[codex] Isolate pnpm store on self-hosted runners#51
Conversation
Greptile SummaryThis PR isolates the pnpm store to each job's workspace directory ( Confidence Score: 5/5Safe to merge; the isolation pattern is correct and the single finding is a speculative concurrency edge case. The only finding is P2: pnpm config set store-dir writes to user-level config, which could theoretically collide if the runner executes concurrent jobs. In practice this rarely happens on self-hosted runners and the existing approach is already proven in MassageIthaca. No correctness, data-integrity, or security issues were found. No files require special attention. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[checkout] --> B[setup-node\nno built-in cache]
B --> C[corepack enable]
C --> D[pnpm config set store-dir\nworkspace local path]
D --> E[actions/cache restore\npath = workspace store]
E -->|hit| F[pnpm install uses\nrestored workspace store]
E -->|miss| G[pnpm install downloads\nto workspace store]
F --> H[build and test steps]
G --> H
H --> I[actions/cache save\npost-job if key is new]
Reviews (1): Last reviewed commit: "ci: isolate pnpm store on self-hosted ru..." | Re-trigger Greptile |
| id: pnpm-store | ||
| run: echo "path=$(pnpm store path --silent)" >> "$GITHUB_OUTPUT" | ||
| - name: Configure workspace pnpm store | ||
| run: pnpm config set store-dir "$PNPM_STORE_PATH" |
There was a problem hiding this comment.
User-level config written by
pnpm config set on shared runners
pnpm config set store-dir writes to ~/.npmrc (user scope) by default, not to the project .npmrc. On a self-hosted runner that executes more than one concurrent job under the same OS user, two jobs with different $GITHUB_WORKSPACE paths could race to overwrite this value — each setting its own workspace-relative path — so one job's pnpm install might end up reading the store of the other job.
A lower-risk alternative is to scope the setting to the project directory, which is unique per checkout:
| run: pnpm config set store-dir "$PNPM_STORE_PATH" | |
| run: pnpm config set store-dir "$PNPM_STORE_PATH" --location project |
This writes to .npmrc inside the workspace rather than ~/.npmrc, so concurrent jobs can't collide. The same change would apply to publish.yml line 34.
* refactor!: remove middleware code (belongs in acuity-middleware) (#10) Removed: src/middleware/ (33 files), modal-app.py, Dockerfile, live tests, playwright deps. Version 0.3.1 to 0.4.0. * chore: bump version to 0.5.0 * refactor!: remove acuity-scraper adapter Scraper belongs in acuity-middleware, not the scheduling library. Deprecated since extract-business.ts + middleware wizard steps replaced all scraper functionality. BREAKING: AcuityScraper, createScraperAdapter, scrapeServicesOnce, scrapeAvailabilityOnce removed from @tummycrypt/scheduling-kit/adapters. * build: add Bazel 8 configuration with subpackage targets - MODULE.bazel: bzlmod config with rules_js 2.9.1, rules_ts 3.8.4, SWC, pnpm 9 - BUILD.bazel: svelte-package build, npm_package, 6 subpackage ts_project targets (core, adapters, payments, reconciliation, lib, testing), vitest, svelte-check typecheck - .bazelrc: build/CI/debug/release configs with disk cache - .bazelversion: pin to 8.1.1 - .npmrc: hoist=false (required by rules_js) * feat: v0.5.0 - remove acuity-scraper, add Bazel 8 config (#11) * chore: bump version to 0.5.0 * refactor!: remove acuity-scraper adapter Scraper belongs in acuity-middleware, not the scheduling library. Deprecated since extract-business.ts + middleware wizard steps replaced all scraper functionality. BREAKING: AcuityScraper, createScraperAdapter, scrapeServicesOnce, scrapeAvailabilityOnce removed from @tummycrypt/scheduling-kit/adapters. * build: add Bazel 8 configuration with subpackage targets - MODULE.bazel: bzlmod config with rules_js 2.9.1, rules_ts 3.8.4, SWC, pnpm 9 - BUILD.bazel: svelte-package build, npm_package, 6 subpackage ts_project targets (core, adapters, payments, reconciliation, lib, testing), vitest, svelte-check typecheck - .bazelrc: build/CI/debug/release configs with disk cache - .bazelversion: pin to 8.1.1 - .npmrc: hoist=false (required by rules_js) * feat(venmo): add payeeEmail option to route payments to practitioner When payeeEmail is set in VenmoAdapterConfig, the PayPal order creation includes payee.email_address in purchase_units. This routes payments directly to the practitioner's PayPal account without requiring their API credentials. Ref: PayPal "Pay another account" docs * chore: bump version to 0.5.1 (payee-email support) * fix(ci): use @Jesssullivan scope for GitHub Packages mirror (Jesssullivan#18) * feat(venmo): add returnUrl/cancelUrl to experience_context (Jesssullivan#19) * fix(ci): use @Jesssullivan scope for GitHub Packages mirror * feat(venmo): add returnUrl/cancelUrl to experience_context PayPal requires return_url and cancel_url in the Venmo payment source experience_context for proper popup handling. Without them, PayPal may force additional buyer verification loops or block the popup flow. New optional fields on VenmoAdapterConfig: returnUrl, cancelUrl. * chore: bump to 0.5.2 (PayPal return URLs) (Jesssullivan#20) * fix(ci): use @Jesssullivan scope for GitHub Packages mirror * feat(venmo): add returnUrl/cancelUrl to experience_context PayPal requires return_url and cancel_url in the Venmo payment source experience_context for proper popup handling. Without them, PayPal may force additional buyer verification loops or block the popup flow. New optional fields on VenmoAdapterConfig: returnUrl, cancelUrl. * chore: bump to 0.5.2 (PayPal return URLs) * feat: onboarding subpackage — provider credential management (Jesssullivan#21-Jesssullivan#27) (Jesssullivan#28) New @tummycrypt/scheduling-kit/onboarding subpackage: Interfaces: - CredentialStore: app-provided key-value storage (PG, Redis, etc.) - EncryptionProvider: app-provided encryption (AES, Vault, etc.) - StripeConnectConfig, StripeAccountStatus, WebhookSetupResult types Stripe: - buildStripeAuthorizeUrl() + exchangeStripeCode() — Connect OAuth - getStripeAccountStatus() — account onboarding status - validateStripeKeys() — key validation against Stripe API - createStripeWebhook() + deleteStripeWebhooks() — webhook CRUD PayPal: - validatePayPalCredentials() — OAuth token validation - createPayPalWebhook() — webhook creation Build: - Bazel //src/onboarding target (deps: :core, :payments, effect) - Package.json ./onboarding export Pattern: library defines interfaces + helpers, application provides CredentialStore implementation. Same pattern as HomegrownAdapter's getDb callback — scheduling-kit doesn't know about databases. Closes Jesssullivan#21, Jesssullivan#22, Jesssullivan#23, Jesssullivan#24, Jesssullivan#27. Partial Jesssullivan#25, Jesssullivan#26. * chore: bump to 0.6.0 (onboarding subpackage) (Jesssullivan#29) * feat: adapter factory pattern + 21 onboarding tests (Jesssullivan#25, Jesssullivan#26) (Jesssullivan#30) - createAdapterFactory(): settings-driven singleton with cache, promise dedup, reset, and disable lifecycle - 21 tests: Stripe OAuth URL, key validation, account status, PayPal credential validation, factory lifecycle (cache, reset, disable, store passthrough) - Updated vitest.config.ts to include onboarding test glob Closes Jesssullivan#25, Jesssullivan#26. * chore: strip sourcemaps from npm package (Jesssullivan#31) * feat: adapter factory pattern + 21 onboarding tests (Jesssullivan#25, Jesssullivan#26) - createAdapterFactory(): settings-driven singleton with cache, promise dedup, reset, and disable lifecycle - 21 tests: Stripe OAuth URL, key validation, account status, PayPal credential validation, factory lifecycle (cache, reset, disable, store passthrough) - Updated vitest.config.ts to include onboarding test glob Closes Jesssullivan#25, Jesssullivan#26. * chore: strip sourcemaps from npm package (2,711 .map files excluded) * feat: provider status helpers + SetupStep type (Jesssullivan#32) (Jesssullivan#33) * chore: bump to 0.6.1 (status helpers) (Jesssullivan#34) * align build truth and package boundaries (Jesssullivan#39) * ci: enforce Bazel release metadata truth (Jesssullivan#40) * docs: add agent and llm operating brief (Jesssullivan#42) * feat(payments)!: converge PaymentCapabilities contract from tinyland-inc (Jesssullivan#45) * feat(payments)!: converge PaymentCapabilities contract from tinyland-inc Cherry-pick tinyland-inc/main squash (v0.7.0) onto Jesssullivan/main. Keeps Jess's CI/publish workflows and Bazel structure. Bumps all version references to 0.7.0. - PaymentCapabilities, StripeCapability, VenmoCapability types - getDefaultCapabilities() factory - HybridCheckoutDrawer: capabilities prop replaces individual payment props - Cash at Visit structurally removed (cash: false) * fix(ci): skip prepublish scripts in gh packages mirror * docs(release): clarify scheduling-kit authority (Jesssullivan#46) * ci(publish): validate bazel package artifact (Jesssullivan#47) * build(bazel): publish scheduling-kit from bazel artifact * fix(ui): dark-mode skeleton shimmer and border parity (Jesssullivan#49) Replace hardcoded hex CSS with light-dark() for 8 components: skeleton loading shimmer, border colors, scrollbar tracks. Ensures proper dark-mode rendering when consumed by host apps. * ci: support honey self-hosted runner stopgap (Jesssullivan#50) * ci: isolate pnpm store on self-hosted runners (Jesssullivan#51) * fix: make publish workflow self-hosted-safe (Jesssullivan#52) * fix(ci): make github package artifact writable (Jesssullivan#53) * perf(components): drop zod from browser client form (Jesssullivan#54) * fix(ci): ignore npm scripts when publishing bazel pkg (Jesssullivan#55) * fix(ci): ignore npm scripts when publishing bazel pkg * fix(ci): clean stale bazel publish artifacts on runners * fix(ci): partition pnpm caches by runner (Jesssullivan#56)
Summary
Testing