From b137a0e0e101e89923452842b1174449bf8de3d0 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Wed, 12 Aug 2026 20:03:29 +0000 Subject: [PATCH] Rebuild the site with Astro and Starlight (#496) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace [#307](https://gitea.com/gitea/docs/issues/307) Closes [#237](https://gitea.com/gitea/docs/issues/237) ## Summary Rebuilds docs.gitea.com with [Astro](https://astro.build) and [Starlight](https://starlight.astro.build), replacing Docusaurus. Every published url keeps working and no content file was moved: the site is a new rendering layer over the existing `docs/`, `versioned_docs/`, `i18n/`, `runner-docs/` and `static/swagger-*.json` trees. For the first time the API reference is part of the site rather than a Redoc bundle: all seven swagger documents are rendered into real pages, one per operation, so they are linkable, crawlable and searchable. ## Why - the Docusaurus build needs an 8 GB heap and about 2 minutes for 2478 pages; the Astro build produces 5751 pages, API reference included, in about 100 seconds - the API reference was a single client rendered Redoc page per version, absent from the site search and from search engines - sidebars, version lists and language lists were configured in three different places and drifted apart ## What is in here - **`packages/content-loader`** — the product × version × language matrix (`products.ts`) and an Astro content loader that reads the existing markdown trees directly. The matrix is the single source of truth: content loading, sidebars, the version and language pickers, the version banner, the search facets and the API schemas are all derived from it. - **Content compatibility** — frontmatter `slug`, `sidebar_position` and `sidebar_label` keep working, `_category_.json` still drives sidebar labels, order and the generated category pages, `@version@` style release variables are still substituted, `:::note` admonitions become Starlight asides and the 2778 relative `*.md` links are rewritten to urls while the site is built. - **API reference** — `starlight-openapi` renders the seven swagger documents. Operation urls are hyphenated (`/api/operations/list-admin-workflow-jobs/`), the sidebar shows the operations of the version being read with a coloured HTTP method badge, and the overview page links to one page per tag instead of repeating all 484 operations. - **Navigation** — a version picker that follows the reader to the same page in another version, a language picker that only offers the languages the current product is published in, and product links for Docs, API, Runner and Enterprise. - **Theme** — the light and dark palettes of about.gitea.com, mapped onto the Starlight variables. - **Search** — Pagefind by default; Algolia DocSearch takes over when `PUBLIC_DOCSEARCH_APP_ID` and `PUBLIC_DOCSEARCH_API_KEY` are set. Every page carries `docsearch:product`, `docsearch:version` and `docsearch:language` meta tags, so a search stays inside what is being read. `cloudflare/docsearch-crawler.json` holds the crawler configuration. ## Bugs fixed along the way - `GET /user/applications/oauth2` and `GET /user/applications/oauth2/{id}` have operation ids that only differ in case, so they collapsed onto the same url and one of the two pages was silently dropped. They are now `user-get-oauth2-application` and `user-get-oauth2-application-by-id`. - The API overview and every tag page were all titled "Overview". ## Url compatibility The routes of both builds were compared page by page during the migration with `scripts/url-diff.mjs`: ``` identical: 2368, missing: 0, accepted: 110, added: 3292 ``` The 110 accepted ones are all redirected in `cloudflare/_redirects`: the localized copies of the English-only API and Runner docs, the Docusaurus search page, and `/1.27/`, `/runner/3/`, `/api/1.27/` which are aliases of the versions served at the product root. The added ones are the API operation and tag pages plus the routes the Starlight language fallback serves in English when a translation is missing — Docusaurus answered those with a 404. ## Workflows - `checks` builds the site and type checks it on every pull request - `Build and Publish Docs site` publishes `sites/docs/dist` to S3/CloudFront and to Cloudflare Pages, and copies `cloudflare/_headers` and `cloudflare/_redirects` into the deployment - `update swagger files` and `update runner reference` are unchanged, they only touch content - `make cut-version PRODUCT=docs VERSION=1.28` replaces `docusaurus docs:version` ## Removed `docusaurus.config.js`, the swizzled theme under `src/`, and the Docusaurus UI translations (`i18n/*/code.json`, `i18n/*/docusaurus-theme-classic/`). The strings those carried — the product names, the footer column titles and the outdated translation notice — were ported to `sites/docs/src/config/strings.ts`; Starlight ships the rest of its interface in both Chinese locales. The documentation content itself is untouched. ## Follow ups - nine relative links are broken in the sources and reported by every build, the same ones Docusaurus warned about; `GITEA_DOCS_STRICT_LINKS=true` turns them into an error once they are fixed - `cloudflare/worker.js` has to be deployed for `/enterprise/` to keep resolving - the Algolia index has to be created and crawled before the search credentials are set ## Testing ```shell make install make serve-fast # english, the version served at the root make serve # the whole matrix make build # 5751 pages make check # 0 errors make serve-built # build and serve, the only way to try the search locally ``` ## Screenshots image.png image.png image.png --------- Co-authored-by: bircni Reviewed-on: https://gitea.com/gitea/docs/pulls/496 Reviewed-by: bircni --- .gitea/workflows/build-and-publish.yaml | 35 +- .gitea/workflows/test.yaml | 25 +- .gitignore | 14 +- Makefile | 38 +- README.md | 112 +- cloudflare/_headers | 51 +- cloudflare/_redirects | 20 + cloudflare/docsearch-crawler.json | 32 + docusaurus.config.js | 542 - i18n/zh-cn/code.json | 8 - .../current/usage/issues-prs/pull-request.md | 2 +- .../installation/windows-service.md | 2 + .../version-1.22/usage/actions/variables.md | 2 +- .../version-1.22/usage/pull-request.md | 2 +- .../version-1.23/usage/pull-request.md | 2 +- .../version-1.24/usage/pull-request.md | 2 +- .../usage/issues-prs/pull-request.md | 2 +- .../usage/issues-prs/pull-request.md | 2 +- .../usage/issues-prs/pull-request.md | 2 +- .../docusaurus-theme-classic/footer.json | 34 - .../docusaurus-theme-classic/navbar.json | 17 - i18n/zh-tw/code.json | 8 - .../installation/windows-service.md | 2 + .../version-1.22/usage/actions/variables.md | 2 +- .../docusaurus-theme-classic/footer.json | 34 - .../docusaurus-theme-classic/navbar.json | 17 - package.json | 52 +- packages/content-loader/package.json | 19 + packages/content-loader/src/categories.ts | 64 + packages/content-loader/src/index.ts | 419 + packages/content-loader/src/links.ts | 78 + packages/content-loader/src/markdown.ts | 79 + packages/content-loader/src/products.ts | 291 + packages/content-loader/src/segments.ts | 171 + packages/content-loader/src/sidebar.ts | 226 + pnpm-lock.yaml | 14858 ++++------------ pnpm-workspace.yaml | 8 +- scripts/cut-version.mjs | 94 + sites/docs/README.md | 120 + sites/docs/astro.config.mjs | 141 + sites/docs/package.json | 25 + sites/docs/src/assets/gitea.svg | 31 + .../docs/src/components/ApiOverviewTags.astro | 76 + sites/docs/src/components/Header.astro | 129 + .../docs/src/components/LanguageSelect.astro | 72 + .../docs/src/components/MarkdownContent.astro | 38 + sites/docs/src/components/PageFrame.astro | 18 + sites/docs/src/components/SiteFooter.astro | 74 + sites/docs/src/components/SiteTitle.astro | 58 + sites/docs/src/config/api.ts | 142 + sites/docs/src/config/apiTags.ts | 24 + sites/docs/src/config/docsearch.ts | 28 + sites/docs/src/config/paths.ts | 21 + sites/docs/src/config/site.ts | 47 + sites/docs/src/config/strings.ts | 70 + sites/docs/src/content.config.ts | 11 + sites/docs/src/integrations/api.ts | 18 + sites/docs/src/integrations/postbuild.ts | 106 + sites/docs/src/lib/routes.ts | 52 + sites/docs/src/lib/search.ts | 21 + sites/docs/src/lib/sidebars.ts | 76 + sites/docs/src/lib/versions.ts | 85 + sites/docs/src/middleware/api.ts | 49 + sites/docs/src/routeData.ts | 49 + sites/docs/src/schema.ts | 25 + sites/docs/src/styles/custom.css | 155 + sites/docs/src/styles/theme.css | 113 + sites/docs/tsconfig.json | 5 + src/components/ActionCard/index.js | 22 - src/components/ActionCard/styles.module.css | 53 - src/components/ActionFooter/footer.module.css | 19 - src/components/ActionFooter/foss.svg | 4 - src/components/ActionFooter/index.js | 53 - src/components/ActionFooter/styles.module.css | 27 - src/components/ActionFooter/subscribeIcon.svg | 5 - src/components/Button/index.js | 66 - src/components/Button/styles.module.css | 95 - src/components/ClientOnly.js | 12 - src/components/DropDown.js | 42 - src/components/Input/index.js | 21 - src/components/Input/styles.module.css | 23 - src/components/Outdated.js | 17 - src/components/Section/index.js | 31 - src/components/Section/styles.module.css | 41 - src/components/Subscribe/index.js | 82 - src/components/Subscribe/style.module.css | 75 - src/components/SvgImage/index.js | 9 - src/css/custom.css | 272 - src/theme/ApiDoc/ApiDoc.jsx | 16 - src/theme/ApiDoc/index.js | 2 - src/theme/DocPage/Layout/index.js | 36 - src/theme/DocPage/Layout/styles.module.css | 9 - src/theme/MDXComponents/A.js | 14 - src/theme/MDXComponents/index.js | 7 - src/theme/MDXContent/index.js | 16 - src/theme/NavbarItem/ComponentTypes.js | 24 - src/theme/NotFound/Content/index.js | 16 - src/theme/NotFound/Content/styles.module.css | 15 - update_runner_docs.sh | 4 +- 99 files changed, 6701 insertions(+), 13674 deletions(-) create mode 100644 cloudflare/_redirects create mode 100644 cloudflare/docsearch-crawler.json delete mode 100644 docusaurus.config.js delete mode 100644 i18n/zh-cn/code.json delete mode 100644 i18n/zh-cn/docusaurus-theme-classic/footer.json delete mode 100644 i18n/zh-cn/docusaurus-theme-classic/navbar.json delete mode 100644 i18n/zh-tw/code.json delete mode 100644 i18n/zh-tw/docusaurus-theme-classic/footer.json delete mode 100644 i18n/zh-tw/docusaurus-theme-classic/navbar.json create mode 100644 packages/content-loader/package.json create mode 100644 packages/content-loader/src/categories.ts create mode 100644 packages/content-loader/src/index.ts create mode 100644 packages/content-loader/src/links.ts create mode 100644 packages/content-loader/src/markdown.ts create mode 100644 packages/content-loader/src/products.ts create mode 100644 packages/content-loader/src/segments.ts create mode 100644 packages/content-loader/src/sidebar.ts create mode 100644 scripts/cut-version.mjs create mode 100644 sites/docs/README.md create mode 100644 sites/docs/astro.config.mjs create mode 100644 sites/docs/package.json create mode 100644 sites/docs/src/assets/gitea.svg create mode 100644 sites/docs/src/components/ApiOverviewTags.astro create mode 100644 sites/docs/src/components/Header.astro create mode 100644 sites/docs/src/components/LanguageSelect.astro create mode 100644 sites/docs/src/components/MarkdownContent.astro create mode 100644 sites/docs/src/components/PageFrame.astro create mode 100644 sites/docs/src/components/SiteFooter.astro create mode 100644 sites/docs/src/components/SiteTitle.astro create mode 100644 sites/docs/src/config/api.ts create mode 100644 sites/docs/src/config/apiTags.ts create mode 100644 sites/docs/src/config/docsearch.ts create mode 100644 sites/docs/src/config/paths.ts create mode 100644 sites/docs/src/config/site.ts create mode 100644 sites/docs/src/config/strings.ts create mode 100644 sites/docs/src/content.config.ts create mode 100644 sites/docs/src/integrations/api.ts create mode 100644 sites/docs/src/integrations/postbuild.ts create mode 100644 sites/docs/src/lib/routes.ts create mode 100644 sites/docs/src/lib/search.ts create mode 100644 sites/docs/src/lib/sidebars.ts create mode 100644 sites/docs/src/lib/versions.ts create mode 100644 sites/docs/src/middleware/api.ts create mode 100644 sites/docs/src/routeData.ts create mode 100644 sites/docs/src/schema.ts create mode 100644 sites/docs/src/styles/custom.css create mode 100644 sites/docs/src/styles/theme.css create mode 100644 sites/docs/tsconfig.json delete mode 100644 src/components/ActionCard/index.js delete mode 100644 src/components/ActionCard/styles.module.css delete mode 100644 src/components/ActionFooter/footer.module.css delete mode 100644 src/components/ActionFooter/foss.svg delete mode 100644 src/components/ActionFooter/index.js delete mode 100644 src/components/ActionFooter/styles.module.css delete mode 100644 src/components/ActionFooter/subscribeIcon.svg delete mode 100644 src/components/Button/index.js delete mode 100644 src/components/Button/styles.module.css delete mode 100644 src/components/ClientOnly.js delete mode 100644 src/components/DropDown.js delete mode 100644 src/components/Input/index.js delete mode 100644 src/components/Input/styles.module.css delete mode 100644 src/components/Outdated.js delete mode 100644 src/components/Section/index.js delete mode 100644 src/components/Section/styles.module.css delete mode 100644 src/components/Subscribe/index.js delete mode 100644 src/components/Subscribe/style.module.css delete mode 100644 src/components/SvgImage/index.js delete mode 100644 src/css/custom.css delete mode 100644 src/theme/ApiDoc/ApiDoc.jsx delete mode 100644 src/theme/ApiDoc/index.js delete mode 100644 src/theme/DocPage/Layout/index.js delete mode 100644 src/theme/DocPage/Layout/styles.module.css delete mode 100644 src/theme/MDXComponents/A.js delete mode 100644 src/theme/MDXComponents/index.js delete mode 100644 src/theme/MDXContent/index.js delete mode 100644 src/theme/NavbarItem/ComponentTypes.js delete mode 100644 src/theme/NotFound/Content/index.js delete mode 100644 src/theme/NotFound/Content/styles.module.css diff --git a/.gitea/workflows/build-and-publish.yaml b/.gitea/workflows/build-and-publish.yaml index 90610315..5b1578c5 100644 --- a/.gitea/workflows/build-and-publish.yaml +++ b/.gitea/workflows/build-and-publish.yaml @@ -1,5 +1,5 @@ name: Build and Publish Docs site -run-name: docusaurus build docs site +run-name: astro build docs site on: push: @@ -9,6 +9,13 @@ on: jobs: build-docs: runs-on: ubuntu-24.04 + env: + NODE_OPTIONS: --max-old-space-size=8192 + # search only appears once the credentials are set, the build falls back + # to pagefind otherwise + PUBLIC_DOCSEARCH_APP_ID: ${{ secrets.DOCSEARCH_APP_ID }} + PUBLIC_DOCSEARCH_API_KEY: ${{ secrets.DOCSEARCH_API_KEY }} + PUBLIC_DOCSEARCH_INDEX_NAME: ${{ secrets.DOCSEARCH_INDEX_NAME }} steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 - uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6 @@ -23,14 +30,13 @@ jobs: sudo ./aws/install - name: prepare awesome list run: | - make prepare-awesome-latest prepare-awesome\#25 prepare-awesome\#24 prepare-awesome\#23 prepare-awesome\#22 + make prepare-awesome-latest prepare-awesome\#27 prepare-awesome\#26 prepare-awesome\#25 prepare-awesome\#24 prepare-awesome\#23 prepare-awesome\#22 - name: Install dependencies run: pnpm install --frozen-lockfile - #- uses: tats-u/docuactions-cache@v1 - name: build site - run: | - make build + run: make build + - name: aws credential configure uses: aws-actions/configure-aws-credentials@e6de054238d6b7531b4efff3b6587d9aade6a06c # v6 with: @@ -39,20 +45,21 @@ jobs: aws-region: ${{ secrets.AWS_REGION}} - name: Copy files to the production website with the AWS CLI run: | - aws s3 sync build/ s3://docs-gitea-com + aws s3 sync sites/docs/dist/ s3://docs-gitea-com aws cloudfront create-invalidation --distribution-id ${{ secrets.AWS_DISTRIBUTION}} --paths '/*' - name: Copy files to Cloudflare Pages env: CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} run: | - # cloudflare/_headers is only meaningful for the Cloudflare Pages - # deployment, so it is copied into build/ here, after the S3 sync - # step above has already run. If it were placed in build/ any - # earlier, that S3 sync would publish it to S3/CloudFront and make - # it publicly accessible at /_headers there. - cp cloudflare/_headers build/_headers - test -f build/_headers || exit 1 - pnpm dlx wrangler@4 pages deploy build \ + # cloudflare/_headers and cloudflare/_redirects are only meaningful for + # the Cloudflare Pages deployment, so they are copied into the build + # here, after the S3 sync above has run. If they were placed in the + # build any earlier, that sync would publish them to S3/CloudFront and + # make them publicly readable there. + cp cloudflare/_headers sites/docs/dist/_headers + cp cloudflare/_redirects sites/docs/dist/_redirects + test -f sites/docs/dist/_headers -a -f sites/docs/dist/_redirects || exit 1 + pnpm dlx wrangler@4 pages deploy sites/docs/dist \ --project-name docs-gitea-com \ --branch main diff --git a/.gitea/workflows/test.yaml b/.gitea/workflows/test.yaml index 465aa4fc..e5efc5ee 100644 --- a/.gitea/workflows/test.yaml +++ b/.gitea/workflows/test.yaml @@ -11,6 +11,8 @@ concurrency: jobs: build-docs: runs-on: ubuntu-latest + env: + NODE_OPTIONS: --max-old-space-size=8192 steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 - uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6 @@ -20,14 +22,17 @@ jobs: cache: pnpm - name: prepare awesome list run: | - make prepare-awesome-latest prepare-awesome\#25 prepare-awesome\#24 prepare-awesome\#23 prepare-awesome\#22 - - name: Install dependencies + make prepare-awesome-latest prepare-awesome\#27 prepare-awesome\#26 prepare-awesome\#25 prepare-awesome\#24 prepare-awesome\#23 prepare-awesome\#22 + + - name: install dependencies run: pnpm install --frozen-lockfile - #- uses: tats-u/docuactions-cache@v1 - name: build site - run: | - make build + run: make build + + - name: type check + run: make check + - name: deploy the preview to Cloudflare Pages id: preview env: @@ -44,11 +49,13 @@ jobs: exit 0 fi - # same as the production deployment: _headers only belongs to the - # Cloudflare Pages output, so it is copied in right before uploading - cp cloudflare/_headers build/_headers + # same as the production deployment: _headers and _redirects only + # belong to the Cloudflare Pages output, so they are copied in right + # before uploading + cp cloudflare/_headers sites/docs/dist/_headers + cp cloudflare/_redirects sites/docs/dist/_redirects - pnpm dlx wrangler@4 pages deploy build \ + pnpm dlx wrangler@4 pages deploy sites/docs/dist \ --project-name docs-gitea-com \ --branch "pr-$PR_NUMBER" | tee wrangler.log diff --git a/.gitignore b/.gitignore index e4ecca58..f3c24951 100644 --- a/.gitignore +++ b/.gitignore @@ -1,12 +1,12 @@ # Dependencies -/node_modules +node_modules -# Production -/build - -# Generated files -.docusaurus -.cache-loader +# Build output +sites/*/dist +sites/*/.astro +sites/*/.cache +build/ +.docusaurus/ # Misc .DS_Store diff --git a/Makefile b/Makefile index 51c886f1..0e103935 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,3 @@ -export NODE_OPTIONS := "--max-old-space-size=8192" - GITEA_AWESOME_REMOTE := https://gitea.com/gitea/awesome-gitea.git GITEA_AWESOME_BRANCH := main @@ -27,26 +25,41 @@ install: pnpm install .PHONY: prepare-docs -prepare-docs: install prepare-awesome-latest prepare-awesome\#19 prepare-awesome\#20 prepare-awesome\#21 prepare-awesome\#22 prepare-awesome\#23 prepare-awesome\#24 +prepare-docs: install prepare-awesome-latest prepare-awesome\#22 prepare-awesome\#23 prepare-awesome\#24 prepare-awesome\#25 prepare-awesome\#26 prepare-awesome\#27 .PHONY: build build: pnpm run build +# type checks the astro site and its components +.PHONY: check +check: + pnpm run check + .PHONY: serve serve: prepare-docs - pnpm run start + pnpm run dev -.PHONY: serve-zh -serve-zh: prepare-docs - pnpm run start -- --locale zh-cn +# only the english docs of the version served at the root, plus the runner: +# starts in a few seconds instead of loading the whole matrix +.PHONY: serve-fast +serve-fast: + pnpm run dev:en-latest + +# search is built by pagefind at build time, so it is only available on the +# built site; this serves it locally +.PHONY: serve-built +serve-built: build + pnpm run preview -# static/swagger-*.json are committed files, use update-api-docs to refresh them .PHONY: clean clean: rm -rf .tmp - rm -rf static/_* + rm -rf sites/docs/dist + rm -rf sites/docs/.cache + rm -rf sites/docs/node_modules/.astro +# static/swagger-*.json are committed files, use update-api-docs to refresh them .PHONY: update-api-docs update-api-docs: ./update_api_docs.sh @@ -67,3 +80,10 @@ update-runner-docs: .PHONY: update-runner-docs-released update-runner-docs-released: ./update_runner_docs.sh --released + +# freezes the current docs or runner tree as a new version, see +# scripts/cut-version.mjs +.PHONY: cut-version +cut-version: + @test -n "$(PRODUCT)" -a -n "$(VERSION)" || { echo 'usage: make cut-version PRODUCT=docs VERSION=1.28'; exit 1; } + node scripts/cut-version.mjs $(PRODUCT) $(VERSION) diff --git a/README.md b/README.md index 10ea1bf9..b5ed3137 100644 --- a/README.md +++ b/README.md @@ -1,65 +1,99 @@ # Gitea Docs ![badge](https://gitea.com/gitea/docs/actions/workflows/build-and-publish.yaml/badge.svg) -## How to build +The sources of [docs.gitea.com](https://docs.gitea.com), built with +[Astro](https://astro.build) and [Starlight](https://starlight.astro.build). -```shell -make clean -make prepare-docs -make build -``` +The site covers three products, all served from this repository: + +| Product | Content | Versions | Languages | +| --- | --- | --- | --- | +| Docs | `docs/`, `versioned_docs/`, `i18n/` | next, 1.27 … 1.22 | English, 简体中文, 繁體中文 | +| API | `static/swagger-*.json` | next, 1.27 … 1.22 | English | +| Runner | `runner-docs/`, `runner-docs_versioned_docs/` | develop, 3 … 0 | English | + +The enterprise documentation is built and deployed from its own repository and +reached through `/enterprise/`, which a Cloudflare worker maintained elsewhere +routes to that deployment. ## Development ```shell -make clean -make prepare-docs -make serve +make install # pnpm install +make serve-fast # english, the version served at the root, starts in seconds +make serve # the whole matrix, every version and language +make build # production build into sites/docs/dist +make check # type checks the site and its components ``` -## Test en version +Search is built by Pagefind while the site is built, so it only answers on the +built site: use `make serve-built` to try it. With the Algolia credentials +(`PUBLIC_DOCSEARCH_APP_ID`, `PUBLIC_DOCSEARCH_API_KEY`) set, DocSearch is used +instead and works in `make serve` too. + +`GITEA_DOCS_PRODUCTS`, `GITEA_DOCS_VERSIONS` and `GITEA_DOCS_LOCALES` (comma +separated) restrict what is built, which is what `make serve-fast` uses. +`GITEA_DOCS_STRICT_LINKS=true` turns the warnings about unresolved relative +markdown links into a build error. + +`sites/docs/README.md` documents how the sources are mapped onto the site. + +## Writing + +Pages are plain markdown with the same frontmatter and admonitions as before: +frontmatter `slug`, `sidebar_position` and `sidebar_label` keep working, and so +do the `:::note` style admonitions and the `@version@` style release variables. +Relative `*.md` links are rewritten to urls while the site is built. + +The order of the top level sidebar groups comes from `sidebars.js` (and +`versioned_sidebars/` for released versions), the label and order of every other +group from the `_category_.json` of its directory. + +## Cutting a version ```shell -pnpm run start +make cut-version PRODUCT=docs VERSION=1.28 +make cut-version PRODUCT=runner VERSION=4 ``` +This freezes the current tree, its translations and its sidebar. The label of +the version, its release variables (`@version@`, `@dockerVersion@`, ...) and +which version is served at the root live in +`packages/content-loader/src/products.ts` and are edited by hand afterwards. +That file is the single source of truth for the product, version and language +matrix. + ## API docs -The swagger definitions rendered under `/api-docs` live in `static/swagger-latest.json` -(gitea main) and `static/swagger-.json` (released versions). +The swagger definitions rendered under `/api/` live in +`static/swagger-latest.json` (gitea main) and `static/swagger-.json` +(released versions). ```shell make update-api-docs # refresh latest + every released version make update-api-docs-latest # refresh only static/swagger-latest.json ``` -`static/swagger-latest.json` is refreshed automatically: the `update swagger files` -workflow runs every 12 hours and opens a pull request whenever gitea main changed. -Released versions are updated by hand when a new gitea version is documented. +`static/swagger-latest.json` is refreshed automatically: the `update swagger +files` workflow runs every 12 hours and opens a pull request whenever gitea main +changed. Released versions are updated by hand when a new gitea version is +documented. ## Runner docs -The runner documentation is a second docs plugin, served under `/runner`: - | Version | Content | URL | | --- | --- | --- | | develop | `runner-docs/` | `/runner/develop/` | | current series | `runner-docs_versioned_docs/version-3/` | `/runner/` | | older series | `runner-docs_versioned_docs/version-2/` | `/runner/2/` | -| archived series | `runner-docs_versioned_docs/version-1/` | `/runner/1/` | A version directory covers a whole release series (`version-3` documents every -`3.x` release), so a patch release only needs a content update, not a new folder. -The UI labels a series `3.x`, derived from `runner-docs_versions.json`, so no -version number has to be bumped anywhere on a runner release. Use floating image -tags (`gitea/runner:3`) and links to the runner's `main` branch in those pages to -keep them valid across patch releases. +`3.x` release), so a patch release only needs a content update, not a new +folder. Use floating image tags (`gitea/runner:3`) and links to the runner's +`main` branch in those pages to keep them valid across patch releases. Its sidebar is written by hand: `runner-sidebars.js` for develop, and `runner-docs_versioned_sidebars/version--sidebars.json` per documented -version. The version list lives in `runner-docs_versions.json`; the `versions`, -`lastVersion` and `Runner Version` dropdown entries in `docusaurus.config.js` are -built from it, so a new series only has to be cut with -`pnpm run docusaurus docs:version:runner-docs `. +version. The pages under `reference/` are generated from the runner sources — the command line reference from `--help`, the example configuration from `generate-config`: @@ -70,12 +104,18 @@ make update-runner-docs-released # every series, from its newest stable tag ./update_runner_docs.sh v3.0.2 runner-docs_versioned_docs/version-3/reference ``` -`--released` (what `make update-runner-docs-released` runs) needs no version list: -it regenerates every `runner-docs_versioned_docs/version-/reference` -directory from the newest stable `v.x.y` tag of `gitea/runner`, looked up -through the Gitea API. +These are refreshed automatically as well: the `update runner reference` +workflow runs weekly and opens a pull request whenever the runner's CLI or +example configuration changed. Generating them needs Go, since the script builds +the runner binary. -All of these pages are refreshed automatically: the `update runner reference` -workflow runs weekly, regenerates the develop and the released references, and -opens a pull request whenever the runner's CLI or example configuration changed. -Generating them needs Go, since the script builds the runner binary. +## Deployment + +`main` is built and published by the `Build and Publish Docs site` workflow, to +S3/CloudFront and to Cloudflare Pages. `cloudflare/_headers` sets the cache +policy and `cloudflare/_redirects` keeps the urls the site used to serve; both +are copied next to the build output by that workflow. +`cloudflare/docsearch-crawler.json` is the Algolia crawler configuration. + +`/enterprise/` is served by another deployment and routed to it by a Cloudflare +worker that lives outside this repository. diff --git a/cloudflare/_headers b/cloudflare/_headers index e388c413..a37ea054 100644 --- a/cloudflare/_headers +++ b/cloudflare/_headers @@ -1,45 +1,24 @@ -# Cloudflare Pages reads this file from the root of the deployed directory -# (build/_headers once .gitea/workflows/build-and-publish.yaml copies it -# in). It lives here, outside static/, so that `make clean` (which does -# `rm -rf static/_*`) cannot delete it and so Docusaurus does not copy it -# into every locale build directory (see the locale rules below for why -# that would matter anyway). - -# Docusaurus content-hashed build output (webpack chunks, css, etc). The -# filename changes whenever the content changes, so it is safe to cache -# these for a long time and mark them immutable. -/assets/* - Cache-Control: public, max-age=31536000, immutable - -# docusaurus.config.js configures locales ["en-us", "zh-cn", "zh-tw"] with -# "en-us" as the default. Docusaurus only serves the default locale at the -# site root; every other locale gets a full copy of the build under a -# // prefix (e.g. build/zh-cn, build/zh-tw), including its own -# assets/img/images directories. Confirmed live: /zh-cn/ references -# /zh-cn/assets/css/styles.a0cbb0c4.css, and without a rule matching that -# path it is served with `cache-control: public, max-age=0, -# must-revalidate` instead of the caching below. +# Cloudflare Pages reads this file from the root of the deployed directory. It +# is copied into the build output by the publish workflow, so that it is not +# uploaded to S3/CloudFront where it would be publicly readable at /_headers. # -# Use a `:locale` placeholder rather than listing "zh-cn" and "zh-tw" -# explicitly, so this keeps working if a locale is added or removed later -# without anyone remembering to update this file. Cloudflare Pages only -# allows a single `*` splat per path, so the locale segment has to be a -# named placeholder (`:locale`, matching exactly one path segment) rather -# than a second splat; `/*/assets/*` is not a valid pattern. -/:locale/assets/* +# Unlike the docusaurus build, astro emits a single content hashed asset +# directory shared by every language, so no per locale rules are needed. + +# Content hashed build output (js, css, fonts). The file name changes with the +# content, so these can be cached forever. +/_astro/* Cache-Control: public, max-age=31536000, immutable -# Files under static/img and static/images keep stable filenames and can be -# replaced in place (same name, new content), so use a short, conservative -# max-age instead of immutable caching. +# Files under public/img and public/images keep stable names and are replaced in +# place, so they get a short, conservative max-age instead. /img/* Cache-Control: public, max-age=86400 -/:locale/img/* - Cache-Control: public, max-age=86400 - /images/* Cache-Control: public, max-age=86400 -/:locale/images/* - Cache-Control: public, max-age=86400 +# The pagefind index, only present when the site is built without algolia +# docsearch. Content hashed as well. +/pagefind/* + Cache-Control: public, max-age=31536000, immutable diff --git a/cloudflare/_redirects b/cloudflare/_redirects new file mode 100644 index 00000000..11dce85e --- /dev/null +++ b/cloudflare/_redirects @@ -0,0 +1,20 @@ +# Redirects for legacy URLs and routes the site no longer serves directly. + +# The api reference and the runner docs are separate products, published in +# english only. Docusaurus served an empty localized copy of them. +/zh-cn/api/* /api/:splat 301 +/zh-tw/api/* /api/:splat 301 +/zh-cn/runner/* /runner/:splat 301 +/zh-tw/runner/* /runner/:splat 301 + +# The version served at the root of a product is also reachable under its +# number, which is what the release notes and old links use. +/api/1.27/* /api/:splat 301 +/runner/3/* /runner/:splat 301 +/1.27/* /:splat 301 + +# The local search plugin had a results page of its own, algolia docsearch is a +# modal opened from any page. +/search / 301 +/zh-cn/search /zh-cn/ 301 +/zh-tw/search /zh-tw/ 301 diff --git a/cloudflare/docsearch-crawler.json b/cloudflare/docsearch-crawler.json new file mode 100644 index 00000000..903d5310 --- /dev/null +++ b/cloudflare/docsearch-crawler.json @@ -0,0 +1,32 @@ +{ + "_comment": "Algolia DocSearch crawler configuration. The three facets come from the docsearch:* meta tags every page carries; only the versions people read are indexed, the older ones stay reachable through the version picker.", + "index_name": "gitea", + "start_urls": [ + "https://docs.gitea.com/", + "https://docs.gitea.com/next/", + "https://docs.gitea.com/zh-cn/", + "https://docs.gitea.com/zh-tw/", + "https://docs.gitea.com/runner/", + "https://docs.gitea.com/api/", + "https://docs.gitea.com/enterprise/" + ], + "sitemap_urls": ["https://docs.gitea.com/sitemap-index.xml"], + "exclusion_patterns": [ + "https://docs.gitea.com/1.2*/**", + "https://docs.gitea.com/*/1.2*/**", + "https://docs.gitea.com/api/1.2*/**", + "https://docs.gitea.com/runner/[0-9]/**" + ], + "selectors": { + "lvl0": { "selector": "//nav[contains(@aria-labelledby,'starlight__sidebar')]//a[@aria-current='page']/ancestor::details//summary//span", "type": "xpath", "global": true, "default_value": "Documentation" }, + "lvl1": ".sl-markdown-content h1, h1", + "lvl2": ".sl-markdown-content h2", + "lvl3": ".sl-markdown-content h3", + "lvl4": ".sl-markdown-content h4", + "text": ".sl-markdown-content p, .sl-markdown-content li, .sl-markdown-content td" + }, + "custom_settings": { + "attributesForFaceting": ["product", "version", "language"] + }, + "conversation_id": [] +} diff --git a/docusaurus.config.js b/docusaurus.config.js deleted file mode 100644 index 29234ff7..00000000 --- a/docusaurus.config.js +++ /dev/null @@ -1,542 +0,0 @@ -// @ts-check -// Note: type annotations allow type checking and IDEs autocompletion - -import { themes as prismThemes } from "prism-react-renderer"; - -const lightCodeTheme = prismThemes.github; -const darkCodeTheme = prismThemes.dracula; - -// order usage directory by type first -function sortItemsByCategory(items) { - // type with "category" (directory) first - const sortedItems = items.sort(function (a, b) { - return a.type.localeCompare(b.type); - }); - return sortedItems; -} - -const renderApiSSR = process.env.API_SSR !== "false"; - -const apiConfig = [ - "redocusaurus", - { - // Plugin Options for loading OpenAPI files - specs: renderApiSSR - ? [ - { - route: "/api/next/", - spec: "static/swagger-latest.json", - }, - { - route: "/api/", - spec: "static/swagger-27.json", - }, - { - route: "/api/1.27/", - spec: "static/swagger-27.json", - }, - { - route: "/api/1.26/", - spec: "static/swagger-26.json", - }, - { - route: "/api/1.25/", - spec: "static/swagger-25.json", - }, - { - route: "/api/1.24/", - spec: "static/swagger-24.json", - }, - { - route: "/api/1.23/", - spec: "static/swagger-23.json", - }, - { - route: "/api/1.22/", - spec: "static/swagger-22.json", - }, - ] - : [], - // Theme Options for modifying how redoc renders them - theme: { - // Change with your site colors - primaryColor: "#1890ff", - }, - }, -]; - -const pageConfig = renderApiSSR - ? { - exclude: ["api/**"], - } - : {}; - -const globalVariables = { - "current": { - goVersion: "1.26", - minGoVersion: "1.26", - minNodeVersion: "22", - version: "main-nightly", - sourceVersion: "main", - sourceBranch: "main", - dockerVersion: "nightly", - displayVersion: "1.28-dev", - }, - "1.27": { - goVersion: "1.26", - minGoVersion: "1.26", - minNodeVersion: "24", - version: "1.27.1", - sourceVersion: "v1.27.1", - sourceBranch: "release/v1.27", - dockerVersion: "1.27.1", - displayVersion: "1.27.1", - }, - "1.26": { - goVersion: "1.26", - minGoVersion: "1.26", - minNodeVersion: "22", - version: "1.26.4", - sourceVersion: "v1.26.4", - sourceBranch: "release/v1.26", - dockerVersion: "1.26.4", - displayVersion: "1.26.4", - }, - "1.25": { - goVersion: "1.25", - minGoVersion: "1.25", - minNodeVersion: "22", - version: "1.25.5", - sourceVersion: "v1.25.0", - sourceBranch: "release/v1.25", - dockerVersion: "1.25.5", - displayVersion: "1.25.5", - }, - "1.24": { - goVersion: "1.24", - minGoVersion: "1.24", - minNodeVersion: "22", - version: "1.24.7", - sourceVersion: "v1.24.0", - sourceBranch: "release/v1.24", - dockerVersion: "1.24.7", - displayVersion: "1.24.7", - }, - "1.23": { - goVersion: "1.23", - minGoVersion: "1.22", - minNodeVersion: "18", - version: "1.23.8", - sourceVersion: "v1.23.8", - sourceBranch: "release/v1.23", - dockerVersion: "1.23.8", - displayVersion: "1.23.8", - }, - "1.22": { - goVersion: "1.22", - minGoVersion: "1.22", - minNodeVersion: "18", - version: "1.22.6", - sourceVersion: "v1.22.6", - sourceBranch: "release/v1.22", - dockerVersion: "1.22.6", - displayVersion: "1.22.6", - }, -}; - -const versions = { - "current": { - label: globalVariables["current"].displayVersion, // path is kept as next for dev (so users can always find "nightly" docs) - banner: "unreleased", - }, - "1.27": { - label: globalVariables["1.27"].displayVersion, - }, - "1.26": { - label: globalVariables["1.26"].displayVersion, - }, - "1.25": { - label: globalVariables["1.25"].displayVersion, - }, - "1.24": { - label: globalVariables["1.24"].displayVersion, - }, - "1.23": { - label: globalVariables["1.23"].displayVersion, - }, - "1.22": { - label: globalVariables["1.22"].displayVersion, - }, -}; - -// The runner docs keep one directory per release series -// (runner-docs_versioned_docs/version-), so a series is labelled "3.x" -// and a patch release never touches this file. The list is the one docusaurus -// maintains, newest first. -const runnerVersions = require("./runner-docs_versions.json"); -const runnerVersionLabel = (version) => `${version}.x`; -const runnerVersionPath = (version) => - // no path for the latest series, its docs are served at /runner/ - version === runnerVersions[0] ? "/runner/" : `/runner/${version}/`; - -/** @type {import('@docusaurus/types').Config} */ -const config = { - title: "Gitea Documentation", - tagline: "Git with a cup of tea", - url: "https://docs.gitea.com", - baseUrl: "/", - onBrokenLinks: "warn", - favicon: "img/favicon.png", - future: { - faster: true, - v4: true - }, - plugins: [ - [ - "docusaurus-plugin-plausible", - { - domain: "docs.gitea.com", - }, - ], - - // for runner documentations - [ - "@docusaurus/plugin-content-docs", - { - id: "runner-docs", - path: "runner-docs", - routeBasePath: "runner", - sidebarPath: require.resolve("./runner-sidebars.js"), - // the current runner docs describe the main branch of gitea/runner - includeCurrentVersion: true, - versions: { - current: { - path: "develop", - label: "develop", - banner: "unreleased", - }, - ...Object.fromEntries( - runnerVersions.map((version) => [ - version, - { label: runnerVersionLabel(version) }, - ]), - ), - }, - // the newest series has no "path", so the latest stable runner docs are - // served at /runner/ and links do not need updating on each release - lastVersion: runnerVersions[0], - editUrl: ({ - versionDocsDirPath, - docPath, - locale, - version, - permalink, - }) => { - return `https://gitea.com/gitea/docs/src/branch/main/${ - version === "current" - ? "runner-docs" - : `runner-docs_versioned_docs/version-${version}` - }/${docPath}`; - }, - }, - ], - ], - - i18n: { - defaultLocale: "en-us", - locales: ["en-us", "zh-cn", "zh-tw"], - localeConfigs: { - "en-us": { - label: "English", - }, - "zh-cn": { - label: "简体中文", - }, - "zh-tw": { - label: "繁體中文", - }, - }, - }, - - presets: [ - [ - "@docusaurus/preset-classic", - //'classic', - /** @type {import('@docusaurus/preset-classic').Options} */ - ({ - docs: { - sidebarPath: require.resolve("./sidebars.js"), - routeBasePath: "/", // Serve the docs at the site's root - editUrl: ({ - versionDocsDirPath, - docPath, - locale, - version, - permalink, - }) => { - // Special case for awesome page - if (docPath.includes("awesome.md")) { - return `https://gitea.com/gitea/awesome-gitea/src/branch/main/README.md`; - } - if (locale === "en-us") { - return `https://gitea.com/gitea/docs/src/branch/main/${ - version === "current" - ? "docs" - : `versioned_docs/version-${version}` - }/${docPath}`; - } - return `https://gitea.com/gitea/docs/src/branch/main/i18n/${locale}/docusaurus-plugin-content-docs/${ - version === "current" ? "current" : `version-${version}` - }/${docPath}`; - }, - versions: versions, - lastVersion: "1.27", - async sidebarItemsGenerator({ - defaultSidebarItemsGenerator, - ...args - }) { - const { item } = args; - // Use the provided data to generate a custom sidebar slice - const sidebarItems = await defaultSidebarItemsGenerator(args); - if (item.dirName !== "usage") { - return sidebarItems; - } else { - return sortItemsByCategory(sidebarItems); - } - }, - }, - blog: false, - theme: { - customCss: require.resolve("./src/css/custom.css"), - }, - pages: pageConfig, - gtag: { - trackingID: "G-KHM0KYT506", - }, - }), - ], - apiConfig, - ], - markdown: { - hooks: { - onBrokenMarkdownLinks: "warn", - }, - preprocessor: ({ filePath, fileContent }) => { - var key = ""; - var found = false; - for (key in globalVariables) { - let folderName = key == "current" ? "current" : `version-${key}`; - if (filePath.includes(`/${folderName}/`)) { - found = true; - break; - } - } - if (key == "" || !found) { - key = "current"; - } - - let content = fileContent; - for (const variable in globalVariables[key]) { - content = content.replaceAll( - "@" + variable + "@", - globalVariables[key][variable] - ); - } - - return content; - }, - }, - themes: [ - [ - "@easyops-cn/docusaurus-search-local", - { - hashed: false, - language: ["en", "zh"], - highlightSearchTermsOnTargetPage: true, - explicitSearchResultPath: true, - indexBlog: false, - docsRouteBasePath: "/", - }, - ], - ], - - themeConfig: - /** @type {import('@docusaurus/preset-classic').ThemeConfig} */ - ({ - image: '/img/gitea.svg', - metadata: [ - { - name: 'og:logo', - content: '/img/gitea.svg' - }, - { - name: "keywords", - content: - "gitea, git, devops, actions, packages, documentation, self-hosted, open-source, version control, gitlab, github", - }, - ], - colorMode: { - defaultMode: "light", - disableSwitch: false, - respectPrefersColorScheme: true, - }, - announcementBar: { - id: "announcementBar-4", // Increment on change - content: `Try   Gitea Cloud   ☁️   for 30 days Accelerate your Development & Deploys!`, - }, - navbar: { - title: "Gitea", - logo: { - alt: "Gitea Logo", - src: "img/gitea.svg", - href: "https://about.gitea.com/", - target: "_self", - }, - items: [ - { - type: "doc", - docId: "index", - position: "left", - label: "Docs", - }, - { - to: "/api/", - label: "API", - position: "left", - activeBaseRegex: "/api/", - }, - { - to: "/runner/", - label: "Runner", - position: "left", - activeBaseRegex: "/runner/", - }, - { - position: "left", - label: "Enterprise", - href: "https://docs.gitea.com/enterprise", - className: "internal-href", - target: "_self", - }, - { - type: "search", - position: "right", - }, - { - type: "localeDropdown", - position: "right", - }, - { - type: "docsVersionDropdown", - position: "right", - dropdownActiveClassDisabled: true, - }, - { - type: "custom-Dropdown", - label: "API Version", - position: "right", - items: [ - { to: "/api/next/", label: "1.28-dev" }, - { to: "/api/", label: "1.27.1" }, - { to: "/api/1.26/", label: "1.26.4" }, - { to: "/api/1.25/", label: "1.25.5" }, - { to: "/api/1.24/", label: "1.24.7" }, - { to: "/api/1.23/", label: "1.23.8" }, - { to: "/api/1.22/", label: "1.22.6" }, - ], - routerRgx: "/api/", - classNames: "api-dropdown", - }, - { - type: "custom-Dropdown", - label: "Runner Version", - position: "right", - items: [ - { to: "/runner/develop/", label: "develop" }, - ...runnerVersions.map((version) => ({ - to: runnerVersionPath(version), - label: runnerVersionLabel(version), - })), - ], - routerRgx: "/runner/", - classNames: "runner-dropdown", - }, - { - to: "help/support", - position: "right", - label: "Support", - activeBaseRegex: "help/support", - }, - { - href: "https://gitea.com/user/login", - label: "Sign In", - position: "right", - className: "internal-href signin-button", - target: "_self", - }, - ], - }, - footer: { - style: "dark", - links: [ - { - title: "Community", - items: [ - { - label: "Awesome Gitea", - href: "https://gitea.com/gitea/awesome-gitea", - }, - { - label: "Stack Overflow", - href: "https://stackoverflow.com/questions/tagged/gitea", - }, - { - label: "Discord", - href: "https://discord.gg/gitea", - }, - { - label: "Forum", - href: "https://forum.gitea.com/", - }, - { - label: "Twitter", - href: "https://twitter.com/giteaio", - }, - { - label: "Mastodon", - href: "https://social.gitea.io/@gitea", - }, - { - label: "Bluesky", - href: "https://bsky.app/profile/gitea.com", - }, - ], - }, - { - title: "Code", - items: [ - { - label: "GitHub", - href: "https://github.com/go-gitea/gitea", - }, - { - label: "Gitea", - href: "https://gitea.com/gitea", - }, - { - label: "Tea CLI", - href: "https://gitea.com/gitea/tea", - }, - ], - }, - ], - }, - prism: { - theme: lightCodeTheme, - darkTheme: darkCodeTheme, - additionalLanguages: ["ini", "diff", "json", "http", "docker", "php"], - }, - }), -}; - -module.exports = config; diff --git a/i18n/zh-cn/code.json b/i18n/zh-cn/code.json deleted file mode 100644 index 627cf77d..00000000 --- a/i18n/zh-cn/code.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "outdated.message": { - "message": "当前中文文档翻译不是最新版,访问英文版本查看最新内容,或" - }, - "outdated.help": { - "message": "帮助我们翻译" - } -} diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/current/usage/issues-prs/pull-request.md b/i18n/zh-cn/docusaurus-plugin-content-docs/current/usage/issues-prs/pull-request.md index 01b7a7df..5a8ff375 100644 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/current/usage/issues-prs/pull-request.md +++ b/i18n/zh-cn/docusaurus-plugin-content-docs/current/usage/issues-prs/pull-request.md @@ -57,4 +57,4 @@ WORK_IN_PROGRESS_PREFIXES=WIP:,[WIP] ## 合并请求模板 -有关合并请求模板的更多信息请您移步 : [工单与合并请求模板](usage/issue-pull-request-templates.md) +有关合并请求模板的更多信息请您移步 : [工单与合并请求模板](issue-pull-request-templates.md) diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.22/installation/windows-service.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.22/installation/windows-service.md index b4943496..7ca0eaa3 100644 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.22/installation/windows-service.md +++ b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.22/installation/windows-service.md @@ -8,6 +8,8 @@ aliases: - /zh-cn/windows-service --- +# 注册为 Windows 服务 + ## 准备工作 在 C:\gitea\custom\conf\app.ini 中进行了以下更改: diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.22/usage/actions/variables.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.22/usage/actions/variables.md index 32fe31ec..7a178285 100644 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.22/usage/actions/variables.md +++ b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.22/usage/actions/variables.md @@ -6,7 +6,7 @@ sidebar_position: 25 --- -## 变量 +# 变量 您可以创建用户、组织和仓库级别的变量。变量的级别取决于创建它的位置。当创建变量时,变量的名称会被 转换为大写,在yaml文件中引用时需要使用大写。 diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.22/usage/pull-request.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.22/usage/pull-request.md index 3546f719..a3ece5bf 100644 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.22/usage/pull-request.md +++ b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.22/usage/pull-request.md @@ -59,4 +59,4 @@ WORK_IN_PROGRESS_PREFIXES=WIP:,[WIP] ## 合并请求模板 -有关合并请求模板的更多信息请您移步 : [工单与合并请求模板](usage/issue-pull-request-templates.md) +有关合并请求模板的更多信息请您移步 : [工单与合并请求模板](issue-pull-request-templates.md) diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.23/usage/pull-request.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.23/usage/pull-request.md index 01b7a7df..5a8ff375 100644 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.23/usage/pull-request.md +++ b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.23/usage/pull-request.md @@ -57,4 +57,4 @@ WORK_IN_PROGRESS_PREFIXES=WIP:,[WIP] ## 合并请求模板 -有关合并请求模板的更多信息请您移步 : [工单与合并请求模板](usage/issue-pull-request-templates.md) +有关合并请求模板的更多信息请您移步 : [工单与合并请求模板](issue-pull-request-templates.md) diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.24/usage/pull-request.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.24/usage/pull-request.md index 01b7a7df..5a8ff375 100644 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.24/usage/pull-request.md +++ b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.24/usage/pull-request.md @@ -57,4 +57,4 @@ WORK_IN_PROGRESS_PREFIXES=WIP:,[WIP] ## 合并请求模板 -有关合并请求模板的更多信息请您移步 : [工单与合并请求模板](usage/issue-pull-request-templates.md) +有关合并请求模板的更多信息请您移步 : [工单与合并请求模板](issue-pull-request-templates.md) diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.25/usage/issues-prs/pull-request.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.25/usage/issues-prs/pull-request.md index 01b7a7df..5a8ff375 100644 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.25/usage/issues-prs/pull-request.md +++ b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.25/usage/issues-prs/pull-request.md @@ -57,4 +57,4 @@ WORK_IN_PROGRESS_PREFIXES=WIP:,[WIP] ## 合并请求模板 -有关合并请求模板的更多信息请您移步 : [工单与合并请求模板](usage/issue-pull-request-templates.md) +有关合并请求模板的更多信息请您移步 : [工单与合并请求模板](issue-pull-request-templates.md) diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.26/usage/issues-prs/pull-request.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.26/usage/issues-prs/pull-request.md index 01b7a7df..5a8ff375 100644 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.26/usage/issues-prs/pull-request.md +++ b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.26/usage/issues-prs/pull-request.md @@ -57,4 +57,4 @@ WORK_IN_PROGRESS_PREFIXES=WIP:,[WIP] ## 合并请求模板 -有关合并请求模板的更多信息请您移步 : [工单与合并请求模板](usage/issue-pull-request-templates.md) +有关合并请求模板的更多信息请您移步 : [工单与合并请求模板](issue-pull-request-templates.md) diff --git a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.27/usage/issues-prs/pull-request.md b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.27/usage/issues-prs/pull-request.md index 01b7a7df..5a8ff375 100644 --- a/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.27/usage/issues-prs/pull-request.md +++ b/i18n/zh-cn/docusaurus-plugin-content-docs/version-1.27/usage/issues-prs/pull-request.md @@ -57,4 +57,4 @@ WORK_IN_PROGRESS_PREFIXES=WIP:,[WIP] ## 合并请求模板 -有关合并请求模板的更多信息请您移步 : [工单与合并请求模板](usage/issue-pull-request-templates.md) +有关合并请求模板的更多信息请您移步 : [工单与合并请求模板](issue-pull-request-templates.md) diff --git a/i18n/zh-cn/docusaurus-theme-classic/footer.json b/i18n/zh-cn/docusaurus-theme-classic/footer.json deleted file mode 100644 index d6798db1..00000000 --- a/i18n/zh-cn/docusaurus-theme-classic/footer.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "link.title.Docs": { - "message": "文档", - "description": "The title of the footer links column with title=Docs in the footer" - }, - "link.title.Community": { - "message": "社区", - "description": "The title of the footer links column with title=Community in the footer" - }, - "link.title.More": { - "message": "更多", - "description": "The title of the footer links column with title=More in the footer" - }, - "link.item.label.Tutorial": { - "message": "教程", - "description": "The label of footer link with label=Tutorial linking to /" - }, - "link.item.label.Code": { - "message": "开源代码", - "description": "The label of footer link with label=Code linking to https://github.com/go-gitea/gitea" - }, - "link.item.label.Stack Overflow": { - "message": "Stack Overflow", - "description": "The label of footer link with label=Stack Overflow linking to https://stackoverflow.com/questions/tagged/gitea" - }, - "link.item.label.Discord": { - "message": "Discord", - "description": "The label of footer link with label=Discord linking to https://discord.gg/gitea" - }, - "link.item.label.Twitter": { - "message": "Twitter", - "description": "The label of footer link with label=Twitter linking to https://twitter.com/giteaio" - } -} diff --git a/i18n/zh-cn/docusaurus-theme-classic/navbar.json b/i18n/zh-cn/docusaurus-theme-classic/navbar.json deleted file mode 100644 index ce9f476e..00000000 --- a/i18n/zh-cn/docusaurus-theme-classic/navbar.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "title": { - "message": "Gitea" - }, - "item.label.Docs": { - "message": "文档" - }, - "item.label.Code": { - "message": "开源代码" - }, - "item.label.Support": { - "message": "支持" - }, - "item.label.Blog": { - "message": "博客" - } -} diff --git a/i18n/zh-tw/code.json b/i18n/zh-tw/code.json deleted file mode 100644 index f17091c8..00000000 --- a/i18n/zh-tw/code.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "outdated.message": { - "message": "當前中文文檔翻譯不是最新版,請訪問英文版本查看最新內容,或" - }, - "outdated.help": { - "message": "幫助我們翻譯" - } -} \ No newline at end of file diff --git a/i18n/zh-tw/docusaurus-plugin-content-docs/version-1.22/installation/windows-service.md b/i18n/zh-tw/docusaurus-plugin-content-docs/version-1.22/installation/windows-service.md index 1f917562..cf5a5dcd 100644 --- a/i18n/zh-tw/docusaurus-plugin-content-docs/version-1.22/installation/windows-service.md +++ b/i18n/zh-tw/docusaurus-plugin-content-docs/version-1.22/installation/windows-service.md @@ -8,6 +8,8 @@ aliases: - /zh-tw/windows-service --- +# 註冊為 Windows 服務 + ## 準備工作 在 C:\gitea\custom\conf\app.ini 中進行了以下更改: diff --git a/i18n/zh-tw/docusaurus-plugin-content-docs/version-1.22/usage/actions/variables.md b/i18n/zh-tw/docusaurus-plugin-content-docs/version-1.22/usage/actions/variables.md index 9d6450c1..5fd27d00 100644 --- a/i18n/zh-tw/docusaurus-plugin-content-docs/version-1.22/usage/actions/variables.md +++ b/i18n/zh-tw/docusaurus-plugin-content-docs/version-1.22/usage/actions/variables.md @@ -6,7 +6,7 @@ sidebar_position: 25 --- -## 變量 +# 變量 您可以建立使用者、組織和儲存庫級別的變量。變量的級別取決於建立它的位置。當建立變量時,變量的名稱會被 轉換為大寫,在yaml文件中引用時需要使用大寫。 diff --git a/i18n/zh-tw/docusaurus-theme-classic/footer.json b/i18n/zh-tw/docusaurus-theme-classic/footer.json deleted file mode 100644 index 42698d79..00000000 --- a/i18n/zh-tw/docusaurus-theme-classic/footer.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "link.title.Docs": { - "message": "文件", - "description": "The title of the footer links column with title=Docs in the footer" - }, - "link.title.Community": { - "message": "社區", - "description": "The title of the footer links column with title=Community in the footer" - }, - "link.title.More": { - "message": "更多", - "description": "The title of the footer links column with title=More in the footer" - }, - "link.item.label.Tutorial": { - "message": "教學", - "description": "The label of footer link with label=Tutorial linking to /" - }, - "link.item.label.Code": { - "message": "開源程式碼", - "description": "The label of footer link with label=Code linking to https://github.com/go-gitea/gitea" - }, - "link.item.label.Stack Overflow": { - "message": "Stack Overflow", - "description": "The label of footer link with label=Stack Overflow linking to https://stackoverflow.com/questions/tagged/gitea" - }, - "link.item.label.Discord": { - "message": "Discord", - "description": "The label of footer link with label=Discord linking to https://discord.gg/gitea" - }, - "link.item.label.Twitter": { - "message": "Twitter", - "description": "The label of footer link with label=Twitter linking to https://twitter.com/giteaio" - } -} diff --git a/i18n/zh-tw/docusaurus-theme-classic/navbar.json b/i18n/zh-tw/docusaurus-theme-classic/navbar.json deleted file mode 100644 index b698cca9..00000000 --- a/i18n/zh-tw/docusaurus-theme-classic/navbar.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "title": { - "message": "Gitea" - }, - "item.label.Docs": { - "message": "文件" - }, - "item.label.Code": { - "message": "開源程式碼" - }, - "item.label.Support": { - "message": "支援" - }, - "item.label.Blog": { - "message": "部落格" - } -} diff --git a/package.json b/package.json index d113efc7..e0cee18a 100644 --- a/package.json +++ b/package.json @@ -3,53 +3,15 @@ "version": "0.0.0", "private": true, "scripts": { - "docusaurus": "docusaurus", - "start": "docusaurus start", - "start-CSRApi": "cross-env API_SSR='false' docusaurus start", - "build": "docusaurus build", - "build-CSRApi": "cross-env API_SSR='false' docusaurus build", - "swizzle": "docusaurus swizzle", - "deploy": "docusaurus deploy", - "clear": "docusaurus clear", - "serve": "docusaurus serve", - "write-translations": "docusaurus write-translations", - "write-heading-ids": "docusaurus write-heading-ids" - }, - "dependencies": { - "@docusaurus/core": "3.10.2", - "@docusaurus/faster": "3.10.2", - "@docusaurus/plugin-content-docs": "3.10.2", - "@docusaurus/preset-classic": "3.10.2", - "@easyops-cn/docusaurus-search-local": "0.55.3", - "@emotion/react": "11.14.0", - "@emotion/styled": "11.14.1", - "@mdx-js/react": "3.1.1", - "@mui/material": "9.2.0", - "clsx": "2.1.1", - "docusaurus-plugin-plausible": "0.0.5", - "prism-react-renderer": "2.4.1", - "react": "19.2.8", - "react-dom": "19.2.8", - "redocusaurus": "2.5.2" - }, - "devDependencies": { - "@docusaurus/module-type-aliases": "3.10.2", - "cross-env": "10.1.0" - }, - "browserslist": { - "production": [ - ">0.5%", - "not dead", - "not op_mini all" - ], - "development": [ - "last 1 chrome version", - "last 1 firefox version", - "last 1 safari version" - ] + "dev": "pnpm --filter @gitea-docs/site dev", + "dev:en-latest": "pnpm --filter @gitea-docs/site dev:en-latest", + "build": "pnpm --filter @gitea-docs/site build", + "preview": "pnpm --filter @gitea-docs/site preview", + "check": "pnpm --filter @gitea-docs/site check", + "cut-version": "node scripts/cut-version.mjs" }, "engines": { - "node": ">=18" + "node": ">=22" }, "packageManager": "pnpm@11.20.0" } diff --git a/packages/content-loader/package.json b/packages/content-loader/package.json new file mode 100644 index 00000000..337fd5f3 --- /dev/null +++ b/packages/content-loader/package.json @@ -0,0 +1,19 @@ +{ + "name": "@gitea-docs/content-loader", + "version": "0.0.0", + "private": true, + "type": "module", + "exports": { + ".": "./src/index.ts", + "./products": "./src/products.ts", + "./segments": "./src/segments.ts", + "./sidebar": "./src/sidebar.ts" + }, + "dependencies": { + "tinyglobby": "0.2.15", + "yaml": "2.9.0" + }, + "peerDependencies": { + "astro": "^7.0.2" + } +} diff --git a/packages/content-loader/src/categories.ts b/packages/content-loader/src/categories.ts new file mode 100644 index 00000000..681b36cb --- /dev/null +++ b/packages/content-loader/src/categories.ts @@ -0,0 +1,64 @@ +import { promises as fs } from 'node:fs'; +import path from 'node:path'; +import type { Segment } from './segments.js'; + +/** `_category_.json`, the docusaurus per directory sidebar metadata. */ +export interface CategoryMeta { + label?: string; + position?: number; + collapsed?: boolean; + link?: { + type?: string; + slug?: string; + title?: string; + description?: string; + }; +} + +export const categoryFile = '_category_.json'; + +export async function readCategoryMeta(dir: string): Promise { + try { + return JSON.parse(await fs.readFile(path.join(dir, categoryFile), 'utf-8')) as CategoryMeta; + } catch { + return undefined; + } +} + +/** Fallback label for a directory without `_category_.json`. */ +export function labelFromDirname(name: string): string { + return name + .split('-') + .map((part) => part.charAt(0).toUpperCase() + part.slice(1)) + .join(' '); +} + +export function slugifyLabel(label: string): string { + return label + .toLowerCase() + .replace(/[^a-z0-9]+/g, '-') + .replace(/^-+|-+$/g, ''); +} + +/** + * Route id of the index page docusaurus generates for a category. + * + * Top level categories are declared by `sidebars.js` without a slug and end up + * under `/category/