diff --git a/.github/workflows/swarm-upload.yaml b/.github/workflows/swarm-upload.yaml new file mode 100644 index 00000000..478efd0b --- /dev/null +++ b/.github/workflows/swarm-upload.yaml @@ -0,0 +1,67 @@ +name: Swarm Upload + +on: + push: + branches: + - 'master' + +jobs: + deploy: + # GitHub-hosted is sufficient: the bee endpoint is publicly reachable and + # gated by PRIVATE_API_TOKEN, so this does not need the self-hosted runners + # (and a public repo should not be granted access to them). + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + with: + fetch-depth: 0 + + - uses: actions/setup-node@v6 + with: + node-version: '24' + # No-op for caching here (package.json declares no packageManager / + # devEngines field), but it also skips setup-node's `npm --version` + # probe, which is known to hang on the self-hosted runners if this + # job is ever moved there. + package-manager-cache: false + + - name: Build + run: | + npm ci + npm run build + + - name: Upload to Swarm + uses: ethersphere/swarm-actions/upload-dir@latest + id: upload + with: + dir: ./build + index-document: index.html + postage-batch-id: ${{ secrets.PRIVATE_POSTAGE_BATCH_ID }} + bee-url: ${{ secrets.PRIVATE_BEE_URL }} + timeout: 300000 + deferred: false + headers: | + authorization: ${{ secrets.PRIVATE_API_TOKEN }} + + - name: Setup feed + uses: ethersphere/swarm-actions/write-feed@latest + id: feed + with: + reference: ${{ steps.upload.outputs.reference }} + topic: "swarm-docs" + postage-batch-id: ${{ secrets.PRIVATE_POSTAGE_BATCH_ID }} + bee-url: ${{ secrets.PRIVATE_BEE_URL }} + signer: ${{ secrets.PRIVATE_SIGNER }} + headers: | + authorization: ${{ secrets.PRIVATE_API_TOKEN }} + + - uses: ethersphere/swarm-actions/reference-to-cid@v0 + id: cid + with: + reference: ${{ steps.feed.outputs.manifest }} + + - run: | + echo 'Chunk Reference: ${{ steps.upload.outputs.reference }}' + echo 'Feed Reference: ${{ steps.feed.outputs.reference }}' + echo 'Feed Manifest: ${{ steps.feed.outputs.manifest }}' + echo 'Feed Bzz.link: https://${{ steps.cid.outputs.cid }}.bzz.link' diff --git a/scripts/fetch-awesome-swarm.mjs b/scripts/fetch-awesome-swarm.mjs index fdf58f34..cacc5f6d 100644 --- a/scripts/fetch-awesome-swarm.mjs +++ b/scripts/fetch-awesome-swarm.mjs @@ -5,12 +5,12 @@ import { mkdir, writeFile } from 'node:fs/promises'; import { resolve, dirname } from 'node:path'; const SOURCE_URL = - 'https://raw.githubusercontent.com/ethersphere/awesome-swarm/refs/heads/master/README.md'; + 'https://raw.githubusercontent.com/ethersphere/awesome-swarm/refs/heads/main/README.md'; const OUT_PATH = resolve(process.cwd(), 'docs/references/awesome-list.mdx'); -const REPO_HTTP_BASE = 'https://github.com/ethersphere/awesome-swarm/blob/master/'; -const RAW_HTTP_BASE = 'https://raw.githubusercontent.com/ethersphere/awesome-swarm/master/'; +const REPO_HTTP_BASE = 'https://github.com/ethersphere/awesome-swarm/blob/main/'; +const RAW_HTTP_BASE = 'https://raw.githubusercontent.com/ethersphere/awesome-swarm/main/'; function normalizeNewlines(str) { return str.replace(/\r\n/g, '\n'); @@ -30,6 +30,30 @@ function rewriteRelativeLinks(md) { return md; } +// MDX (Docusaurus) requires void HTML elements to be self-closed. The upstream +// README embeds a raw inside an ; left as-is the build fails with +// "end-tag-mismatch". +function selfCloseVoidTags(md) { + return md.replace( + /<(img|br|hr|input|meta|source)\b([^>]*?)\s*\/?>/gi, + (_m, tag, attrs) => `<${tag}${attrs.replace(/\s+$/, '')} />` + ); +} + +// Relative paths inside raw HTML attributes are not covered by the markdown +// link rewriting above, so they would 404 once rendered on the docs site. +function rewriteHtmlAssetPaths(md) { + md = md.replace( + /(<[^>]*\ssrc=")(?!https?:|data:|#|\/)([^"]+)(")/gi, + (_m, pre, path, post) => `${pre}${RAW_HTTP_BASE}${path}${post}` + ); + md = md.replace( + /(<[^>]*\shref=")(?!https?:|mailto:|#|\/)([^"]+)(")/gi, + (_m, pre, path, post) => `${pre}${REPO_HTTP_BASE}${path}${post}` + ); + return md; +} + async function main() { const res = await fetch(SOURCE_URL); if (!res.ok) throw new Error(`Fetch failed: ${res.status} ${res.statusText}`); @@ -39,7 +63,7 @@ async function main() { // Optional: strip upstream H1 to avoid a second big title under our frontmatter title md = md.replace(/^# .*\n+/, ''); - md = rewriteRelativeLinks(md); + md = selfCloseVoidTags(rewriteHtmlAssetPaths(rewriteRelativeLinks(md))); const header = `--- title: Awesome Swarm