Skip to content

chore(release): bump 4.1.1 — fix root exports, fallback handling, and release docs#26

Merged
marklearst merged 2 commits intomainfrom
codex/conduct-comprehensive-code-review-04u6jr
Feb 23, 2026
Merged

chore(release): bump 4.1.1 — fix root exports, fallback handling, and release docs#26
marklearst merged 2 commits intomainfrom
codex/conduct-comprehensive-code-review-04u6jr

Conversation

@marklearst
Copy link
Copy Markdown
Owner

Motivation

  • Restore documented package root exports and ensure runtime utilities are available when importing from @figma-vars/hooks.
  • Prevent invalid fallback JSON from forcing SWR fallback cache keys so live credentials are used when appropriate.
  • Make the release checklist reusable for 4.x and provide guidance to backfill missing tags for CI-driven npm publishes.

Description

  • Re-exported utilities from the package root in src/index.ts (withRetry, redactToken, rate-limit helpers, and runtime type guards including validateFallbackData).
  • Hardened fallback logic in src/hooks/useVariables.ts, src/hooks/usePublishedVariables.ts, and src/hooks/useInvalidateVariables.ts to treat fallback mode as active only when parsedFallbackFile is present.
  • Exported validateFallbackData from src/utils/index.ts and adjusted other utils barrel exports.
  • Updated tests to use parsedFallbackFile in mocks, added regression tests that assert live SWR keys are used when fallbackFile exists but parsedFallbackFile is invalid, and expanded index export checks to include the newly re-exported utilities.
  • Bumped package version to 4.1.1 and updated README.md release checklist to a reusable 4.x flow with a backfill-tag example for v4.1.0 and v4.1.1.

Testing

  • Ran the full test suite with pnpm vitest run; all tests passed (301 tests, 32 files).
  • Ran the repository formatting/hooks as part of the commit (prettier applied) as part of the change process and there were no lint/format failures.
  • Attempted to publish/backfill tags in this environment but pushing tags remotely could not be completed due to no configured remote in the execution environment; the README now documents how to backfill tags locally and push them for CI to pick up.

Codex Task

Copilot AI review requested due to automatic review settings February 23, 2026 11:31
@codecov
Copy link
Copy Markdown

codecov bot commented Feb 23, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 91.30%. Comparing base (cb180a6) to head (1abd939).
⚠️ Report is 3 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main      #26   +/-   ##
=======================================
  Coverage   91.30%   91.30%           
=======================================
  Files          36       36           
  Lines         978      978           
  Branches      282      282           
=======================================
  Hits          893      893           
  Misses         84       84           
  Partials        1        1           
Flag Coverage Δ
unittests 91.30% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This patch release addresses three main issues: restoring documented utility exports from the package root, hardening fallback mode detection to prevent invalid JSON from triggering fallback cache keys, and updating the release documentation with a reusable 4.x checklist.

Changes:

  • Re-exported runtime utilities (withRetry, redactToken, rate-limit helpers, and type guards) from the package root to match documentation
  • Updated fallback logic in hooks to only activate fallback mode when parsedFallbackFile is valid, not just when fallbackFile exists
  • Added regression tests for the edge case where fallbackFile exists but parsedFallbackFile is invalid, ensuring live credentials are used

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
package.json Bumped version from 4.0.0 to 4.1.1
CHANGELOG.md Added 4.1.1 release notes documenting the fixes
README.md Updated release checklist to be reusable for 4.x releases and added backfill tag examples
src/index.ts Re-exported utilities (withRetry, redactToken, rate-limit helpers, type guards) from package root
src/utils/index.ts Exported validateFallbackData from utils barrel
src/hooks/useVariables.ts Changed fallback detection to only check parsedFallbackFile, removed legacy fallback support
src/hooks/usePublishedVariables.ts Changed fallback detection to only check parsedFallbackFile, removed legacy fallback support
src/hooks/useInvalidateVariables.ts Changed fallback detection to only check parsedFallbackFile
tests/index.test.ts Added assertions for newly exported utilities
tests/hooks/useVariables.test.tsx Updated mocks to use parsedFallbackFile, added test for invalid fallback with live credentials
tests/hooks/usePublishedVariables.test.tsx Updated mocks to use parsedFallbackFile, added test for invalid fallback with live credentials
tests/hooks/useInvalidateVariables.test.tsx Updated mocks to use parsedFallbackFile instead of fallbackFile

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +498 to +526

