chore: bump strings.json version #159
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Build Skins | |
| on: | |
| push: | |
| branches: [main, master] | |
| paths: | |
| - 'skins-pro/**' | |
| - 'screenshots/**' | |
| workflow_dispatch: | |
| permissions: | |
| contents: write | |
| concurrency: | |
| group: skins-build | |
| cancel-in-progress: false | |
| jobs: | |
| build-skins: | |
| name: Build and publish skins | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v7 | |
| with: | |
| fetch-depth: 2 | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Detect changed skins | |
| id: skins | |
| run: | | |
| HAS_PARENT=$(git rev-parse --verify HEAD~1 2>/dev/null && echo 1 || echo 0) | |
| # Changes from diff (for new pushes) | |
| SKIN_TOUCHED="" | |
| SCREENSHOT_TOUCHED="" | |
| if [ "$HAS_PARENT" = 1 ]; then | |
| SKIN_TOUCHED=$(git diff --name-only HEAD~1 HEAD -- skins-pro/ 2>/dev/null \ | |
| | grep '^skins-pro/' | cut -d/ -f2 | sort -u \ | |
| | grep -v '^\.gitkeep$' || true) | |
| SCREENSHOT_TOUCHED=$(git diff --name-only HEAD~1 HEAD -- screenshots/ 2>/dev/null \ | |
| | grep '^screenshots/' | cut -d/ -f2 | sed 's/\.[^.]*$//' | sort -u \ | |
| | grep -v '^thumbnails$' | grep -v '^registry$' | grep -v '^\.gitkeep$' || true) | |
| fi | |
| # Scan for residual assets on master (cleanup leftover from failed prior runs) | |
| SKIN_PRESENT=$(find skins-pro/ -maxdepth 1 -mindepth 1 -type d 2>/dev/null | cut -d/ -f2 | sort -u || true) | |
| SCREENSHOT_PRESENT=$(find screenshots/ -maxdepth 1 -type f ! -name '.gitkeep' 2>/dev/null \ | |
| | xargs -n1 basename 2>/dev/null | sed 's/\.[^.]*$//' | sort -u \ | |
| | grep -v '^thumbnails$' | grep -v '^registry$' || true) | |
| CHANGED="" | |
| DELETED="" | |
| for skin in $(printf '%s\n%s\n%s\n%s\n' "$SKIN_TOUCHED" "$SCREENSHOT_TOUCHED" "$SKIN_PRESENT" "$SCREENSHOT_PRESENT" | grep -v '^$' | sort -u); do | |
| if [ -d "skins-pro/$skin" ]; then | |
| CHANGED="$CHANGED $skin" | |
| else | |
| DELETED="$DELETED $skin" | |
| fi | |
| done | |
| CHANGED=$(echo "$CHANGED" | xargs || true) | |
| DELETED=$(echo "$DELETED" | xargs || true) | |
| echo "target=$CHANGED" >> "$GITHUB_OUTPUT" | |
| echo "deleted=$DELETED" >> "$GITHUB_OUTPUT" | |
| echo "Changed skins: ${CHANGED:-<none>}" | |
| echo "Deleted themes: ${DELETED:-<none>}" | |
| - name: Prepare asset worktrees | |
| run: | | |
| for branch in skin-assets screenshot-assets; do | |
| if git fetch origin "$branch" --depth=1 2>/dev/null; then | |
| git worktree add "$branch" "origin/$branch" | |
| else | |
| git worktree add --detach "$branch" | |
| git -C "$branch" checkout --orphan "$branch" | |
| git -C "$branch" rm -rf . 2>/dev/null || true | |
| fi | |
| done | |
| - name: Move source files into full asset worktrees | |
| run: | | |
| TARGET="${{ steps.skins.outputs.target }}" | |
| if [ -z "$TARGET" ]; then | |
| exit 0 | |
| fi | |
| for skin in $TARGET; do | |
| if [ -d "skins-pro/$skin" ]; then | |
| mkdir -p "skin-assets/$skin" | |
| cp -r "skins-pro/$skin/." "skin-assets/$skin/" | |
| rm -rf "skins-pro/$skin" | |
| fi | |
| for ext in png jpg jpeg webp bmp gif mp4; do | |
| if [ -f "screenshots/$skin.$ext" ]; then | |
| cp "screenshots/$skin.$ext" "screenshot-assets/$skin.$ext" | |
| rm "screenshots/$skin.$ext" | |
| fi | |
| done | |
| done | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v7 | |
| with: | |
| node-version: '24' | |
| cache: npm | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Build skins | |
| run: | | |
| TARGET="${{ steps.skins.outputs.target }}" | |
| if [ -n "$TARGET" ]; then | |
| echo "Incremental build for: $TARGET" | |
| npm run build -- $TARGET | |
| else | |
| echo "Full build" | |
| npm run build | |
| fi | |
| - name: Sync to Cloudflare R2 | |
| env: | |
| AWS_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }} | |
| AWS_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }} | |
| AWS_DEFAULT_REGION: auto | |
| R2_ACCOUNT_ID: ${{ secrets.R2_ACCOUNT_ID }} | |
| run: | | |
| ENDPOINT="https://${R2_ACCOUNT_ID}.r2.cloudflarestorage.com" | |
| TARGET="${{ steps.skins.outputs.target }}" | |
| DELETED="${{ steps.skins.outputs.deleted }}" | |
| if [ -z "$TARGET" ] && [ -z "$DELETED" ]; then | |
| echo "Full sync" | |
| aws s3 sync store/ "s3://skinspro/store/" --endpoint-url "$ENDPOINT" | |
| aws s3 sync screenshot-assets/ "s3://skinspro/screenshots/" --endpoint-url "$ENDPOINT" --exclude "thumbnails/*" | |
| aws s3 sync screenshot-assets/thumbnails/ "s3://skinspro/screenshots/thumbnails/" --endpoint-url "$ENDPOINT" | |
| aws s3 cp screenshot-assets/registry.json "s3://skinspro/screenshots/registry.json" --endpoint-url "$ENDPOINT" | |
| else | |
| echo "Incremental sync for: target=$TARGET deleted=$DELETED" | |
| for skin in $TARGET; do | |
| [ -f "store/${skin}.zip" ] && aws s3 cp "store/${skin}.zip" "s3://skinspro/store/${skin}.zip" --endpoint-url "$ENDPOINT" | |
| [ -f "screenshot-assets/thumbnails/${skin}.jpg" ] && aws s3 cp "screenshot-assets/thumbnails/${skin}.jpg" "s3://skinspro/screenshots/thumbnails/${skin}.jpg" --endpoint-url "$ENDPOINT" | |
| for ext in png jpg jpeg webp bmp gif mp4; do | |
| [ -f "screenshot-assets/${skin}.${ext}" ] && aws s3 cp "screenshot-assets/${skin}.${ext}" "s3://skinspro/screenshots/${skin}.${ext}" --endpoint-url "$ENDPOINT" | |
| done | |
| done | |
| [ -f "screenshot-assets/registry.json" ] && aws s3 cp "screenshot-assets/registry.json" "s3://skinspro/screenshots/registry.json" --endpoint-url "$ENDPOINT" | |
| fi | |
| - name: Push new skin sources to skin-assets branch | |
| run: | | |
| TARGET="${{ steps.skins.outputs.target }}" | |
| if [ -z "$TARGET" ]; then | |
| echo "No new skins to publish" | |
| exit 0 | |
| fi | |
| cd skin-assets | |
| for skin in $TARGET; do | |
| if [ -d "${{ github.workspace }}/skins-pro/$skin" ]; then | |
| rm -rf "$skin" | |
| cp -r "${{ github.workspace }}/skins-pro/$skin" "$skin" | |
| echo "Copied skin source: $skin" | |
| fi | |
| done | |
| git add . | |
| if git diff --cached --quiet; then | |
| echo "No changes to skin-assets" | |
| else | |
| git -c user.name="github-actions[bot]" -c user.email="github-actions[bot]@users.noreply.github.com" \ | |
| commit -m "Add skin sources: $TARGET [skip ci]" | |
| git push origin HEAD:skin-assets | |
| fi | |
| - name: Push new screenshots to screenshot-assets branch | |
| run: | | |
| TARGET="${{ steps.skins.outputs.target }}" | |
| if [ -z "$TARGET" ]; then | |
| echo "No new screenshots to publish" | |
| exit 0 | |
| fi | |
| cd screenshot-assets | |
| # Copy new screenshots from master workspace (build already wrote | |
| # thumbnails/registry.json directly here since this is the worktree) | |
| for skin in $TARGET; do | |
| for ext in png jpg jpeg webp bmp gif mp4; do | |
| if [ -f "${{ github.workspace }}/screenshots/$skin.$ext" ]; then | |
| cp "${{ github.workspace }}/screenshots/$skin.$ext" "$skin.$ext" | |
| echo "Copied screenshot: $skin.$ext" | |
| fi | |
| done | |
| done | |
| git add . | |
| if git diff --cached --quiet; then | |
| echo "No changes to screenshot-assets" | |
| else | |
| git -c user.name="github-actions[bot]" -c user.email="github-actions[bot]@users.noreply.github.com" \ | |
| commit -m "Add screenshots: $TARGET [skip ci]" | |
| git push origin HEAD:screenshot-assets | |
| fi | |
| - name: Clean moved assets from master | |
| run: | | |
| TARGET="${{ steps.skins.outputs.target }}" | |
| if [ -z "$TARGET" ]; then | |
| echo "No cleanup needed" | |
| exit 0 | |
| fi | |
| cd "${{ github.workspace }}" | |
| for skin in $TARGET; do | |
| if git rm -r --ignore-unmatch "skins-pro/$skin" >/dev/null 2>&1; then | |
| echo "Removed skins-pro/$skin from master" | |
| fi | |
| for ext in png jpg jpeg webp bmp gif mp4; do | |
| if git rm --ignore-unmatch "screenshots/$skin.$ext" >/dev/null 2>&1; then | |
| echo "Removed screenshots/$skin.$ext from master" | |
| fi | |
| done | |
| done | |
| mkdir -p skins-pro screenshots | |
| [ -f "skins-pro/.gitkeep" ] || touch skins-pro/.gitkeep | |
| [ -f "screenshots/.gitkeep" ] || touch screenshots/.gitkeep | |
| git add skins-pro/.gitkeep screenshots/.gitkeep 2>/dev/null || true | |
| if git diff --cached --quiet; then | |
| echo "Nothing to clean" | |
| else | |
| git -c user.name="github-actions[bot]" -c user.email="github-actions[bot]@users.noreply.github.com" \ | |
| commit -m "chore: move $TARGET assets to asset branches [skip ci]" | |
| git push origin HEAD:master | |
| fi | |
| - name: Clean up worktrees | |
| if: always() | |
| run: | | |
| git worktree remove --force skin-assets 2>/dev/null || true | |
| git worktree remove --force screenshot-assets 2>/dev/null || true |