Skip to content

Commit

Permalink
Setup keychain image snapshots
Browse files Browse the repository at this point in the history
  • Loading branch information
tarrencev committed Jan 3, 2025
1 parent 88a5f2f commit 3e70d68
Show file tree
Hide file tree
Showing 116 changed files with 958 additions and 69 deletions.
50 changes: 50 additions & 0 deletions .github/workflows/docker.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
name: Build Storybook Docker Image

on:
push:
branches:
- main
paths:
- "Dockerfile.storybook"
pull_request:
paths:
- "Dockerfile.storybook"
workflow_dispatch:

env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}/storybook-env

jobs:
storybook-build-and-push:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write

steps:
- uses: actions/checkout@v4

- uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=sha,format=long
type=ref,event=branch
type=ref,event=pr
type=raw,value=latest,enable={{is_default_branch}}
- uses: docker/build-push-action@v5
with:
context: .
file: Dockerfile.storybook
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
231 changes: 224 additions & 7 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,18 +71,65 @@ jobs:
files: coverage/lcov.info

storybook:
runs-on: ubuntu-latest
runs-on: ubuntu-22.04
container:
image: mcr.microsoft.com/playwright:v1.48.0
permissions:
contents: "read"
id-token: "write"
pull-requests: "write"
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4

# Install Rust using rustup
- name: Install Rust
run: |
apt-get update && apt-get install -y curl build-essential
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain ${{ env.RUST_VERSION }}
echo "$HOME/.cargo/bin" >> $GITHUB_PATH
# Install wasm-pack
- name: Install wasm-pack
run: |
curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
- uses: dorny/paths-filter@v3
id: changes
with:
filters: |
ui:
- 'packages/ui-next/**'
- 'packages/keychain/**'
- '**/package.json'
- '**/pnpm-lock.yaml'
- if: steps.changes.outputs.ui == 'true'
uses: actions/setup-node@v4
with:
node-version: 20.x
- uses: actions/cache@v4

- if: steps.changes.outputs.ui == 'true'
uses: actions/cache@v4
with:
path: ~/.pnpm-store
key: ${{ runner.os }}-pnpm-${{ hashFiles('**/pnpm-lock.yaml') }}
path: |
~/.pnpm-store
**/node_modules
key:
${{ runner.os }}-storybook-${{ hashFiles('**/pnpm-lock.yaml') }}-${{
github.sha }}
restore-keys: |
${{ runner.os }}-pnpm-
${{ runner.os }}-storybook-${{ hashFiles('**/pnpm-lock.yaml') }}-
${{ runner.os }}-storybook-
- name: Setup environment
run: |
# Set consistent environment variables
echo "CI=true" >> $GITHUB_ENV
echo "TZ=UTC" >> $GITHUB_ENV
# Set consistent screen resolution
Xvfb :99 -screen 0 1280x1024x24 &
echo "DISPLAY=:99" >> $GITHUB_ENV
- run: corepack enable pnpm

Expand All @@ -91,6 +138,176 @@ jobs:
with:
run_install: false

# Install Playwright dependencies
- name: Install Playwright
run: |
pnpm exec playwright install --with-deps chromium
- run: pnpm install --frozen-lockfile
- run: pnpm keychain exec playwright install

# Run regular storybook tests first to detect diffs
- run: pnpm test:storybook
id: test-storybook
continue-on-error: true

# Check for visual differences and collect info
- name: Check for visual differences
id: check-diffs
if: always() # Run even if previous step failed
run: |
# Configure git safety
git config --global --add safe.directory '*'
# Fetch the base branch first
git fetch origin ${{ github.base_ref }}
touch diff_info.txt
# Function to check diffs and PR snapshot changes
check_snapshots() {
local pkg=$1
local dir=$2
# Check diff output directory
if [ -d "${dir}/__diff_output__" ]; then
find "${dir}/__diff_output__" -name "*.png" -type f | while read -r file; do
echo "${pkg}:${file}:diff" >> diff_info.txt
done
fi
# Check for snapshot changes in the PR
git diff --name-only origin/${{ github.base_ref }} | grep "^${dir}/.*\.png$" | while read -r file; do
if [ -f "$file" ]; then
echo "${pkg}:${file}:update" >> diff_info.txt
fi
done
}
# Check both packages
check_snapshots "keychain" "packages/keychain/__image_snapshots__"
check_snapshots "ui-next" "packages/ui-next/__image_snapshots__"
# Set environment variables
if [ -s diff_info.txt ]; then
echo "snapshot_failed=true" >> "$GITHUB_ENV"
echo "diff_files<<EOF" >> "$GITHUB_ENV"
cat diff_info.txt >> "$GITHUB_ENV"
echo "EOF" >> "$GITHUB_ENV"
else
echo "snapshot_failed=false" >> "$GITHUB_ENV"
fi
# Upload diff images to GCP
- uses: "google-github-actions/auth@v2"
with:
project_id: c7e-prod
workload_identity_provider: "projects/276773611885/locations/global/workloadIdentityPools/github/providers/controller-repo"

