Storybook Git Metadata Generation
Status: Stable This guide explains how to generate git metadata for Storybook builds, enabling the design tests library to detect the current deployment version being tested.
Overview
The design tests library can automatically detect the current deployment version by reading /git-metadata.json from your Storybook build. This file contains git commit information and is generated during the Storybook build process.
What it provides:
- Git commit hash and branch
- Commit message and author
- Timestamp and build metadata
- Link to commit/build for traceability
Why it's needed:
- Tracks which deployment is being tested
- Enables baseline version tracking
- Provides attribution for visual changes
- Helps debug "what changed" questions
Implementation Steps
1. Create the Generator Script
Create .storybook/scripts/generate-git-metadata.js:
const fs = require('fs');
const { execSync } = require('child_process');
const path = require('path');
/**
* Generate git metadata for design tests
*
* Creates a git-metadata.json file with current git state
* to be included in the Storybook static build.
*/
function generateGitMetadata() {
try {
// Extract git information
const gitHash = execSync('git rev-parse HEAD').toString().trim();
const shortHash = execSync('git rev-parse --short HEAD').toString().trim();
const branch = execSync('git rev-parse --abbrev-ref HEAD').toString().trim();
const commitMessage = execSync('git log -1 --pretty=%B | head -n 1').toString().trim();
const author = execSync('git log -1 --pretty="%an <%ae>"').toString().trim();
const timestamp = new Date().toISOString();
// Build reference string (format: {hash}|{branch}|{timestamp})
const reference = `${branch}_${shortHash}_${timestamp}`;
// Generate reference link (customize for your git hosting)
// Examples:
// - Bitbucket: `https://bitbucket.org/your-org/repo/commits/${gitHash}`
// - GitHub: `https://github.com/your-org/repo/commit/${gitHash}`
// - GitLab: `https://gitlab.com/your-org/repo/-/commit/${gitHash}`
const referenceLink = `https://bitbucket.org/your-org/your-repo/commits/${gitHash}`;
// Build metadata object
const metadata = {
reference,
referenceLink,
createdAt: timestamp,
gitHash,
branch,
commitMessage,
author,
};
// Ensure output directory exists
const outputDir = path.join(__dirname, '../generated');
if (!fs.existsSync(outputDir)) {
fs.mkdirSync(outputDir, { recursive: true });
}
// Write metadata file
const outputPath = path.join(outputDir, 'git-metadata.json');
fs.writeFileSync(outputPath, JSON.stringify(metadata, null, 2), 'utf-8');
console.log('✅ Generated git-metadata.json');
console.log(` Reference: ${reference}`);
console.log(` Link: ${referenceLink}`);
} catch (error) {
console.warn('⚠️ Could not generate git metadata:', error.message);
console.warn(' Design tests will use fallback detection');
// Non-fatal - tests can still run without this metadata
}
}
// Run if called directly
if (require.main === module) {
generateGitMetadata();
}
module.exports = { generateGitMetadata };
Customize the reference link:
- Update the
referenceLinkURL to match your git hosting provider - Add build number or other metadata if running in CI
2. Configure Storybook to Include the File
Update .storybook/main.js or .storybook/main.ts:
module.exports = {
// ... other config
staticDirs: [
'../public',
// Serve generated files at root (includes git-metadata.json)
{ from: '../.storybook/generated', to: '/' },
],
// ... rest of config
};
How it works:
- Files in
.storybook/generated/are served at the root of the Storybook /git-metadata.jsonbecomes accessible athttps://your-storybook.com/git-metadata.json- Design tests library fetches this file during test preparation
3. Update Build Script
Update package.json to run the generator before building:
{
"scripts": {
"build-storybook": "node .storybook/scripts/generate-git-metadata.js && storybook build",
"build-storybook:ci": "node .storybook/scripts/generate-git-metadata.js && storybook build --quiet"
}
}
4. Add to .gitignore
Add the generated directory to .gitignore:
# Storybook generated files
.storybook/generated/
Why ignore it:
- Generated during build, not source code
- Contains git hash specific to current commit
- Should be regenerated on each build
CI Integration (Jenkins Example)
If you're building Storybook in CI, you might want to include build metadata:
// .storybook/scripts/generate-git-metadata.js (CI section)
function generateGitMetadata() {
try {
// ... git extraction code ...
// Add CI-specific metadata
const metadata = {
reference,
referenceLink,
createdAt: timestamp,
gitHash,
branch,
commitMessage,
author,
// CI-specific fields
...(process.env.JENKINS_URL && {
buildNumber: process.env.BUILD_NUMBER,
buildUrl: `${process.env.JENKINS_URL}job/${process.env.JOB_NAME}/${process.env.BUILD_NUMBER}`,
jobName: process.env.JOB_NAME,
}),
};
// ... rest of code ...
}
}
Testing the Setup
After implementing, verify the metadata is accessible:
-
Build Storybook:
npm run build-storybook -
Check the generated file:
cat .storybook/generated/git-metadata.jsonShould output:
{
"reference": "abc123d|develop|2025-10-28T14:00:00.000Z",
"referenceLink": "https://bitbucket.org/.../commits/abc123d...",
"createdAt": "2025-10-28T14:00:00.000Z",
"gitHash": "abc123def456789...",
"branch": "develop",
"commitMessage": "feat: add new component",
"author": "John Doe <john@example.com>"
} -
Serve and test:
npx http-server storybook-static -p 8080
curl http://localhost:8080/git-metadata.json -
Run design tests:
# The library will automatically detect the metadata
pnpm run design-tests run --project storybookLook for this in the output:
🔍 Detecting current deployment metadata...
✓ Current metadata detected from /git-metadata.json
✓ Current: abc123d|develop|2025-10-28T14:00:00.000Z
Link: https://bitbucket.org/.../commits/abc123d...
Fallback Detection
If /git-metadata.json is not available, the design tests library will fall back to:
-
Environment variables:
CURRENT_REFERENCE="abc123|develop|2025-10-28T14:00:00Z" \
CURRENT_REFERENCE_LINK="https://example.com/commit/abc123" \
pnpm test -
Legacy meta tag detection:
<meta name="git-commit" content="abc123def456"> -
Unknown fallback:
reference: "unknown|unknown|{current-timestamp}"
Benefits
✅ Automatic version tracking - No manual configuration needed ✅ Traceability - Link back to exact commit being tested ✅ Debugging - Know exactly what changed when tests fail ✅ Baseline attribution - Track which commit created current baseline ✅ CI-friendly - Works in Jenkins, GitHub Actions, etc.
Example Repositories
- BFH Storybook:
bfh-web/.storybook/scripts/generate-git-metadata.js - MCHWEB Storybook:
mchweb-design-tests/.storybook/scripts/generate-git-metadata.js - EWZ Design System:
ewz-design-system/.storybook/scripts/generate-git-metadata.js
Troubleshooting
Q: The file isn't accessible at /git-metadata.json
A: Check that staticDirs in .storybook/main.js includes the generated directory with to: '/'
Q: Git commands fail during build A: Ensure the build runs in a git repository (not a shallow clone or .zip download)
Q: Design tests still show "unknown" reference A: Verify the file exists and is valid JSON. Check browser console for fetch errors.
Q: Can I use a different filename?
A: Yes, but you'll need to customize the detectCurrentMeta function in the library
Related Documentation
- Baseline Management - How baseline metadata works
- Adding Projects - Adding new projects to test configuration