it('should use live key when fallbackFile exists but parsedFallbackFile is invalid', () => {
const spy = vi
.spyOn(useFigmaTokenContextModule, 'useFigmaTokenContext')
.mockReturnValue({
token: 'test-token',
fileKey: 'test-key',
fallbackFile: '{invalid-json}',
parsedFallbackFile: undefined,
providerId: 'test-provider',
} as ReturnType<typeof useFigmaTokenContextModule.useFigmaTokenContext>)

mockedUseSWR.mockReturnValue({
data: undefined,
error: undefined,
isLoading: false,
isValidating: false,
})

renderHook(() => useVariables())

expect(mockedUseSWR).toHaveBeenCalledWith(
['https://api.figma.com/v1/files/test-key/variables/local', 'test-token'],
expect.any(Function),
undefined
)

spy.mockRestore()
})
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

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

This test expects legacy fallback behavior where a fallbackFile object would be used even when parsedFallbackFile is undefined. However, the PR removes this legacy support - the hook now only treats fallback mode as active when parsedFallbackFile is present (line 24 in useVariables.ts). With parsedFallbackFile set to undefined in this test, hasFallback will be false, and the code will attempt to use live credentials instead of the fallback. This test should either be updated to reflect the new behavior (testing that live credentials are used when parsedFallbackFile is undefined) or removed if the legacy behavior is no longer supported.

Suggested change
it('should use live key when fallbackFile exists but parsedFallbackFile is invalid', () => {
const spy = vi
.spyOn(useFigmaTokenContextModule, 'useFigmaTokenContext')
.mockReturnValue({
token: 'test-token',
fileKey: 'test-key',
fallbackFile: '{invalid-json}',
parsedFallbackFile: undefined,
providerId: 'test-provider',
} as ReturnType<typeof useFigmaTokenContextModule.useFigmaTokenContext>)
mockedUseSWR.mockReturnValue({
data: undefined,
error: undefined,
isLoading: false,
isValidating: false,
})
renderHook(() => useVariables())
expect(mockedUseSWR).toHaveBeenCalledWith(
['https://api.figma.com/v1/files/test-key/variables/local', 'test-token'],
expect.any(Function),
undefined
)
spy.mockRestore()
})

Copilot uses AI. Check for mistakes.
Comment on lines 486 to +524
it('should use live key when fallbackFile exists but parsedFallbackFile is invalid', () => {
const spy = vi
.spyOn(useFigmaTokenContextModule, 'useFigmaTokenContext')
.mockReturnValue({
token: 'test-token',
fileKey: 'test-key',
fallbackFile: '{invalid-json}',
parsedFallbackFile: undefined,
providerId: 'test-provider',
} as ReturnType<typeof useFigmaTokenContextModule.useFigmaTokenContext>)

mockedUseSWR.mockReturnValue({
data: undefined,
error: undefined,
isLoading: false,
isValidating: false,
})

renderHook(() => usePublishedVariables())

expect(mockedUseSWR).toHaveBeenCalledWith(
[
'https://api.figma.com/v1/files/test-key/variables/published',
'test-token',
],
expect.any(Function),
undefined
)

spy.mockRestore()
})

it('should use live key when fallbackFile exists but parsedFallbackFile is invalid', () => {
const spy = vi
.spyOn(useFigmaTokenContextModule, 'useFigmaTokenContext')
.mockReturnValue({
token: 'test-token',
fileKey: 'test-key',
fallbackFile: '{invalid-json}',
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

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

This test expects legacy fallback behavior where a fallbackFile object would be used even when parsedFallbackFile is undefined. However, the PR removes this legacy support - the hook now only treats fallback mode as active when parsedFallbackFile is present (line 50 in usePublishedVariables.ts). With parsedFallbackFile set to undefined in this test, hasFallback will be false, and the code will attempt to use live credentials instead of the fallback. This test should either be updated to reflect the new behavior (testing that live credentials are used when parsedFallbackFile is undefined) or removed if the legacy behavior is no longer supported.

Copilot uses AI. Check for mistakes.
Comment on lines +547 to +548
git tag -a v4.1.0 <commit-sha-for-4.1.0> -m "v4.1.0"
git tag -a v4.1.1 <commit-sha-for-4.1.1> -m "v4.1.1"
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

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

The README shows instructions for backfilling tags for v4.1.0, but there is no 4.1.0 release documented in the CHANGELOG. The version jumps directly from 4.0.0 to 4.1.1. If v4.1.0 was actually released but not documented, the CHANGELOG should be updated to include it. If v4.1.0 was never released, the README examples should use v4.1.1 instead of v4.1.0 to avoid confusion.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

@copilot open a new pull request to apply changes based on this feedback

Copy link
Copy Markdown

Copilot AI commented Feb 23, 2026

@marklearst I've opened a new pull request, #27, to work on those changes. Once the pull request is ready, I'll request review from you.

@marklearst marklearst merged commit 005c91f into main Feb 23, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants