You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@casbin.apache.org by hs...@apache.org on 2026/08/20 17:02:24 UTC

(casbin-website) branch master updated: feat: auto-generate download page release info

This is an automated email from the ASF dual-hosted git repository.

hsluoyz pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/casbin-website.git


The following commit(s) were added to refs/heads/master by this push:
     new 45040fa25 feat: auto-generate download page release info
45040fa25 is described below

commit 45040fa2504de5521e0e4b90926ee76565c3219d
Author: Yang Luo <hs...@gmail.com>
AuthorDate: Fri Aug 21 01:02:13 2026 +0800

    feat: auto-generate download page release info
---
 .github/workflows/master.yml               |   3 +
 .github/workflows/pr_ci.yml                |   3 +
 docs/Download.mdx                          |  26 ++++++++
 docusaurus.config.js                       |   9 +++
 package.json                               |   1 +
 scripts/generate-asf-release.js            | 103 +++++++++++++++++++++++++++++
 sidebars.js                                |   2 +-
 src/components/AsfReleaseDownload/index.js |  33 +++++++++
 src/data/asf-release.json                  |   8 +++
 9 files changed, 187 insertions(+), 1 deletion(-)

diff --git a/.github/workflows/master.yml b/.github/workflows/master.yml
index ad7bbf4bb..6bf4c63c6 100644
--- a/.github/workflows/master.yml
+++ b/.github/workflows/master.yml
@@ -54,6 +54,9 @@ jobs:
       - name: Generate homepage release
         run: yarn generate:homepage-release
 
+      - name: Generate ASF release
+        run: yarn generate:asf-release
+
       - name: Build
         run: yarn build
 
diff --git a/.github/workflows/pr_ci.yml b/.github/workflows/pr_ci.yml
index 9a99b4611..7fc0cd3da 100644
--- a/.github/workflows/pr_ci.yml
+++ b/.github/workflows/pr_ci.yml
@@ -28,5 +28,8 @@ jobs:
       - name: Generate homepage release
         run: yarn generate:homepage-release
 
+      - name: Generate ASF release
+        run: yarn generate:asf-release
+
       - name: Build website
         run: yarn build --locale en
diff --git a/docs/Download.mdx b/docs/Download.mdx
new file mode 100644
index 000000000..bc8f89db4
--- /dev/null
+++ b/docs/Download.mdx
@@ -0,0 +1,26 @@
+---
+id: download
+title: Download
+description: Download and verify Apache Casbin releases
+keywords: [Casbin, download, release, source release, PGP signature, SHA-512, verification]
+---
+
+```mdx-code-block
+import AsfReleaseDownload from "@site/src/components/AsfReleaseDownload";
+```
+
+The official Apache Casbin release is the source archive published by The Apache Software Foundation. For package-manager installation and first use, see [Get Started](/docs/get-started).
+
+## Latest release
+
+```mdx-code-block
+<AsfReleaseDownload />
+```
+
+## Verify your download
+
+Always verify the source archive with its SHA-512 checksum and PGP signature before use. The signing keys are in the KEYS file above, and [the ASF verification guide](https://www.apache.org/info/verification.html) explains how to check both.
+
+## Older releases
+
+Every Apache Casbin release stays available in [the ASF distribution archive](https://archive.apache.org/dist/incubator/casbin/). Only the latest release is supported.
diff --git a/docusaurus.config.js b/docusaurus.config.js
index bf35edb36..6184b6ccc 100644
--- a/docusaurus.config.js
+++ b/docusaurus.config.js
@@ -84,6 +84,11 @@ module.exports = {
             },
           ],
         },
