Cloud Save Http3VsHttp2WhatChangedForDevelopers #32
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 Blogs Metadata JSON | |
| on: | |
| push: | |
| paths: | |
| - "Logs/**/*.json" # Triggers when json files in 'blogs' folder change | |
| workflow_dispatch: # Allows manual trigger from Actions tab | |
| permissions: | |
| contents: write | |
| jobs: | |
| build-metadata: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout main | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 # Required for git history to determine the date if needed | |
| - name: Generate JSON metadata | |
| run: | | |
| node <<'EOF' | |
| const fs = require("fs"); | |
| const path = require("path"); | |
| const { execSync } = require("child_process"); | |
| // CONFIGURATION | |
| const ROOT = "Logs"; // Target Directory | |
| const OUT = "blogs.json"; | |
| if (!fs.existsSync(ROOT)) { | |
| console.error(`Error: Directory "${ROOT}" not found.`); | |
| process.exit(1); | |
| } | |
| // Recursive directory walk | |
| function walk(dir) { | |
| return fs.readdirSync(dir).flatMap(f => { | |
| const p = path.join(dir, f); | |
| return fs.statSync(p).isDirectory() ? walk(p) : p; | |
| }).filter(f => f.toLowerCase().endsWith('.json')); | |
| } | |
| // Helper to get Git Date if 'Date' property is missing in JSON | |
| function getGitDate(file) { | |
| try { | |
| const res = execSync(`git log -1 --format=%aI -- "${file}"`).toString().trim(); | |
| return res ? res.slice(0, 10) : new Date().toISOString().slice(0, 10); | |
| } catch { | |
| return new Date().toISOString().slice(0, 10); | |
| } | |
| } | |
| const files = walk(ROOT); | |
| const blogsData =[]; | |
| console.log(`Processing ${files.length} JSON files...`); | |
| for (const file of files) { | |
| try { | |
| const content = fs.readFileSync(file, "utf8"); | |
| const json = JSON.parse(content); | |
| const fileName = path.basename(file); // Original Name of the JSON file | |
| const baseName = path.basename(file, path.extname(file)); // File name without extension | |
| // Safely extract categories | |
| const categoriesArray = Array.isArray(json.Categories) ? json.Categories :[]; | |
| const tagsArray = Array.isArray(json.Tags) ? json.Tags :[]; | |
| // Build Output Structure (One line per attribute as requested) | |
| blogsData.push({ | |
| Article: json.Id || baseName, | |
| Name: json.Title || baseName, | |
| Author: json.Author || "MyWrite", | |
| Desc: json.Desc || "", | |
| Img: json.Img || "", | |
| Url: fileName, | |
| Date: json.Date || getGitDate(file), | |
| Cat: categoriesArray, | |
| Tags: tagsArray, | |
| Status: json.Status || "Un" | |
| }); | |
| } catch (err) { | |
| console.error(`Skipping invalid JSON file: ${file} - ${err.message}`); | |
| } | |
| } | |
| // Sort descending by Date | |
| blogsData.sort((a, b) => new Date(b.Date) - new Date(a.Date)); | |
| const finalContent = JSON.stringify(blogsData, null, 2); | |
| fs.writeFileSync(OUT, finalContent); | |
| console.log(`Successfully generated ${OUT} with ${blogsData.length} entries.`); | |
| EOF | |
| - name: Deploy to Output Branch | |
| run: | | |
| cp blogs.json /tmp/blogs.json | |
| git config user.name "github-actions[bot]" | |
| git config user.email "github-actions[bot]@users.noreply.github.com" | |
| # Check and switch to output branch | |
| git fetch origin | |
| if git show-ref --verify --quiet refs/remotes/origin/output; then | |
| git checkout -f output | |
| git reset --hard origin/output | |
| else | |
| git checkout --orphan output | |
| fi | |
| # Remove all previous files in branch and copy over the new JSON | |
| git rm -rf . || true | |
| cp /tmp/blogs.json blogs.json | |
| git add blogs.json | |
| git commit -m "chore: update blogs JSON metadata [skip ci]" || echo "No changes to commit" | |
| git push origin output --force |