Perhaps a slightly better approach #108
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 | |
| on: | |
| push: | |
| branches: ["master"] | |
| workflow_dispatch: | |
| env: | |
| INSTANCE: 'Writerside/1' | |
| DOCKER_VERSION: '2025.04.8412' | |
| CF_ACC_ID: ${{ secrets.CF_ACC_ID }} | |
| CF_API_TOK: ${{ secrets.CF_API_TOK }} | |
| jobs: | |
| build: | |
| name: Build | |
| runs-on: ubuntu-latest | |
| outputs: | |
| zip_path: ${{ steps.discover.outputs.zip_path }} | |
| build_dir: ${{ steps.discover.outputs.build_dir }} | |
| algolia_zip: ${{ steps.discover.outputs.algolia_zip }} | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - name: Writerside Build | |
| uses: JetBrains/writerside-github-action@v4 | |
| with: | |
| instance: ${{ env.INSTANCE }} | |
| docker-version: ${{ env.DOCKER_VERSION }} | |
| - name: Discover Build Artifacts | |
| id: discover | |
| run: | | |
| echo "Workspace contents:" | |
| find . -type f -maxdepth 3 | sed 's/^/ /' | |
| ZIP_PATH=$(find artifacts -type f -name '*.zip' ! -name 'algolia-indexes-*.zip' | head -n1) | |
| ALG_ZIP=$(find artifacts -type f -name 'algolia-indexes-*.zip' | head -n1) | |
| if [ -z "$ZIP_PATH" ]; then | |
| echo "❌ No ZIP found under artifacts/—check Writerside action output!" | |
| exit 1 | |
| fi | |
| BUILD_DIR="${ZIP_PATH%.zip}" | |
| echo "Found ZIP: $ZIP_PATH" | |
| echo "Derived build_dir: $BUILD_DIR" | |
| echo "zip_path=$ZIP_PATH" >> "$GITHUB_OUTPUT" | |
| echo "build_dir=$BUILD_DIR" >> "$GITHUB_OUTPUT" | |
| echo "algolia_zip=$ALG_ZIP" >> "$GITHUB_OUTPUT" | |
| - name: Upload Build | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: zip | |
| path: ${{ steps.discover.outputs.zip_path }} | |
| - name: Upload Algolia | |
| if: steps.discover.outputs.algolia_zip != '' | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: algolia-zip | |
| path: ${{ steps.discover.outputs.algolia_zip }} | |
| deploy-cf: | |
| name: Deploy for CloudFlare Pages | |
| needs: build | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - name: Download Build | |
| uses: actions/download-artifact@v5 | |
| with: | |
| name: zip | |
| path: . | |
| - name: Debug - List Everything | |
| run: | | |
| echo "Working directory: $(pwd)" | |
| echo "Contents of repo root:" | |
| ls -R . | sed 's/^/ /' | |
| - name: Unzip Writerside Output | |
| run: | | |
| ZIP_FILE="$(basename '${{ needs.build.outputs.zip_path }}')" | |
| DEST="${{ needs.build.outputs.build_dir }}" | |
| echo "Unzipping $ZIP_FILE into $DEST" | |
| mkdir -p "$DEST" | |
| unzip "$ZIP_FILE" -d "$DEST" | |
| - name: Place verification files | |
| run: | | |
| GOOGLE_SRC=$(find .github -maxdepth 1 -type f -name 'google*.html' | head -n1) | |
| DISCORD_SRC=".github/discord" | |
| DEST="${{ needs.build.outputs.build_dir }}" | |
| echo "Deploy build dir: $DEST" | |
| if [ -z "$GOOGLE_SRC" ]; then | |
| echo "Error: no google*.html found under .github" | |
| exit 1 | |
| fi | |
| # Ensure destination exists and copy Google file to site root | |
| mkdir -p "$DEST" | |
| cp "$GOOGLE_SRC" "$DEST/$(basename "$GOOGLE_SRC")" | |
| echo "Copied $GOOGLE_SRC -> $DEST/$(basename "$GOOGLE_SRC")" | |
| # Ensure .well-known exists and copy Discord token there | |
| if [ ! -f "$DISCORD_SRC" ]; then | |
| echo "Error: $DISCORD_SRC not found in repo" | |
| exit 1 | |
| fi | |
| mkdir -p "$DEST/.well-known" | |
| cp "$DISCORD_SRC" "$DEST/.well-known/discord" | |
| echo "Copied $DISCORD_SRC -> $DEST/.well-known/discord" | |
| - name: Deploy to CF | |
| uses: cloudflare/wrangler-action@v3 | |
| with: | |
| apiToken: ${{ env.CF_API_TOK }} | |
| accountId: ${{ env.CF_ACC_ID }} | |
| command: pages deploy --project-name=mmkb | |
| gitHubToken: ${{ secrets.GITHUB_TOKEN }} | |
| deploy-gh: | |
| name: Deploy to GitHub Pages | |
| needs: build | |
| runs-on: ubuntu-latest | |
| permissions: | |
| pages: write | |
| id-token: write | |
| environment: | |
| name: github-pages | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - name: Download Build | |
| uses: actions/download-artifact@v5 | |
| with: | |
| name: zip | |
| path: ./site | |
| - name: Unzip Writerside Output | |
| run: | | |
| ZIP_FILE="$(basename '${{ needs.build.outputs.zip_path }}')" | |
| DEST_DIR="./site/${{ needs.build.outputs.build_dir }}" | |
| echo "Unzipping $ZIP_FILE into $DEST_DIR" | |
| mkdir -p "$DEST_DIR" | |
| unzip "./site/$ZIP_FILE" -d "$DEST_DIR" | |
| - name: Upload Pages Artifact | |
| uses: actions/upload-pages-artifact@v4 | |
| with: | |
| name: github-pages | |
| path: ./site/${{ needs.build.outputs.build_dir }} | |
| - name: Deploy to GH | |
| uses: actions/deploy-pages@v4 | |
| with: | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| deploy-algolia: | |
| name: Deploy Records to Algolia | |
| needs: build | |
| if: needs.build.outputs.algolia_zip != '' | |
| runs-on: ubuntu-latest | |
| env: | |
| ALGOLIA_APPLICATION_ID: ${{ secrets.ALG_APP_ID }} | |
| ALGOLIA_ADMIN_API_KEY: ${{ secrets.ALG_ADM_API_KEY }} | |
| ALGOLIA_INDEX_NAME: ${{ secrets.ALG_INDEX_NAME }} | |
| PRODUCT: '1' | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - name: Download Algolia Indexes | |
| uses: actions/download-artifact@v5 | |
| with: | |
| name: algolia-zip | |
| path: ./algolia | |
| - name: Unzip Algolia Data | |
| run: | | |
| ZIP_NAME="$(basename '${{ needs.build.outputs.algolia_zip }}')" | |
| echo "Unzipping ./algolia/$ZIP_NAME into ./algolia" | |
| unzip "./algolia/$ZIP_NAME" -d ./algolia | |
| - name: Patch Algolia JSON files | |
| run: | | |
| set -euo pipefail | |
| cd algolia | |
| processed=0 | |
| for f in *.json; do | |
| [ -e "$f" ] || continue | |
| if jq -e 'type == "array"' "$f" >/dev/null 2>&1; then | |
| jq 'map(if (.product == "") then . + {product:"-1"} else . end)' "$f" > "$f.tmp" | |
| mv "$f.tmp" "$f" | |
| elif jq -e 'has("records") and (.records | type == "array")' "$f" >/dev/null 2>&1; then | |
| jq '.records = (.records | map(if (.product == "") then . + {product:"-1"} else . end))' "$f" > "$f.tmp" | |
| mv "$f.tmp" "$f" | |
| elif jq -e 'type == "object"' "$f" >/dev/null 2>&1; then | |
| jq 'if (.product == "") then . + {product:"-1"} else . end' "$f" > "$f.tmp" | |
| mv "$f.tmp" "$f" | |
| else | |
| tmp="$(mktemp)" | |
| while IFS= read -r line || [ -n "$line" ]; do | |
| trimmed="$(echo "$line" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')" | |
| if [ -z "$trimmed" ]; then | |
| echo "" >> "$tmp" | |
| continue | |
| fi | |
| if echo "$trimmed" | jq -e '.' >/dev/null 2>&1; then | |
| echo "$trimmed" | jq -c 'if (.product == "") then . + {product:"-1"} else . end' >> "$tmp" | |
| else | |
| echo "$line" >> "$tmp" | |
| fi | |
| done < "$f" | |
| mv "$tmp" "$f" | |
| fi | |
| processed=$((processed + 1)) | |
| done | |
| echo "Files parsed: $processed" | |
| - name: Setup Algolia CLI | |
| uses: algolia/setup-algolia-cli@master | |
| - name: Publish Algolia Indexes | |
| run: | | |
| cd algolia | |
| for file in *.json; do | |
| echo "Importing $file into $ALGOLIA_INDEX_NAME" | |
| algolia objects import "$ALGOLIA_INDEX_NAME" -F "$file" | |
| done |