+        {
+          to: "/docs/download",
+          label: "Download",
+          position: "left",
+        },
         {
           to: "/ecosystem",
           label: "Plugins",
@@ -183,6 +188,10 @@ module.exports = {
         {
           title: "Docs",
           items: [
+            {
+              label: "Download",
+              to: "/docs/download",
+            },
             {
               label: "Getting Started",
               to: "/docs/get-started",
diff --git a/package.json b/package.json
index 476481e5e..a53d84d13 100644
--- a/package.json
+++ b/package.json
@@ -7,6 +7,7 @@
     "docusaurus": "docusaurus",
     "generate:footer-stars": "node scripts/generate-footer-stars.js",
     "generate:homepage-release": "node scripts/generate-homepage-release.js",
+    "generate:asf-release": "node scripts/generate-asf-release.js",
     "start": "node scripts/start.js",
     "build": "docusaurus build",
     "swizzle": "docusaurus swizzle",
diff --git a/scripts/generate-asf-release.js b/scripts/generate-asf-release.js
new file mode 100644
index 000000000..2531e21c1
--- /dev/null
+++ b/scripts/generate-asf-release.js
@@ -0,0 +1,103 @@
+const path = require("path");
+const {readExistingJson, writeJson} = require("./github-data-utils");
+
+// Podling releases live under /incubator/; drop that segment once Casbin graduates.
+const distPath = "incubator/casbin";
+// Checksums, signatures and KEYS must come from the ASF distribution directory,
+// while the source archive itself must go through the closer.lua mirror script.
+// See https://infra.apache.org/release-download-pages.html
+const downloadsBase = `https://downloads.apache.org/${distPath}`;
+const mirrorBase = `https://www.apache.org/dyn/closer.lua/${distPath}`;
+
+const outputPath = path.join(__dirname, "..", "src", "data", "asf-release.json");
+const fallbackVersion = "3.11.0-incubating";
+
+function buildRelease(version, sourceFile) {
+  return {
+    generatedAt: new Date().toISOString(),
+    version,
+    sourceUrl: `${mirrorBase}/${version}/${sourceFile}`,
+    signatureUrl: `${downloadsBase}/${version}/${sourceFile}.asc`,
+    checksumUrl: `${downloadsBase}/${version}/${sourceFile}.sha512`,
+    keysUrl: `${downloadsBase}/KEYS`,
+  };
+}
+
+async function fetchListing(url) {
+  const response = await fetch(url, {
+    headers: {"User-Agent": "casbin-website-asf-release"},
+  });
+
+  if (!response.ok) {
+    const body = await response.text();
+    throw new Error(`Failed to fetch ASF release listing ${url}: ${response.status} ${body}`);
+  }
+
+  return response.text();
+}
+
+function parseHrefs(html) {
+  return [...html.matchAll(/href="([^"]+)"/gu)].map((match) => match[1]);
+}
+
+function compareVersions(left, right) {
+  const toParts = (version) => version.split("-")[0].split(".").map(Number);
+  const leftParts = toParts(left);
+  const rightParts = toParts(right);
+
+  for (let i = 0; i < Math.max(leftParts.length, rightParts.length); i += 1) {
+    const diff = (leftParts[i] ?? 0) - (rightParts[i] ?? 0);
+    if (diff !== 0) {
+      return diff;
+    }
+  }
+
+  return 0;
+}
+
+async function fetchLatestRelease() {
+  const versions = parseHrefs(await fetchListing(`${downloadsBase}/`))
+    .filter((href) => /^\d+\.\d+[^/]*\/$/u.test(href))
+    .map((href) => href.replace(/\/$/u, ""))
+    .sort(compareVersions);
+
+  const version = versions[versions.length - 1];
+  if (!version) {
+    throw new Error(`Found no release directory under ${downloadsBase}/`);
+  }
+
+  const sourceFile = parseHrefs(await fetchListing(`${downloadsBase}/${version}/`))
+    .map((href) => href.split("/").pop())
+    .find((file) => file.endsWith("-src.tar.gz"));
+
+  if (!sourceFile) {
+    throw new Error(`Found no source archive under ${downloadsBase}/${version}/`);
+  }
+
+  return buildRelease(version, sourceFile);
+}
+
+async function main() {
+  const existingRelease = readExistingJson(outputPath);
+
+  try {
+    writeJson(outputPath, await fetchLatestRelease());
+    process.stdout.write(`Updated ASF release at ${outputPath}\n`);
+  } catch (error) {
+    if (existingRelease?.version && existingRelease?.sourceUrl) {
+      process.stderr.write(`${error.message}\nUsing existing ASF release JSON.\n`);
+      return;
+    }
+
+    writeJson(
+      outputPath,
+      buildRelease(fallbackVersion, `apache-casbin-${fallbackVersion}-src.tar.gz`)
+    );
+    process.stderr.write(`${error.message}\nUsing fallback ASF release JSON.\n`);
+  }
+}
+
+main().catch((error) => {
+  process.stderr.write(`${error.stack || error}\n`);
+  process.exit(1);
+});
diff --git a/sidebars.js b/sidebars.js
index ed40816d1..7278a1668 100644
--- a/sidebars.js
+++ b/sidebars.js
@@ -16,7 +16,7 @@ module.exports = {
   // But you can create a sidebar manually
 
   docs: [
-    "downloads",
+    "download",
     {
       type: "category",
       label: "Basics",
diff --git a/src/components/AsfReleaseDownload/index.js b/src/components/AsfReleaseDownload/index.js
new file mode 100644
index 000000000..83b387ad3
--- /dev/null
+++ b/src/components/AsfReleaseDownload/index.js
@@ -0,0 +1,33 @@
+import React from "react";
+import Translate from "@docusaurus/Translate";
+import release from "@site/src/data/asf-release.json";
+
+// The release metadata is refreshed at build time by scripts/generate-asf-release.js,
+// so a new ASF release shows up here without editing the download page.
+export default function AsfReleaseDownload() {
+  return (
+    <ul>
+      <li>
+        <a href={release.sourceUrl}>
+          <Translate
+            values={{version: release.version}}
+          >
+            {"Apache Casbin {version} source release"}
+          </Translate>
+        </a>
+        {" ("}
+        <a href={release.signatureUrl}>
+          <Translate>PGP signature</Translate>
+        </a>
+        {", "}
+        <a href={release.checksumUrl}>SHA-512</a>
+        {")"}
+      </li>
+      <li>
+        <a href={release.keysUrl}>
+          <Translate>Release signing keys (KEYS)</Translate>
+        </a>
+      </li>
+    </ul>
+  );
+}
diff --git a/src/data/asf-release.json b/src/data/asf-release.json
new file mode 100644
index 000000000..ce521c198
--- /dev/null
+++ b/src/data/asf-release.json
@@ -0,0 +1,8 @@
+{
+  "generatedAt": "2026-08-20T16:55:02.560Z",
+  "version": "3.11.0-incubating",
+  "sourceUrl": "https://www.apache.org/dyn/closer.lua/incubator/casbin/3.11.0-incubating/apache-casbin-3.11.0-incubating-src.tar.gz",
+  "signatureUrl": "https://downloads.apache.org/incubator/casbin/3.11.0-incubating/apache-casbin-3.11.0-incubating-src.tar.gz.asc",
+  "checksumUrl": "https://downloads.apache.org/incubator/casbin/3.11.0-incubating/apache-casbin-3.11.0-incubating-src.tar.gz.sha512",
+  "keysUrl": "https://downloads.apache.org/incubator/casbin/KEYS"
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@casbin.apache.org
For additional commands, e-mail: commits-help@casbin.apache.org