- name: Debug directory structure
run: |
echo "Checking directories..."
ls -la packages/ui-next/__image_snapshots__ || echo "ui-next snapshots dir not found"
ls -la packages/keychain/__image_snapshots__ || echo "keychain snapshots dir not found"
echo "Current working directory: $PWD"
find . -name "__diff_output__"
- uses: "google-github-actions/upload-cloud-storage@v2"
if: env.snapshot_failed == 'true'
id: upload-diffs
with:
path: "packages"
destination:
"c7e-prod-static/gh/visual-diffs/${{ github.repository }}/${{
github.event.pull_request.number }}"
glob: "*/__image_snapshots__/__diff_output__/**"
parent: false

# Create PR comment with results
- uses: actions/github-script@v7
if: always() && github.event_name == 'pull_request'
with:
script: |
const fs = require('fs');
let comment = '### 🎨 Visual Regression Test Results\n\n';
const testStatus = process.env.snapshot_failed === 'true'
? '❌ Visual differences detected'
: '✅ No visual changes detected';
comment += `${testStatus}\n\n`;
if (process.env.snapshot_failed === 'true') {
const diffFiles = process.env.diff_files.split('\n').filter(Boolean);
// Group changes by package and type
const changes = {
'ui-next': { diffs: [], updates: [] },
'keychain': { diffs: [], updates: [] }
};
// Process all files
diffFiles.forEach(diff => {
const [pkg, path, type] = diff.split(':');
if (path && fs.existsSync(path)) {
const fileName = path.split('/').pop();
const storyName = fileName.replace('.png', '').replace('-diff', '');
const imageUrl = `https://static.cartridge.gg/gh/visual-diffs/${process.env.GITHUB_REPOSITORY}/${context.payload.pull_request.number}/${pkg}/__image_snapshots__/__diff_output__/${fileName}`;
if (type === 'diff') {
changes[pkg].diffs.push({ storyName, imageUrl });
} else {
changes[pkg].updates.push({ storyName, imageUrl });
}
}
});
// Generate comment sections for each package
for (const [pkg, pkgChanges] of Object.entries(changes)) {
if (pkgChanges.diffs.length > 0 || pkgChanges.updates.length > 0) {
comment += `\n#### 📦 ${pkg}\n\n`;
if (pkgChanges.diffs.length > 0) {
comment += '##### ⚠️ Visual Differences Detected\n\n';
comment += 'The following components have visual differences that need review:\n\n';
pkgChanges.diffs.forEach(({ storyName, imageUrl }) => {
comment += `<details><summary><code>${storyName}</code></summary>\n\n`;
comment += `![${storyName}](${imageUrl})\n\n`;
comment += '</details>\n\n';
});
}
if (pkgChanges.updates.length > 0) {
comment += '##### 🔄 Snapshot Updates in PR\n\n';
comment += 'The following snapshots have been updated in this PR:\n\n';
pkgChanges.updates.forEach(({ storyName, imageUrl }) => {
comment += `<details><summary><code>${storyName}</code></summary>\n\n`;
comment += `![${storyName}](${imageUrl})\n\n`;
comment += '</details>\n\n';
});
}
}
}
comment += '\n---\n';
if (Object.values(changes).some(pkg => pkg.diffs.length > 0)) {
comment += '⚠️ **Action Required**: Please review the visual differences and:\n';
comment += '1. Update the snapshots locally if the changes are intended (`scripts/update-storybook-snapshot.sh`)\n';
comment += '2. Fix the components if the changes are unintended\n\n';
}
}
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: comment
});
# Fail the job if there were visual differences
- name: Check for failures
if: always()
run: |
if [[ "${{ env.snapshot_failed }}" == "true" ]]; then
echo "Visual differences detected in Storybook tests"
exit 1
fi
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ node_modules/
*.tsbuildinfo

.turbo
.pnpm-store

**/.pnpm-debug.log*

Expand Down
33 changes: 33 additions & 0 deletions Dockerfile.storybook
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
FROM mcr.microsoft.com/playwright:v1.49.1

# Set environment variables
ENV CI=true \
TZ=UTC \
DISPLAY=:99

# Install additional dependencies
RUN apt-get update && \
apt-get install -y \
curl \
build-essential \
jq \
&& rm -rf /var/lib/apt/lists/*

# Install Rust and wasm-pack
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y && \
. $HOME/.cargo/env && \
curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh

# Add cargo to PATH
ENV PATH="/root/.cargo/bin:${PATH}"

# Install pnpm
RUN corepack enable pnpm

# Setup display with consistent resolution
RUN Xvfb :99 -screen 0 1280x1024x24 2>/dev/null &

WORKDIR /app

# Default command that can be overridden
CMD ["bash"]
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,20 @@
"example:svelte": "pnpm --filter @cartridge/controller-example-svelte",
"test": "pnpm keychain test",
"test:ci": "pnpm keychain test:ci",
"test:storybook": "pnpm turbo build:deps test:storybook"
"test:storybook": "pnpm turbo build:deps test:storybook",
"test:storybook:update": "pnpm turbo build:deps test:storybook:update"
},
"dependencies": {
"@cartridge/presets": "github:cartridge-gg/presets#b0def0f"
},
"devDependencies": {
"@changesets/changelog-github": "^0.4.2",
"@changesets/cli": "^2.20.0",
"playwright": "^1.49.1",
"prettier": "^2.7.1",
"tsup": "^8.0.1",
"turbo": "^2.0.12",
"vercel": "^37.4.2",
"@types/react": "^18.3.12"
}
}
}
Loading

0 comments on commit 3e70d68

Please sign in to comment.