diff --git a/.gitea/scoped_workflows/publish-wiki.yml b/.gitea/scoped_workflows/publish-wiki.yml index 305b2ec..4537510 100644 --- a/.gitea/scoped_workflows/publish-wiki.yml +++ b/.gitea/scoped_workflows/publish-wiki.yml @@ -1,5 +1,10 @@ name: Publish wiki +# DEPRECATED (ADR-0009, MIL-008): repositories publish their wiki by calling +# the reusable workflow publish-wiki-pages.yml. This scoped workflow stays +# until every repository that has wiki/.publish has migrated; it is then +# removed in a later major release. + # Shared through scoped delivery: it runs in every repository of an # organization, but writes only where the repository has opted in with # wiki/.publish (ADR-0004). TOKEN_FOR_GITEA_WIKI is read from the organization diff --git a/.gitea/workflows/publish-own-wiki.yml b/.gitea/workflows/publish-own-wiki.yml new file mode 100644 index 0000000..228fff4 --- /dev/null +++ b/.gitea/workflows/publish-own-wiki.yml @@ -0,0 +1,25 @@ +name: Publish own wiki + +# Publishes the wiki of this repository from docs/wiki/ by calling the +# reusable workflow of this repository (ADR-0009, MIL-008 task 4). It is the +# caller a project copies from framework/templates/ci/publish-wiki.yml, with +# two differences: the reusable workflow is called by its local path, and +# tools-ref is main so that the script that is run is the one of this commit. +on: + push: + branches: [ main ] + paths: + - "docs/wiki/**" + workflow_dispatch: + +jobs: + wiki: + permissions: + contents: read + uses: ./.gitea/workflows/publish-wiki-pages.yml + with: + wiki_dir: docs/wiki + prune: "true" + tools-ref: main + secrets: + TOKEN_FOR_GITEA_WIKI: ${{ secrets.TOKEN_FOR_GITEA_WIKI }} diff --git a/.gitea/workflows/publish-wiki-pages.yml b/.gitea/workflows/publish-wiki-pages.yml new file mode 100644 index 0000000..d9e2b45 --- /dev/null +++ b/.gitea/workflows/publish-wiki-pages.yml @@ -0,0 +1,64 @@ +name: Publish wiki + +# Reusable workflow (ADR-0009, MIL-008). A repository calls it with +# +# on: +# push: +# branches: [ main ] +# paths: [ "docs/wiki/**" ] +# jobs: +# wiki: +# uses: TirSystem/github-action/.gitea/workflows/publish-wiki-pages.yml@v1 +# secrets: +# TOKEN_FOR_GITEA_WIKI: ${{ secrets.TOKEN_FOR_GITEA_WIKI }} +# +# The caller file is the opt-in; there is no marker file. It publishes the +# Markdown pages of wiki_dir to the wiki of the calling repository, creating +# and updating pages, and deleting pages that are not in the folder only when +# prune is true. The script is a file of this repository +# (tools/publish_wiki.py), fetched at tools-ref. +on: + workflow_call: + inputs: + wiki_dir: + description: "Directory, relative to the repository root, with the wiki pages" + type: string + default: "docs/wiki" + prune: + description: "true deletes wiki pages that are not in the folder; false keeps them" + type: string + default: "false" + tools-ref: + description: "Tag or branch of TirSystem/github-action whose tools/publish_wiki.py is run; pin it to the exact tag together with the workflow" + type: string + default: "v1" + secrets: + TOKEN_FOR_GITEA_WIKI: + description: "Gitea token with write access to the wiki of the calling repository" + required: true + +jobs: + publish-wiki: + permissions: + contents: read + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - name: Check out the repository + uses: actions/checkout@v4.2.2 + + - name: Fetch the shared script + uses: actions/checkout@v4.2.2 + with: + repository: TirSystem/github-action + ref: ${{ inputs.tools-ref }} + path: shared-scripts + + - name: Publish the pages to the wiki + env: + GITEA_API_URL: ${{ gitea.api_url }} + SOURCE_REPOSITORY: ${{ gitea.repository }} + WIKI_CREDENTIALS: ${{ secrets.TOKEN_FOR_GITEA_WIKI }} + WIKI_DIR: ${{ inputs.wiki_dir }} + WIKI_PRUNE: ${{ inputs.prune }} + run: python3 shared-scripts/tools/publish_wiki.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 58d2b44..969126c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,39 @@ Each release lists its changes in these groups, in this order: ## [Unreleased] +## [1.2.2] - 2026-10-13 + +### Added + +- Reusable workflow `publish-wiki-pages.yml` (ADR-0009): publishes the Markdown + pages of a folder to the wiki of the calling repository. The call is the + opt-in and no `wiki/.publish` marker is read. Inputs: `wiki_dir` (default + `docs/wiki`), `prune` (`"true"` deletes wiki pages that are not in the folder, + default `"false"`) and `tools-ref` (default `v1`); the secret + `TOKEN_FOR_GITEA_WIKI` is declared by the workflow and passed by the caller, + with no fallback to another token. A missing folder is a configuration error, + and an empty folder never deletes pages. A caller template is + `templates/ci/publish-wiki.yml` of the SQA and QC framework. +- Environment variable `WIKI_PRUNE` of `tools/publish_wiki.py`: when it is set the + marker is not read. Without it the script behaves as before, so the scoped + workflow is unchanged. + +### Changed + +- The scoped workflow `publish-wiki.yml` is deprecated. It still publishes the + eight repositories that have `wiki/.publish` (checked on 2026-10-13) and is not + removed in this release; it is removed, with their migration, in a later major + release. +- The wiki of this repository moves from `wiki/` to `docs/wiki/` and is published + through the new workflow by `publish-own-wiki.yml`. `tools/build_wiki.py` + writes to `docs/wiki/`. No change for callers of the other workflows. +- The onboarding, credentials and troubleshooting guides and their wiki pages + (English, Danish, Bahasa Malaysia) describe the caller, `docs/wiki/`, the + `prune` and `wiki_dir` inputs and the two new error messages. +- Release type: this is a patch release by the owner's decision (S01, MIL-008), + although ADR-0006 classes a new workflow as minor. Nothing is removed or + renamed, so no caller breaks. + ## [1.2.1] - 2026-10-13 ### Changed diff --git a/README.md b/README.md index b1b6417..ddb37cf 100644 --- a/README.md +++ b/README.md @@ -17,19 +17,21 @@ A collection of reusable Gitea Actions workflows for DevOps professionals and so This repository is the central collection of reusable automation for TirSystem repositories. The primary repository lives at `git.tirsystem.com` (Gitea) and is push-mirrored to GitHub. -It contains eight workflows: metadata sync to the GitHub mirror, wiki publishing, shared quality checks for Python and shell, for C and C++ and for C#, a release workflow, the publishing of accepted milestones and the repository's own validation. They are listed with their purpose and a diagram under [Workflows](#-workflows). +It contains ten workflows: metadata sync to the GitHub mirror, wiki publishing (scoped, and reusable for repositories that call it), shared quality checks for Python and shell, for C and C++ and for C#, a release workflow, the publishing of accepted milestones and the repository's own validation. They are listed with their purpose and a diagram under [Workflows](#-workflows). ## 🔧 Workflows -Eight workflows live in this repository. A **scoped** workflow is delivered by the instance to every repository of the TirSystem organizations and needs nothing in the repository; a **reusable** workflow is called by a repository with `uses:`; the others run only here. The diagrams are PlantUML source. +Ten workflows live in this repository. A **scoped** workflow is delivered by the instance to every repository of the TirSystem organizations and needs nothing in the repository; a **reusable** workflow is called by a repository with `uses:`; the others run only here. The diagrams are PlantUML source. | Workflow | File | Kind | Starts on | Purpose | | --- | --- | --- | --- | --- | | Sync GitHub mirror metadata | [`sync-github-metadata.yml`](.gitea/scoped_workflows/sync-github-metadata.yml) | Scoped | push to `main`, manual, daily 03:17 UTC | Copies the description and topics of a Gitea repository to its GitHub push mirror | -| Publish wiki | [`publish-wiki.yml`](.gitea/scoped_workflows/publish-wiki.yml) | Scoped, opt-in with `wiki/.publish` | push to `main` that changes `wiki/**`, manual | Publishes the pages in `wiki/` to the repository wiki | +| Publish wiki | [`publish-wiki.yml`](.gitea/scoped_workflows/publish-wiki.yml) | Scoped, opt-in with `wiki/.publish`; deprecated, replaced by the reusable workflow below (ADR-0009) | push to `main` that changes `wiki/**`, manual | Publishes the pages in `wiki/` to the repository wiki | +| Publish wiki pages | [`publish-wiki-pages.yml`](.gitea/workflows/publish-wiki-pages.yml) | Reusable (`workflow_call`) | a call from another repository | Publishes the pages in `docs/wiki/` (or the folder named by `wiki_dir`) to the wiki of the calling repository | | Quality checks | [`quality-checks.yml`](.gitea/workflows/quality-checks.yml) | Reusable (`workflow_call`) | a call from another repository | Runs ruff, mypy, shellcheck and shfmt on the tracked files and changes nothing | | Quality checks C++ | [`quality-checks-cpp.yml`](.gitea/workflows/quality-checks-cpp.yml) | Reusable (`workflow_call`) | a call from another repository | Runs clang-format and clang-tidy at exact versions on the tracked C and C++ files and changes nothing | | Quality checks C# | [`quality-checks-csharp.yml`](.gitea/workflows/quality-checks-csharp.yml) | Reusable (`workflow_call`) | a call from another repository | Runs `dotnet format` and `dotnet build` on an exact .NET SDK 10 or later and changes nothing | +| Publish own wiki | [`publish-own-wiki.yml`](.gitea/workflows/publish-own-wiki.yml) | This repository only | push to `main` that changes `docs/wiki/**`, manual | Calls the reusable Publish wiki pages workflow for the wiki of this repository | | Release | [`release.yml`](.gitea/workflows/release.yml) | This repository only | manual | Creates the version tag, the release page and the major tag after the checks | | Publish accepted milestones | [`sync-milestones.yml`](.gitea/workflows/sync-milestones.yml) | This repository only | push to `main` that changes `docs/milestones/**` or `docs/sqa/reviews/**`, manual (dry run by default) | Creates or updates the Gitea milestone and issues of every milestone that is Accepted with a Go review | | Validate workflows | [`validate-workflows.yml`](.gitea/workflows/validate-workflows.yml) | This repository only | pull request, push to `main`, manual | Parses every workflow and runs the offline tests | @@ -100,7 +102,7 @@ deactivate Workflow @enduml ``` -### 📖 Publish wiki +### 📖 Publish wiki (scoped, deprecated) Publishes `wiki/` to the repository wiki, only in a repository that has opted in with `wiki/.publish`. The word `prune` in that file also deletes pages that are not in `wiki/`. @@ -329,6 +331,90 @@ deactivate Workflow @enduml ``` +### 📖 Publish wiki pages + +A reusable workflow (ADR-0009). A repository calls it from its own workflow, so the call is the opt-in and no marker file is needed. It publishes the Markdown pages of `wiki_dir` (default `docs/wiki`) to the wiki of the calling repository, and deletes pages that are not in the folder only when `prune` is `true`. + +```yaml +on: + push: + branches: [ main ] + paths: [ "docs/wiki/**" ] +jobs: + wiki: + uses: TirSystem/github-action/.gitea/workflows/publish-wiki-pages.yml@v1 + secrets: + TOKEN_FOR_GITEA_WIKI: ${{ secrets.TOKEN_FOR_GITEA_WIKI }} +``` + +#### 🔀 Workflow + +```plantuml +@startuml +title Publish docs/wiki to the wiki of the calling repository + +autonumber + +actor "Calling repository\nuses: ...publish-wiki-pages.yml@v1" as Caller +participant "Gitea Actions\npublish-wiki-pages" as Workflow +participant "shared-scripts\n(tools/publish_wiki.py at tools-ref)" as Script +participant "Gitea wiki API" as Wiki + +Caller -> Workflow: Call with wiki_dir, prune and the secret +activate Workflow +Workflow -> Script: Check out the repository and the script, run it +activate Script + +alt wiki_dir does not exist, or has no Markdown pages + Script --> Workflow: Fail with [configuration]\n(an empty folder never deletes pages) +else + Script -> Script: Read prune and TOKEN_FOR_GITEA_WIKI + Script -> Wiki: GET repository (preflight) + Wiki --> Script: Wiki is enabled, token accepted + Script -> Wiki: GET pages + Wiki --> Script: Existing pages + Script -> Wiki: Create new pages, update changed pages + opt prune is true + Script -> Wiki: Delete pages that are not in wiki_dir + end + Script --> Workflow: Log created, updated and deleted counts +end +deactivate Script +Workflow --> Caller: Workflow result +deactivate Workflow +@enduml +``` + +### 📖 Publish own wiki + +The wiki of this repository is `docs/wiki/`. This workflow calls the reusable workflow above by its local path, with `prune` set to `true` so the wiki always equals the folder and `tools-ref` set to `main` so that the script of the same commit runs. It is the caller that a project copies from the framework's `templates/ci/publish-wiki.yml`. + +#### 🔀 Workflow + +```plantuml +@startuml +title Publish the wiki of this repository (docs/wiki) + +autonumber + +actor "Push to main that changes docs/wiki/**,\nor manual trigger" as Trigger +participant "Gitea Actions\npublish-own-wiki" as Caller +participant "Gitea Actions\npublish-wiki-pages\n(called by its local path)" as Workflow +participant "Gitea wiki API" as Wiki + +Trigger -> Caller: Start workflow +activate Caller +Caller -> Workflow: Call with wiki_dir docs/wiki, prune true,\ntools-ref main and TOKEN_FOR_GITEA_WIKI +activate Workflow +Workflow -> Wiki: Create, update and delete pages\nso the wiki equals docs/wiki +Wiki --> Workflow: Done +Workflow --> Caller: Workflow result +deactivate Workflow +Caller --> Trigger: Workflow result +deactivate Caller +@enduml +``` + ### 📌 Publish accepted milestones Standing authorization to publish: on a push to `main` that changes the milestones or their reviews, every milestone whose latest Version History row is Accepted and whose latest review is a Go is created or updated on Gitea with its tasks as issues. Nothing is closed or deleted. A manual run is a dry run unless `dry_run` is switched off. It uses the secret `TOKEN_FOR_GITEA` and the `--accepted-only` rule of the mounted framework (v0.5.0 or later). @@ -456,7 +542,8 @@ Rows that say Implemented or Guides written exist today. The rest is planned and | Synchronize repository metadata (Gitea to GitHub mirror) | Implemented in `.gitea/scoped_workflows/`, with offline tests and a validation workflow | | Configure and validate workflow credentials | Implemented for the sync workflow: preflight checks both tokens before any change ([guide](guides/credentials.md)) | | Onboard a repository, manage runners, diagnose failures | Guides written ([onboarding](guides/onboarding.md), [troubleshooting](guides/troubleshooting.md)); scoped delivery to the repositories of all four organizations verified (MIL-002) | -| Publish a repository wiki from `wiki/` (opt-in, delivered to every organization) | Implemented in `.gitea/scoped_workflows/publish-wiki.yml`, with offline tests; a pilot in a second repository publishes its wiki (MIL-006) | +| Publish a repository wiki from `wiki/` (opt-in, delivered to every organization) | Implemented in `.gitea/scoped_workflows/publish-wiki.yml`, with offline tests; a pilot in a second repository publishes its wiki (MIL-006); being replaced by the reusable workflow below (ADR-0009) | +| Publish a repository wiki from `docs/wiki/` through a called workflow | Implemented as the reusable workflow `.gitea/workflows/publish-wiki-pages.yml`, with offline tests; this repository's own wiki is in `docs/wiki/` and published by it through `publish-own-wiki.yml`; not yet called from another repository (MIL-008) | | Shared quality checks (Python and shell) | Implemented as the reusable workflow `.gitea/workflows/quality-checks.yml`, with offline tests and a trial in a second organization; adopted in RepoFoundry ([guide](guides/quality-checks.md)) | | Shared quality checks (C and C++, C#) | Implemented as the reusable workflows `.gitea/workflows/quality-checks-cpp.yml` and `.gitea/workflows/quality-checks-csharp.yml` with exact tool versions and offline tests; not yet used in another repository (MIL-007) ([C and C++ guide](guides/quality-checks-cpp.md), [C# guide](guides/quality-checks-csharp.md)) | | Versioned release and publishing | Release process, changelog and upgrade guide defined; the release workflow exists and `v1.0.0` is released (MIL-004) ([guide](guides/upgrading.md)) | diff --git a/docs/adr/adr-0009-wiki-publishing-reusable-workflow.md b/docs/adr/adr-0009-wiki-publishing-reusable-workflow.md new file mode 100644 index 0000000..a5383ff --- /dev/null +++ b/docs/adr/adr-0009-wiki-publishing-reusable-workflow.md @@ -0,0 +1,93 @@ +# ADR-0009: Wiki publishing as a reusable workflow + +## Metadata +| Key | Value | +| --- | --- | +| ID | ADR-0009 | +| CrossReference | [MIL-008], [ADR-0003], [ADR-0004], [ADR-0005], [ADR-0006] | + +## Version History +| Date | Status | Author | Reviewer | Change | Commit | +| --- | --- | --- | --- | --- | --- | +| 2026-10-13 | Proposed | Jens Tirsvad Nielsen | S01 | Initial version | [01b9c29] | + +Allowed Status values: `Proposed`, `Accepted`, `Rejected`, `Deprecated`, `Superseded by ADR-NNNN`. + +--- + +## Context + +[ADR-0004] chose a scoped workflow to publish wikis: Gitea runs it in every +repository of an organisation, and a marker file `wiki/.publish` is the opt-in. +That avoids a copy of the workflow, but it runs where nobody asked for it and +needs a safety gate for that reason; its trigger path (`wiki/**`) and the +version of the script (`v1`) are fixed centrally. The framework now prescribes +the wiki in `docs/wiki/` with English and the PO language as a minimum, and +repositories need to say where their wiki is. + +Options: + +1. **Keep the scoped workflow and read both folders.** No file in consumers, + but the central trigger lists every location and the gate stays. +2. **A reusable workflow (`workflow_call`) that each repository calls.** One + source in this repository, called as `uses: ...@v1` the way + `quality-checks` and `release` already are ([ADR-0005], [ADR-0006]). The + caller sets its own trigger paths and the folder. + +## Decision + +Wiki publishing is the reusable workflow `publish-wiki-pages.yml`, called by +each repository that wants a published wiki; the caller file is the opt-in and +`docs/wiki/` is the default folder. The scoped `publish-wiki.yml` and the +`wiki/.publish` marker are deprecated and stay until every publishing repository +has a caller; they are then removed in a later major release. + +The rules that follow from it: + +- Inputs: `wiki_dir` (default `docs/wiki`), `prune` (default `false`) and + `tools-ref` (default `v1`). The secret `TOKEN_FOR_GITEA_WIKI` is declared and + passed by the caller; there is no fallback to another token. +- With the reusable workflow the marker is not read: the script treats the + `prune` input as the setting, and a missing folder is a configuration error + rather than a skip, because the caller asked for it. +- The script, the page-title rules, the empty-folder protection and the error + categories of [ADR-0004] and [ADR-0003] are unchanged. + +## Consequences + +**Positive:** + +- A repository states its own folder and trigger paths, so the wiki can move + to `docs/wiki/` one repository at a time. +- Opting in is a file in the repository, reviewed in a pull request, and a + repository without a caller is never written to. +- One call convention for every shared workflow of this repository. + +**Negative:** + +- Every publishing repository needs a caller file, and the removal of the + scoped workflow stops publishing in any repository that still relies on the + marker; the list of those repositories is taken before the removal. +- Eight repositories still publish through the scoped workflow (checked on + 2026-10-13), so it is deprecated and not removed here; removing it is a + breaking change under [ADR-0006] and belongs to a follow-up milestone with + their migrations. +- The owner chose a patch release (1.2.2) for this change although a new + workflow is a minor one under [ADR-0006]; the changelog states the deviation. +- Passing a declared secret through `workflow_call` is not yet verified on this + Gitea instance; it is checked by the first call, in this repository. + +## Affected Artifacts + +- [MIL-008] — the plan this decision belongs to. +- [ADR-0004] — its scoped delivery and marker parts are replaced once the + scoped workflow is removed; its token and safety rules stand. + +--- + +[MIL-008]: ../milestones/mil-008-wiki-reusable-workflow.md +[ADR-0003]: ./adr-0003-wiki-publish-token.md +[ADR-0004]: ./adr-0004-shared-wiki-publishing-opt-in.md +[ADR-0006]: ./adr-0006-release-process-and-version-pinning.md +[ADR-0005]: ./adr-0005-quality-check-contract.md +[01b9c29]: https://git.tirsystem.com/TirSystem/github-action/commit/01b9c2972b4317bcc590540010aea0eaf7f30014 diff --git a/docs/artifact-registry.md b/docs/artifact-registry.md index cd4c561..5a2de19 100644 --- a/docs/artifact-registry.md +++ b/docs/artifact-registry.md @@ -10,10 +10,10 @@ each document lives in *this* project and the next version to use. | BC | Business Case | docs/business-case.md | 002 | | SA | Stakeholder Analysis | docs/stakeholder-analysis.md | 002 | | PP | Project Plan | docs/project-plan.md | 002 | -| MIL | Milestone / Gateway | docs/milestones/*.md | 008 | -| RC | SQA Review Record | docs/sqa/reviews/rc-*.md | 060 | +| MIL | Milestone / Gateway | docs/milestones/*.md | 009 | +| RC | SQA Review Record | docs/sqa/reviews/rc-*.md | 062 | | TM | Traceability Matrix | docs/sqa/traceability-matrix.md | 002 | -| ADR | Architecture Decision Record | docs/adr/adr-NNNN-*.md | 0009 | +| ADR | Architecture Decision Record | docs/adr/adr-NNNN-*.md | 0010 | | UCD | Use Case Diagram | docs/use-case-diagram.md | 002 | | US | User Story | docs/user-stories.md | 002 | | UC | Use Case | docs/uc-NNN/uc.md | 008 | diff --git a/docs/milestones/mil-008-wiki-reusable-workflow.md b/docs/milestones/mil-008-wiki-reusable-workflow.md new file mode 100644 index 0000000..ea40173 --- /dev/null +++ b/docs/milestones/mil-008-wiki-reusable-workflow.md @@ -0,0 +1,86 @@ +# MIL-008: Wiki publishing as a reusable workflow + +## Metadata +| Key | Value | +| --- | --- | +| ID | MIL-008 | +| CrossReference | [BC-001], [MIL-006], [ADR-0004], [RC-060], [RC-061] | + +## Version History +| Date | Status | Author | Reviewer | Change | Commit | +| --- | --- | --- | --- | --- | --- | +| 2026-10-13 | Deprecated | Jens Tirsvad Nielsen | S01 | Initial version; reviewed (RC-060) | [01b9c29] | +| 2026-10-13 | Accepted | Jens Tirsvad Nielsen | S01 | Task 5 changed to deprecate the scoped workflow (8 repositories still use it); reviewed (RC-061) | [01b9c29] | + +--- + +## Purpose + +Decide whether the wiki can be published by a reusable workflow that each +repository calls, from `docs/wiki/` (the location `process/wiki.md` of the +framework prescribes), instead of a scoped workflow that runs in every +repository of the organisation and reads `wiki/`. + +## Deliverable + +A reusable workflow `publish-wiki-pages.yml` in `.gitea/workflows/` with a +`wiki_dir` input, a caller template for projects, offline tests, a superseding +ADR, updated guides and wiki pages, this repository publishing its own wiki +from `docs/wiki/` through it, the scoped workflow marked deprecated (not +removed), and a release that projects can pin. + +## Go / No-Go Criteria + +| # | Criterion (objectively checkable) | Go | No-Go | +| --- | --- | --- | --- | +| 1 | The reusable workflow publishes the folder named by `wiki_dir` (default `docs/wiki`), and a repository that has no caller workflow is never written to | Offline tests pass; no caller means no run | Any write without a caller | +| 2 | An empty or missing folder never deletes pages, the failure names its category, and the secret is passed explicitly (criteria 1 and 4 of MIL-006 still hold) | Existing tests pass unchanged | A regression | +| 3 | This repository publishes its own wiki from `docs/wiki/` through a caller that uses the reusable workflow, and the pages on the host equal the folder | 0 differences read back through the API | Pages differ or the run fails | +| 4 | A caller template exists for projects, with the trigger `docs/wiki/**` and the secret named | File exists and is linted (QC-WF-001) | Missing | +| 5 | The scoped `publish-wiki.yml` is marked deprecated in its header, the README and ADR-0009, and the repositories that still use it are listed; it is not removed here | Notice present and the list recorded (8 repositories on 2026-10-13) | No notice, or the workflow was removed while a repository still depends on it | +| 6 | The change is released as patch 1.2.2 and the moving major tag points at it | `v1` includes the change | Not released | + +## Dependencies + +| Depends on | Reason | +| --- | --- | +| MIL-006 | The publisher script, the prune rule and the safety limits come from it | +| `TirSystem/sqa-qc-framework` `process/wiki.md` | Defines `docs/wiki/` and the English plus PO language minimum; unmerged when this was written | + +## Traceability + +| Business Case objective / KPI / user story | Reference | +| --- | --- | +| O2, O3 | [BC-001] | + +## Ownership + +| Role | Stakeholder ID (SA) | +| --- | --- | +| Owner | S05 | +| Approving reviewer | S01 | + +## Target Date + +2026-11-15 — the Business Case sets no deadline. + +## Tasks + +| # | Task | Summary | Needs its own Use Case/User Story? | Reference | +| --- | --- | --- | --- | --- | +| 1 | Record the decision | An ADR that supersedes the scoped-delivery part of ADR-0004: publishing is a reusable workflow called by each repository; the caller file is the opt-in, so `wiki/.publish` is no longer a gate; the `prune` setting becomes an input. Keep the rest of ADR-0004 (secret handling) as it stands. | No | | +| 2 | Add the reusable workflow | `.gitea/workflows/publish-wiki-pages.yml` with `on: workflow_call`, inputs `wiki_dir` (default `docs/wiki`) and `prune`, and the token as a declared secret. It runs `tools/publish_wiki.py` with `WIKI_DIR` and the prune setting from the inputs. Update the script and its tests: the marker is no longer required. | No | | +| 3 | Add the caller template | A `publish-wiki.yml` caller for projects (`uses: TirSystem/github-action/.gitea/workflows/publish-wiki-pages.yml@v1`, `paths: docs/wiki/**`, `secrets:` mapped). Proposed in `sqa-qc-framework` under `templates/ci/` once this is released. | No | | +| 4 | Move this repository's wiki and call the workflow | `git mv wiki docs/wiki`, check the links and the translation hash comments, add the caller, publish, read the pages back. | No | | +| 5 | Deprecate the scoped workflow | Do not remove it: on 2026-10-13, 8 repositories still publish through it with `wiki/.publish` (`sqa-and-qc`, `sqa-qc-framework`, `sqa-qc-checklists`, `github-action`, `repo-foundry` and three of `Tirsvad-Udemy-100-days-of-code`), and none calls the reusable workflow yet. Add a deprecation notice to its header, the README table and ADR-0009, and record the list. The migrations and the removal are a follow-up milestone after this release (ADR-0006: a removed workflow is a new major). | No | | +| 6 | Update guides and wiki pages | Describe the caller, `docs/wiki/` and the removed marker in the onboarding and credentials guides and in the English, Danish and Bahasa Malaysia pages (rule 8 of `AGENTS.md`). | No | | +| 7 | Release | Release as a patch, 1.2.1 to 1.2.2, as the owner instructed: changelog entry and a release through the release workflow; the `v1` tag moves with it. ADR-0006 classes a new workflow as minor, so the changelog entry states the deviation and the reason. Nothing is removed, so no consumer breaks. | No | | + +--- + +[BC-001]: ../business-case.md +[MIL-006]: ./mil-006-shared-wiki-publishing.md +[ADR-0004]: ../adr/adr-0004-shared-wiki-publishing-opt-in.md +[RC-060]: ../sqa/reviews/rc-060-mil-008-plan.md +[RC-061]: ../sqa/reviews/rc-061-mil-008-task-5-deferred.md +[01b9c29]: https://git.tirsystem.com/TirSystem/github-action/commit/01b9c2972b4317bcc590540010aea0eaf7f30014 diff --git a/docs/sqa/reviews/rc-060-mil-008-plan.md b/docs/sqa/reviews/rc-060-mil-008-plan.md new file mode 100644 index 0000000..3dc7dd0 --- /dev/null +++ b/docs/sqa/reviews/rc-060-mil-008-plan.md @@ -0,0 +1,54 @@ +# Review Record: MIL-008 + +## Metadata +| Key | Value | +| --- | --- | +| ID | RC-060 | +| CrossReference | [MIL-008], [QC-MIL-001] | + +## Version History +| Date | Status | Author | Reviewer | Change | Commit | +| --- | --- | --- | --- | --- | --- | +| 2026-10-13 | Accepted | Jens Tirsvad Nielsen | S01 | Initial version | [01b9c29] | + +--- + +## Artifact Under Review + +- Instance reviewed: [MIL-008] +- Checklist used: [QC-MIL-001] +- Scope: full review +- Language and domain: n/a (technical type) +- Language reviewer: none +- Mode: supervised (S01, the user, accepted the plan in chat on 2026-10-13; the AI prepared the record) + +## Checklist Results + +| # | Criterion | Status | Evidence/Notes | +| --- | --- | --- | --- | +| 1 | A concrete deliverable is defined for every gate | Pass | The Deliverable section names the reusable workflow, the caller template, tests, the superseding ADR, the moved wiki and the release. | +| 2 | Explicit Go/No-Go criteria are stated for each gate | Pass | Six criteria, each with a checkable Go and No-Go (tests, a read-back with 0 differences, the `v1` tag). | +| 3 | Dependencies on other milestones are explicitly mapped | Pass | MIL-006, and the framework's `process/wiki.md`, which is still unmerged and is named as such. | +| 4 | Each milestone is traceable to a Business Case objective or KPI | Pass | O2 and O3 of [BC-001], as for MIL-006. | +| 5 | Milestone owner and approving reviewer are identified | Pass | Owner S05, approving reviewer S01. | +| 6 | Milestone has a defined target date consistent with project constraints | Pass | 2026-11-15; the Business Case sets no deadline and the plan's last decision is 2026-12-26. | + +## Overall Verdict + +Go - all six criteria pass. The release is a patch (1.2.1 to 1.2.2) by the owner's decision, although ADR-0006 classes a new workflow as minor and a removed one as breaking; task 7 records the deviation in the changelog, and S01 chose it over a minor release and over keeping the scoped workflow. + +## Action Items + +| Action | Owner | Due | +| --- | --- | --- | +| Add MIL-008 to the Project Plan (milestone table, CrossReference, dependency graph) and review it | S05 | before the pull request | +| Merge `process/wiki.md` in `sqa-qc-framework` before this repository pins it | S05 | before task 3 ships | +| List the repositories that publish through the scoped workflow before task 5 removes it | S05 | before task 5 | + +--- + +--- + +[MIL-008]: ../../milestones/mil-008-wiki-reusable-workflow.md +[QC-MIL-001]: ../../../framework/qc/artifacts/qc-milestones-gateways.md +[01b9c29]: https://git.tirsystem.com/TirSystem/github-action/commit/01b9c2972b4317bcc590540010aea0eaf7f30014 diff --git a/docs/sqa/reviews/rc-061-mil-008-task-5-deferred.md b/docs/sqa/reviews/rc-061-mil-008-task-5-deferred.md new file mode 100644 index 0000000..ee40f57 --- /dev/null +++ b/docs/sqa/reviews/rc-061-mil-008-task-5-deferred.md @@ -0,0 +1,54 @@ +# Review Record: MIL-008 (task 5 deferred) + +## Metadata +| Key | Value | +| --- | --- | +| ID | RC-061 | +| CrossReference | [MIL-008], [QC-MIL-001], [RC-060] | + +## Version History +| Date | Status | Author | Reviewer | Change | Commit | +| --- | --- | --- | --- | --- | --- | +| 2026-10-13 | Accepted | Jens Tirsvad Nielsen | S01 | Initial version | [01b9c29] | + +--- + +## Artifact Under Review + +- Instance reviewed: [MIL-008] after the amendment of 2026-10-13: task 5 changed from removing the scoped workflow to deprecating it, with the criterion that follows from it +- Checklist used: [QC-MIL-001] +- Scope: delta re-review of the amended task 5, criterion 5 and the Deliverable; the earlier record is [RC-060] +- Language and domain: n/a (technical type) +- Language reviewer: none +- Mode: supervised (S01, the user, chose option 1, defer the removal, in chat on 2026-10-13; the AI prepared the record) + +## Checklist Results + +| # | Criterion | Status | Evidence/Notes | +| --- | --- | --- | --- | +| 1 | A concrete deliverable is defined for every gate | Pass | The Deliverable now says the scoped workflow is marked deprecated, not removed. | +| 2 | Explicit Go/No-Go criteria are stated for each gate | Pass | Criterion 5 is checkable: a notice in the header, the README and ADR-0009, and the list of repositories recorded; No-Go if it was removed while a repository depends on it. | +| 3 | Dependencies on other milestones are explicitly mapped | Pass | Unchanged: MIL-006 and the framework's `process/wiki.md`. | +| 4 | Each milestone is traceable to a Business Case objective or KPI | Pass | Unchanged: O2, O3. | +| 5 | Milestone owner and approving reviewer are identified | Pass | Owner S05, approving reviewer S01. | +| 6 | Milestone has a defined target date consistent with project constraints | Pass | 2026-11-15, unchanged. | + +## Overall Verdict + +Go - all six criteria pass. The amendment follows from a scan on 2026-10-13: 8 repositories still publish through the scoped workflow and none calls the reusable one, so removal would have broken them. Removal and the migrations move to a follow-up milestone that needs its own plan. + +## Action Items + +| Action | Owner | Due | +| --- | --- | --- | +| Plan the follow-up milestone: migrate the 8 repositories (move `wiki/` to `docs/wiki/`, add the caller from `templates/ci/publish-wiki.yml`), then remove the scoped workflow in a major release | S05 | after the 1.2.2 release | +| Add MIL-008 to the Project Plan and review it (open since RC-060) | S05 | before the pull request | + +--- + +--- + +[MIL-008]: ../../milestones/mil-008-wiki-reusable-workflow.md +[QC-MIL-001]: ../../../framework/qc/artifacts/qc-milestones-gateways.md +[RC-060]: ./rc-060-mil-008-plan.md +[01b9c29]: https://git.tirsystem.com/TirSystem/github-action/commit/01b9c2972b4317bcc590540010aea0eaf7f30014 diff --git a/docs/sqa/traceability-matrix.md b/docs/sqa/traceability-matrix.md index 4018571..5574067 100644 --- a/docs/sqa/traceability-matrix.md +++ b/docs/sqa/traceability-matrix.md @@ -4,13 +4,13 @@ | Key | Value | | --- | --- | | ID | TM-001 | -| CrossReference | [BC-001], [SA-001], [PP-001], [MIL-001], [MIL-002], [MIL-003], [MIL-004], [MIL-005], [MIL-006], [MIL-007], [RC-001], [RC-002], [RC-003], [RC-004], [RC-005], [RC-006], [RC-007], [RC-008], [RC-009], [RC-010], [RC-011], [RC-012], [RC-013], [RC-014], [RC-015], [RC-016], [RC-017], [RC-018], [RC-019], [RC-020], [RC-021], [RC-022], [RC-023], [RC-024], [RC-025], [RC-026], [RC-027], [RC-028], [RC-029], [RC-030], [RC-031], [RC-032], [RC-033], [RC-034], [RC-035], [RC-036], [RC-037], [RC-038], [RC-039], [RC-040], [RC-041], [RC-042], [RC-043], [RC-044], [RC-045], [RC-046], [RC-047], [RC-048], [RC-049], [RC-050], [RC-051], [RC-052], [RC-053], [RC-054], [RC-055], [RC-056], [RC-057], [RC-058], [RC-059], [ADR-0007], [ADR-0008], [UC-007], [UC-006], [ADR-0006], [UC-005], [ADR-0005], [UCD-001], [US-001], [UC-001], [UC-002], [UC-003], [UC-004], [ADR-0001], [ADR-0002], [ADR-0003], [ADR-0004] | +| CrossReference | [BC-001], [SA-001], [PP-001], [MIL-001], [MIL-002], [MIL-003], [MIL-004], [MIL-005], [MIL-006], [MIL-007], [MIL-008], [RC-001], [RC-002], [RC-003], [RC-004], [RC-005], [RC-006], [RC-007], [RC-008], [RC-009], [RC-010], [RC-011], [RC-012], [RC-013], [RC-014], [RC-015], [RC-016], [RC-017], [RC-018], [RC-019], [RC-020], [RC-021], [RC-022], [RC-023], [RC-024], [RC-025], [RC-026], [RC-027], [RC-028], [RC-029], [RC-030], [RC-031], [RC-032], [RC-033], [RC-034], [RC-035], [RC-036], [RC-037], [RC-038], [RC-039], [RC-040], [RC-041], [RC-042], [RC-043], [RC-044], [RC-045], [RC-046], [RC-047], [RC-048], [RC-049], [RC-050], [RC-051], [RC-052], [RC-053], [RC-054], [RC-055], [RC-056], [RC-057], [RC-058], [RC-059], [RC-060], [ADR-0007], [ADR-0008], [UC-007], [UC-006], [ADR-0006], [UC-005], [ADR-0005], [UCD-001], [US-001], [UC-001], [UC-002], [UC-003], [UC-004], [ADR-0001], [ADR-0002], [ADR-0003], [ADR-0004] | ## Version History | Date | Status | Author | Reviewer | Change | Commit | | --- | --- | --- | --- | --- | --- | -| 2026-10-13 | Proposed | Jens Tirsvad Nielsen | S01 | Added RC-058 (MIL-006 task 6 amendment) | [8051cc4] | | 2026-10-13 | Proposed | Jens Tirsvad Nielsen | S01 | Added RC-059 (MIL-007 task 7 results) | [2481c26] | +| 2026-10-13 | Proposed | Jens Tirsvad Nielsen | S01 | Added MIL-008, RC-060 and RC-061 | [01b9c29] | --- @@ -40,6 +40,7 @@ updated whenever an artifact instance is created or reviewed. | [MIL-005] | MIL | [BC-001], [PP-001], [MIL-002] | [MIL-006] | [RC-010], [RC-011], [RC-030], [RC-050] | | [MIL-006] | MIL | [BC-001], [PP-001], [MIL-002], [MIL-005] | - | [RC-016], [RC-031], [RC-049], [RC-058] | | [MIL-007] | MIL | [BC-001], [PP-001], [MIL-003], [MIL-004], [ADR-0008] | - | [RC-052], [RC-055], [RC-059] | +| [MIL-008] | MIL | [BC-001], [MIL-006], [ADR-0004] | - | [RC-060], [RC-061] | | [RC-007] | RC | [MIL-004] | - | - | | [RC-008] | RC | [BC-001] | - | - | | [RC-009] | RC | [PP-001] | - | - | @@ -110,6 +111,8 @@ updated whenever an artifact instance is created or reviewed. | [RC-057] | RC | [US-001] | - | - | | [RC-058] | RC | [MIL-006] | - | - | | [RC-059] | RC | [MIL-007] | - | - | +| [RC-060] | RC | [MIL-008] | - | - | +| [RC-061] | RC | [MIL-008] | - | - | ## Coverage Notes @@ -130,6 +133,7 @@ updated whenever an artifact instance is created or reviewed. [MIL-005]: ../milestones/mil-005-wiki-and-translations.md [MIL-006]: ../milestones/mil-006-shared-wiki-publishing.md [MIL-007]: ../milestones/mil-007-cpp-csharp-quality-checks.md +[MIL-008]: ../milestones/mil-008-wiki-reusable-workflow.md [RC-001]: ./reviews/rc-001-business-case.md [RC-002]: ./reviews/rc-002-project-plan.md [RC-003]: ./reviews/rc-003-mil-001.md @@ -199,6 +203,8 @@ updated whenever an artifact instance is created or reviewed. [RC-057]: ./reviews/rc-057-us-001-cpp-csharp.md [RC-058]: ./reviews/rc-058-mil-006-task-6.md [RC-059]: ./reviews/rc-059-mil-007-adoption.md +[RC-060]: ./reviews/rc-060-mil-008-plan.md +[RC-061]: ./reviews/rc-061-mil-008-task-5-deferred.md [ADR-0008]: ../adr/adr-0008-cpp-csharp-quality-check-contract.md [ADR-0007]: ../adr/adr-0007-release-publish-destination.md [UC-007]: ../uc-007/uc.md @@ -208,5 +214,5 @@ updated whenever an artifact instance is created or reviewed. [ADR-0005]: ../adr/adr-0005-quality-check-contract.md [faf13b2]: https://git.tirsystem.com/TirSystem/github-action/commit/faf13b2c2a4901c0171977de1ffc2841023f537a [1bc56f8]: https://git.tirsystem.com/TirSystem/github-action/commit/1bc56f8b771531f221f218fc00b147ecc73c051e -[8051cc4]: https://git.tirsystem.com/TirSystem/github-action/commit/8051cc4489ee9bcf3b6c62f2eafcb2013b7d2f90 [2481c26]: https://git.tirsystem.com/TirSystem/github-action/commit/2481c26d802464decd51d75539157093b60e08e8 +[01b9c29]: https://git.tirsystem.com/TirSystem/github-action/commit/01b9c2972b4317bcc590540010aea0eaf7f30014 diff --git a/wiki/Capabilities.da.md b/docs/wiki/Capabilities.da.md similarity index 80% rename from wiki/Capabilities.da.md rename to docs/wiki/Capabilities.da.md index c136509..009b82c 100644 --- a/wiki/Capabilities.da.md +++ b/docs/wiki/Capabilities.da.md @@ -1,4 +1,4 @@ - + > Dette er en oversættelse af [`Capabilities`](Capabilities). Den engelske side er autoritativ, og ændringer her bliver overskrevet, næste gang wikien publiceres. @@ -13,7 +13,8 @@ Rækker, der siger Implementeret eller Vejledninger er skrevet, findes i dag. Re | Synkronisering af repositorymetadata (Gitea til GitHub-spejl) | Implementeret i `.gitea/scoped_workflows/`, med offline-tests og et valideringsworkflow | | Konfiguration og validering af workflow-credentials | Implementeret for synkroniseringsworkflowet: en forhåndskontrol tjekker begge tokens før enhver ændring ([vejledning](Credentials.da)) | | Tilslutning af et repository, administration af runners, fejlfinding | Vejledninger er skrevet ([tilslutning](Onboarding.da), [fejlfinding](Troubleshooting.da)); scoped levering til alle fire organisationers repositories er verificeret (MIL-002) | -| Publicering af et repositorys wiki fra `wiki/` (tilmelding, leveres til alle organisationer) | Implementeret i `.gitea/scoped_workflows/publish-wiki.yml`, med offline-tests; et pilotforsøg i et andet repository publicerer sin wiki (MIL-006) | +| Publicering af et repositorys wiki fra `wiki/` (tilmelding, leveres til alle organisationer) | Implementeret i `.gitea/scoped_workflows/publish-wiki.yml`, med offline-tests; et pilotforsøg i et andet repository publicerer sin wiki (MIL-006); afløses af det genbrugelige workflow nedenfor (ADR-0009) | +| Publicering af et repositorys wiki fra `docs/wiki/` gennem et kaldt workflow | Implementeret som det genbrugelige workflow `.gitea/workflows/publish-wiki-pages.yml`, med offline-tests; dette repositorys egen wiki er i `docs/wiki/` og publiceres af det gennem `publish-own-wiki.yml`; endnu ikke kaldt fra et andet repository (MIL-008) | | Fælles kvalitetskontrol (Python og shell) | Implementeret som det genbrugelige workflow `.gitea/workflows/quality-checks.yml`, med offline-tests og et forsøg i en anden organisation; taget i brug i RepoFoundry ([vejledning](QualityChecksPythonShell.da)) | | Fælles kvalitetskontrol (C og C++, C#) | Implementeret som de genbrugelige workflows `.gitea/workflows/quality-checks-cpp.yml` og `.gitea/workflows/quality-checks-csharp.yml` med præcise værktøjsversioner og offline-tests; endnu ikke brugt i et andet repository (MIL-007) ([vejledning til C og C++](QualityChecksCpp.da), [vejledning til C#](QualityChecksCSharp.da)) | | Versioneret udgivelse og publicering | Udgivelsesproces, changelog og opgraderingsvejledning er defineret; udgivelsesworkflowet findes, og `v1.0.0` er udgivet (MIL-004) ([vejledning](Upgrading.da)) | diff --git a/wiki/Capabilities.md b/docs/wiki/Capabilities.md similarity index 83% rename from wiki/Capabilities.md rename to docs/wiki/Capabilities.md index db4a428..f417638 100644 --- a/wiki/Capabilities.md +++ b/docs/wiki/Capabilities.md @@ -13,7 +13,8 @@ Rows that say Implemented or Guides written exist today. The rest is planned and | Synchronize repository metadata (Gitea to GitHub mirror) | Implemented in `.gitea/scoped_workflows/`, with offline tests and a validation workflow | | Configure and validate workflow credentials | Implemented for the sync workflow: preflight checks both tokens before any change ([guide](Credentials)) | | Onboard a repository, manage runners, diagnose failures | Guides written ([onboarding](Onboarding), [troubleshooting](Troubleshooting)); scoped delivery to the repositories of all four organizations verified (MIL-002) | -| Publish a repository wiki from `wiki/` (opt-in, delivered to every organization) | Implemented in `.gitea/scoped_workflows/publish-wiki.yml`, with offline tests; a pilot in a second repository publishes its wiki (MIL-006) | +| Publish a repository wiki from `wiki/` (opt-in, delivered to every organization) | Implemented in `.gitea/scoped_workflows/publish-wiki.yml`, with offline tests; a pilot in a second repository publishes its wiki (MIL-006); being replaced by the reusable workflow below (ADR-0009) | +| Publish a repository wiki from `docs/wiki/` through a called workflow | Implemented as the reusable workflow `.gitea/workflows/publish-wiki-pages.yml`, with offline tests; this repository's own wiki is in `docs/wiki/` and published by it through `publish-own-wiki.yml`; not yet called from another repository (MIL-008) | | Shared quality checks (Python and shell) | Implemented as the reusable workflow `.gitea/workflows/quality-checks.yml`, with offline tests and a trial in a second organization; adopted in RepoFoundry ([guide](QualityChecksPythonShell)) | | Shared quality checks (C and C++, C#) | Implemented as the reusable workflows `.gitea/workflows/quality-checks-cpp.yml` and `.gitea/workflows/quality-checks-csharp.yml` with exact tool versions and offline tests; not yet used in another repository (MIL-007) ([C and C++ guide](QualityChecksCpp), [C# guide](QualityChecksCSharp)) | | Versioned release and publishing | Release process, changelog and upgrade guide defined; the release workflow exists and `v1.0.0` is released (MIL-004) ([guide](Upgrading)) | diff --git a/wiki/Capabilities.ms.md b/docs/wiki/Capabilities.ms.md similarity index 81% rename from wiki/Capabilities.ms.md rename to docs/wiki/Capabilities.ms.md index 4b60182..2e58ec1 100644 --- a/wiki/Capabilities.ms.md +++ b/docs/wiki/Capabilities.ms.md @@ -1,4 +1,4 @@ - + > Ini ialah terjemahan [`Capabilities`](Capabilities). Halaman bahasa Inggeris ialah teks yang sah, dan perubahan di sini akan ditimpa pada penerbitan wiki yang seterusnya. @@ -13,7 +13,8 @@ Baris yang menyatakan Dilaksanakan atau Panduan telah ditulis wujud hari ini. Se | Menyegerakkan metadata repositori (Gitea ke cermin GitHub) | Dilaksanakan dalam `.gitea/scoped_workflows/`, dengan ujian luar talian dan aliran kerja pengesahan | | Mengkonfigur dan mengesahkan kelayakan (credentials) aliran kerja | Dilaksanakan untuk aliran kerja penyegerakan: semakan awal (preflight) memeriksa kedua-dua token sebelum sebarang perubahan ([panduan](Credentials.ms)) | | Menyertakan repositori, mengurus runner, mendiagnosis kegagalan | Panduan telah ditulis ([menyertakan repositori](Onboarding.ms), [diagnosis](Troubleshooting.ms)); penghantaran scoped ke repositori keempat-empat organisasi telah disahkan (MIL-002) | -| Menerbitkan wiki repositori daripada `wiki/` (pilih menyertai, dihantar ke setiap organisasi) | Dilaksanakan dalam `.gitea/scoped_workflows/publish-wiki.yml`, dengan ujian luar talian; satu juruterbang dalam repositori kedua menerbitkan wikinya (MIL-006) | +| Menerbitkan wiki repositori daripada `wiki/` (pilih menyertai, dihantar ke setiap organisasi) | Dilaksanakan dalam `.gitea/scoped_workflows/publish-wiki.yml`, dengan ujian luar talian; satu juruterbang dalam repositori kedua menerbitkan wikinya (MIL-006); sedang diganti oleh aliran kerja boleh guna semula di bawah (ADR-0009) | +| Menerbitkan wiki repositori daripada `docs/wiki/` melalui aliran kerja yang dipanggil | Dilaksanakan sebagai aliran kerja boleh guna semula `.gitea/workflows/publish-wiki-pages.yml`, dengan ujian luar talian; wiki repositori ini sendiri ada dalam `docs/wiki/` dan diterbitkan olehnya melalui `publish-own-wiki.yml`; belum dipanggil daripada repositori lain (MIL-008) | | Semakan kualiti bersama (Python dan shell) | Dilaksanakan sebagai aliran kerja boleh guna semula `.gitea/workflows/quality-checks.yml`, dengan ujian luar talian dan percubaan dalam organisasi kedua; digunakan dalam RepoFoundry ([panduan](QualityChecksPythonShell.ms)) | | Semakan kualiti bersama (C dan C++, C#) | Dilaksanakan sebagai aliran kerja boleh guna semula `.gitea/workflows/quality-checks-cpp.yml` dan `.gitea/workflows/quality-checks-csharp.yml` dengan versi alat yang tepat dan ujian luar talian; belum digunakan dalam repositori lain (MIL-007) ([panduan C dan C++](QualityChecksCpp.ms), [panduan C#](QualityChecksCSharp.ms)) | | Keluaran berversi dan penerbitan | Proses keluaran, changelog dan panduan naik taraf telah ditakrifkan; aliran kerja keluaran sudah ada dan `v1.0.0` telah dikeluarkan (MIL-004) ([panduan](Upgrading.ms)) | diff --git a/wiki/Credentials.da.md b/docs/wiki/Credentials.da.md similarity index 87% rename from wiki/Credentials.da.md rename to docs/wiki/Credentials.da.md index c540f03..683ee83 100644 --- a/wiki/Credentials.da.md +++ b/docs/wiki/Credentials.da.md @@ -1,4 +1,4 @@ - + > Dette er en oversættelse af [`Credentials`](Credentials). Den engelske side er autoritativ, og ændringer her bliver overskrevet, næste gang wikien publiceres. @@ -56,17 +56,17 @@ Ved succes står der i loggen `Preflight passed: Gitea and GitHub accepted the c ## Secret til publicering af wiki -Workflowet **Publish wiki** kopierer `wiki/` til Gitea-wikien i et repository, der har meldt sig til med `wiki/.publish` (se [onboarding.md](Onboarding.da)). Det bruger sin egen secret, så synkroniseringstokenet forbliver skrivebeskyttet. +Workflowet **Publish wiki pages** kopierer `docs/wiki/` til Gitea-wikien i et repository, der kalder det (se [onboarding.md](Onboarding.da)). Det bruger sin egen secret, så synkroniseringstokenet forbliver skrivebeskyttet. Kalderen sender secreten i `secrets:`; den nedarves ikke. | Secret | Indhold | Bruges til | | --- | --- | --- | | `TOKEN_FOR_GITEA_WIKI` | Gitea-tokenet, intet andet | At skrive wikisiderne for de repositories i en organisation, der melder sig til | -- Gem den som en secret i organisationen for hvert repository, der publicerer. Der er ingen reserve til `TOKEN_FOR_GITEA`: et repository, der har meldt sig til og ikke har secreten, fejler med en konfigurationsfejl, og et repository, der ikke har meldt sig til, behøver den ikke. +- Gem den som en secret i organisationen for hvert repository, der publicerer. Der er ingen reserve til `TOKEN_FOR_GITEA`: et repository, der kalder workflowet og ikke har secreten, fejler med en konfigurationsfejl, og et repository, der ikke kalder det, behøver den ikke. - Tokenet skal have scope `write:repository`, og dets bruger skal have skriveadgang til repositories. Gitea har intet scope kun til wikien, så opret tokenet til en dedikeret bruger. S05 godkender scopet, og S03 gemmer secreten. -- Kald, der foretages: `GET /repos/{owner}/{repo}`, `GET /repos/{owner}/{repo}/wiki/pages`, `GET`, `POST` og `PATCH /repos/{owner}/{repo}/wiki/...` og, for en side, der ikke længere findes i `wiki/`, `DELETE /repos/{owner}/{repo}/wiki/page/{name}`. +- Kald, der foretages: `GET /repos/{owner}/{repo}`, `GET /repos/{owner}/{repo}/wiki/pages`, `GET`, `POST` og `PATCH /repos/{owner}/{repo}/wiki/...` og, for en side, der ikke længere findes i `docs/wiki/`, `DELETE /repos/{owner}/{repo}/wiki/page/{name}`. - Wikien skal være aktiveret i repositoryets indstillinger. Workflowet nægter at køre, hvis den ikke er det. -- Sider, der findes i `wiki/`, overskrives altid fra den, så en ændring i Gitea's weboverflade går tabt ved næste publicering. Sider, der kun findes i wikien, fjernes kun, når `wiki/.publish` indeholder ordet `prune`. +- Sider, der findes i `docs/wiki/`, overskrives altid fra den, så en ændring i Gitea's weboverflade går tabt ved næste publicering. Sider, der kun findes i wikien, fjernes kun, når kaldet sætter `prune: "true"`. ## Udskiftning af et token diff --git a/wiki/Credentials.md b/docs/wiki/Credentials.md similarity index 87% rename from wiki/Credentials.md rename to docs/wiki/Credentials.md index 7688b6b..bf02e2a 100644 --- a/wiki/Credentials.md +++ b/docs/wiki/Credentials.md @@ -88,29 +88,30 @@ is ever printed. ## Wiki publishing secret -The workflow **Publish wiki** copies `wiki/` to the Gitea wiki of a repository -that has opted in with `wiki/.publish` (see [onboarding.md](Onboarding)). It -uses its own secret, so the metadata sync token stays read-only. +The workflow **Publish wiki pages** copies `docs/wiki/` to the Gitea wiki of a +repository that calls it (see [onboarding.md](Onboarding)). It uses its own +secret, so the metadata sync token stays read-only. The caller passes the +secret in `secrets:`; it is not inherited. | Secret | Content | Used for | | --- | --- | --- | | `TOKEN_FOR_GITEA_WIKI` | The Gitea token, nothing else | Writing the wiki pages of the repositories of an organization that opt in | - Store it as a secret of the organization of each repository that publishes. - There is no fallback to `TOKEN_FOR_GITEA`: a repository that opted in and has - no such secret fails with a configuration error, and a repository that did - not opt in does not need it. + There is no fallback to `TOKEN_FOR_GITEA`: a repository that calls the + workflow and has no such secret fails with a configuration error, and a + repository that does not call it does not need it. - The token needs scope `write:repository`, and its user needs write access to the repositories. Gitea has no wiki-only scope, so create the token for a dedicated user. S05 approves the scope and S03 stores the secret. - Calls made: `GET /repos/{owner}/{repo}`, `GET /repos/{owner}/{repo}/wiki/pages`, `GET`, `POST` and `PATCH /repos/{owner}/{repo}/wiki/...` and, for a page that - no longer exists in `wiki/`, `DELETE /repos/{owner}/{repo}/wiki/page/{name}`. + no longer exists in `docs/wiki/`, `DELETE /repos/{owner}/{repo}/wiki/page/{name}`. - The wiki must be enabled in the repository settings. The workflow refuses to run when it is not. -- Pages that are in `wiki/` are always overwritten from it, so a change made - in the Gitea web UI is lost on the next publish. Pages that are only in the - wiki are removed only when `wiki/.publish` contains the word `prune`. +- Pages that are in `docs/wiki/` are always overwritten from it, so a change + made in the Gitea web UI is lost on the next publish. Pages that are only in + the wiki are removed only when the call sets `prune: "true"`. ## Rotating a token diff --git a/wiki/Credentials.ms.md b/docs/wiki/Credentials.ms.md similarity index 86% rename from wiki/Credentials.ms.md rename to docs/wiki/Credentials.ms.md index 3889964..f63b52e 100644 --- a/wiki/Credentials.ms.md +++ b/docs/wiki/Credentials.ms.md @@ -1,4 +1,4 @@ - + > Ini ialah terjemahan [`Credentials`](Credentials). Halaman bahasa Inggeris ialah teks yang sah, dan perubahan di sini akan ditimpa pada penerbitan wiki yang seterusnya. @@ -56,17 +56,17 @@ Apabila berjaya, log menyatakan `Preflight passed: Gitea and GitHub accepted the ## Secret untuk menerbitkan wiki -Aliran kerja **Publish wiki** menyalin `wiki/` ke wiki Gitea bagi repositori yang telah memilih menyertainya dengan `wiki/.publish` (lihat [onboarding.md](Onboarding.ms)). Ia menggunakan secret sendiri, supaya token penyegerakan metadata kekal baca sahaja. +Aliran kerja **Publish wiki pages** menyalin `docs/wiki/` ke wiki Gitea bagi repositori yang memanggilnya (lihat [onboarding.md](Onboarding.ms)). Ia menggunakan secret sendiri, supaya token penyegerakan metadata kekal baca sahaja. Pemanggil menghantar secret dalam `secrets:`; ia tidak diwarisi. | Secret | Kandungan | Digunakan untuk | | --- | --- | --- | | `TOKEN_FOR_GITEA_WIKI` | Token Gitea, tiada yang lain | Menulis halaman wiki bagi repositori dalam organisasi yang memilih menyertainya | -- Simpan sebagai secret organisasi bagi setiap repositori yang menerbitkan. Tiada sandaran kepada `TOKEN_FOR_GITEA`: repositori yang telah memilih menyertainya dan tidak mempunyai secret itu gagal dengan ralat konfigurasi, dan repositori yang tidak memilih tidak memerlukannya. +- Simpan sebagai secret organisasi bagi setiap repositori yang menerbitkan. Tiada sandaran kepada `TOKEN_FOR_GITEA`: repositori yang memanggil aliran kerja dan tidak mempunyai secret itu gagal dengan ralat konfigurasi, dan repositori yang tidak memanggilnya tidak memerlukannya. - Token mesti mempunyai skop `write:repository`, dan penggunanya mesti mempunyai akses tulis kepada repositori. Gitea tidak mempunyai skop untuk wiki sahaja, jadi cipta token untuk pengguna khusus. S05 meluluskan skop dan S03 menyimpan secret. -- Panggilan yang dibuat: `GET /repos/{owner}/{repo}`, `GET /repos/{owner}/{repo}/wiki/pages`, `GET`, `POST` dan `PATCH /repos/{owner}/{repo}/wiki/...` dan, bagi halaman yang tidak lagi wujud dalam `wiki/`, `DELETE /repos/{owner}/{repo}/wiki/page/{name}`. +- Panggilan yang dibuat: `GET /repos/{owner}/{repo}`, `GET /repos/{owner}/{repo}/wiki/pages`, `GET`, `POST` dan `PATCH /repos/{owner}/{repo}/wiki/...` dan, bagi halaman yang tidak lagi wujud dalam `docs/wiki/`, `DELETE /repos/{owner}/{repo}/wiki/page/{name}`. - Wiki mesti diaktifkan dalam tetapan repositori. Aliran kerja enggan berjalan jika ia tidak diaktifkan. -- Halaman yang ada dalam `wiki/` sentiasa ditimpa daripadanya, jadi perubahan yang dibuat dalam antara muka web Gitea hilang pada penerbitan seterusnya. Halaman yang hanya ada dalam wiki dibuang hanya apabila `wiki/.publish` mengandungi perkataan `prune`. +- Halaman yang ada dalam `docs/wiki/` sentiasa ditimpa daripadanya, jadi perubahan yang dibuat dalam antara muka web Gitea hilang pada penerbitan seterusnya. Halaman yang hanya ada dalam wiki dibuang hanya apabila panggilan menetapkan `prune: "true"`. ## Menukar token diff --git a/wiki/Home.da.md b/docs/wiki/Home.da.md similarity index 79% rename from wiki/Home.da.md rename to docs/wiki/Home.da.md index bac4073..3b4a28d 100644 --- a/wiki/Home.da.md +++ b/docs/wiki/Home.da.md @@ -1,4 +1,4 @@ - + > Dette er en oversættelse af [`Home`](Home). Den engelske side er autoritativ, og ændringer her bliver overskrevet, næste gang wikien publiceres. @@ -13,20 +13,22 @@ En samling af genbrugelige Gitea Actions-workflows til DevOps-professionelle og Dette repository er den centrale samling af genbrugelig automatisering til TirSystems repositories. Det primære repository ligger på `git.tirsystem.com` (Gitea) og spejles med push til GitHub. -Det indeholder otte workflows: synkronisering af metadata til GitHub-spejlet, publicering af wiki, fælles kvalitetskontrol for Python og shell, for C og C++ og for C#, et udgivelsesworkflow, publicering af accepterede milepæle og repositoryets egen validering. De er listet med formål og diagram under [Workflows](#workflows). +Det indeholder ti workflows: synkronisering af metadata til GitHub-spejlet, publicering af wiki (scoped og genbrugeligt for repositories, der kalder det), fælles kvalitetskontrol for Python og shell, for C og C++ og for C#, et udgivelsesworkflow, publicering af accepterede milepæle og repositoryets egen validering. De er listet med formål og diagram under [Workflows](#workflows). ## Workflows -Der er otte workflows i dette repository. Et **scoped** workflow leveres af instansen til alle repositories i TirSystem-organisationerne og kræver intet i repositoryet; et **genbrugeligt** workflow kaldes fra et repository med `uses:`; de øvrige kører kun her. Diagrammerne er PlantUML-kildekode og er på engelsk. +Der er ti workflows i dette repository. Et **scoped** workflow leveres af instansen til alle repositories i TirSystem-organisationerne og kræver intet i repositoryet; et **genbrugeligt** workflow kaldes fra et repository med `uses:`; de øvrige kører kun her. Diagrammerne er PlantUML-kildekode og er på engelsk. | Workflow | Fil | Type | Starter ved | Formål | | --- | --- | --- | --- | --- | | Sync GitHub mirror metadata | [`sync-github-metadata.yml`](https://git.tirsystem.com/TirSystem/github-action/src/branch/main/.gitea/scoped_workflows/sync-github-metadata.yml) | Scoped | push til `main`, manuelt, dagligt kl. 03:17 UTC | Kopierer beskrivelsen og emnerne for et Gitea-repository til dets GitHub push-spejl | -| Publish wiki | [`publish-wiki.yml`](https://git.tirsystem.com/TirSystem/github-action/src/branch/main/.gitea/scoped_workflows/publish-wiki.yml) | Scoped, tilmelding med `wiki/.publish` | push til `main`, der ændrer `wiki/**`, manuelt | Publicerer siderne i `wiki/` til repositoryets wiki | +| Publish wiki | [`publish-wiki.yml`](https://git.tirsystem.com/TirSystem/github-action/src/branch/main/.gitea/scoped_workflows/publish-wiki.yml) | Scoped, tilmelding med `wiki/.publish`; forældet, afløses af det genbrugelige workflow nedenfor (ADR-0009) | push til `main`, der ændrer `wiki/**`, manuelt | Publicerer siderne i `wiki/` til repositoryets wiki | +| Publish wiki pages | [`publish-wiki-pages.yml`](https://git.tirsystem.com/TirSystem/github-action/src/branch/main/.gitea/workflows/publish-wiki-pages.yml) | Genbrugeligt (`workflow_call`) | et kald fra et andet repository | Publicerer siderne i `docs/wiki/` (eller den mappe, `wiki_dir` angiver) til wikien i det kaldende repository | | Quality checks | [`quality-checks.yml`](https://git.tirsystem.com/TirSystem/github-action/src/branch/main/.gitea/workflows/quality-checks.yml) | Genbrugeligt (`workflow_call`) | et kald fra et andet repository | Kører ruff, mypy, shellcheck og shfmt på de sporede filer og ændrer intet | | Quality checks C++ | [`quality-checks-cpp.yml`](https://git.tirsystem.com/TirSystem/github-action/src/branch/main/.gitea/workflows/quality-checks-cpp.yml) | Genbrugeligt (`workflow_call`) | et kald fra et andet repository | Kører clang-format og clang-tidy i præcise versioner på de sporede C- og C++-filer og ændrer intet | | Quality checks C# | [`quality-checks-csharp.yml`](https://git.tirsystem.com/TirSystem/github-action/src/branch/main/.gitea/workflows/quality-checks-csharp.yml) | Genbrugeligt (`workflow_call`) | et kald fra et andet repository | Kører `dotnet format` og `dotnet build` på et præcist .NET SDK 10 eller nyere og ændrer intet | +| Publish own wiki | [`publish-own-wiki.yml`](https://git.tirsystem.com/TirSystem/github-action/src/branch/main/.gitea/workflows/publish-own-wiki.yml) | Kun dette repository | push til `main`, der ændrer `docs/wiki/**`, manuelt | Kalder det genbrugelige workflow Publish wiki pages for dette repositorys wiki | | Release | [`release.yml`](https://git.tirsystem.com/TirSystem/github-action/src/branch/main/.gitea/workflows/release.yml) | Kun dette repository | manuelt | Opretter versionstagget, udgivelsessiden og major-tagget efter kontrollerne | | Publicering af accepterede milepæle | [`sync-milestones.yml`](https://git.tirsystem.com/TirSystem/github-action/src/branch/main/.gitea/workflows/sync-milestones.yml) | Kun dette repository | push til `main`, der ændrer `docs/milestones/**` eller `docs/sqa/reviews/**`, manuelt (tørkørsel som standard) | Opretter eller opdaterer Gitea-milepælen og issues for hver milepæl, der er Accepted med en Go-gennemgang | | Validate workflows | [`validate-workflows.yml`](https://git.tirsystem.com/TirSystem/github-action/src/branch/main/.gitea/workflows/validate-workflows.yml) | Kun dette repository | pull request, push til `main`, manuelt | Læser hvert workflow som YAML og kører offline-testene | @@ -97,7 +99,7 @@ deactivate Workflow @enduml ``` -### Publicering af wiki +### Publicering af wiki (scoped, forældet) Publicerer `wiki/` til repositoryets wiki, kun i et repository, der har tilmeldt sig med `wiki/.publish`. Ordet `prune` i den fil sletter også sider, som ikke findes i `wiki/`. @@ -326,6 +328,90 @@ deactivate Workflow @enduml ``` +### Publicering af wiki-sider + +Et genbrugeligt workflow (ADR-0009). Et repository kalder det fra sit eget workflow, så selve kaldet er tilmeldingen, og der behøves ingen markørfil. Det publicerer Markdown-siderne i `wiki_dir` (standard `docs/wiki`) til wikien i det kaldende repository og sletter kun sider, der ikke findes i mappen, når `prune` er `true`. + +```yaml +on: + push: + branches: [ main ] + paths: [ "docs/wiki/**" ] +jobs: + wiki: + uses: TirSystem/github-action/.gitea/workflows/publish-wiki-pages.yml@v1 + secrets: + TOKEN_FOR_GITEA_WIKI: ${{ secrets.TOKEN_FOR_GITEA_WIKI }} +``` + +#### Workflow + +```plantuml +@startuml +title Publish docs/wiki to the wiki of the calling repository + +autonumber + +actor "Calling repository\nuses: ...publish-wiki-pages.yml@v1" as Caller +participant "Gitea Actions\npublish-wiki-pages" as Workflow +participant "shared-scripts\n(tools/publish_wiki.py at tools-ref)" as Script +participant "Gitea wiki API" as Wiki + +Caller -> Workflow: Call with wiki_dir, prune and the secret +activate Workflow +Workflow -> Script: Check out the repository and the script, run it +activate Script + +alt wiki_dir does not exist, or has no Markdown pages + Script --> Workflow: Fail with [configuration]\n(an empty folder never deletes pages) +else + Script -> Script: Read prune and TOKEN_FOR_GITEA_WIKI + Script -> Wiki: GET repository (preflight) + Wiki --> Script: Wiki is enabled, token accepted + Script -> Wiki: GET pages + Wiki --> Script: Existing pages + Script -> Wiki: Create new pages, update changed pages + opt prune is true + Script -> Wiki: Delete pages that are not in wiki_dir + end + Script --> Workflow: Log created, updated and deleted counts +end +deactivate Script +Workflow --> Caller: Workflow result +deactivate Workflow +@enduml +``` + +### Publicering af egen wiki + +Dette repositorys wiki er `docs/wiki/`. Workflowet kalder det genbrugelige workflow ovenfor med dets lokale sti, med `prune` sat til `true`, så wikien altid er lig med mappen, og `tools-ref` sat til `main`, så scriptet fra samme commit kører. Det er den kalder, et projekt kopierer fra frameworkets `templates/ci/publish-wiki.yml`. + +#### Workflow + +```plantuml +@startuml +title Publish the wiki of this repository (docs/wiki) + +autonumber + +actor "Push to main that changes docs/wiki/**,\nor manual trigger" as Trigger +participant "Gitea Actions\npublish-own-wiki" as Caller +participant "Gitea Actions\npublish-wiki-pages\n(called by its local path)" as Workflow +participant "Gitea wiki API" as Wiki + +Trigger -> Caller: Start workflow +activate Caller +Caller -> Workflow: Call with wiki_dir docs/wiki, prune true,\ntools-ref main and TOKEN_FOR_GITEA_WIKI +activate Workflow +Workflow -> Wiki: Create, update and delete pages\nso the wiki equals docs/wiki +Wiki --> Workflow: Done +Workflow --> Caller: Workflow result +deactivate Workflow +Caller --> Trigger: Workflow result +deactivate Caller +@enduml +``` + ### Publicering af accepterede milepæle Permanent tilladelse til at publicere: ved et push til `main`, der ændrer milepælene eller deres gennemgange, oprettes eller opdateres hver milepæl, hvis seneste række i Version History er Accepted, og hvis seneste gennemgang er en Go, på Gitea med sine opgaver som issues. Intet lukkes eller slettes. En manuel kørsel er en tørkørsel, medmindre `dry_run` slås fra. Det bruger secret'en `TOKEN_FOR_GITEA` og `--accepted-only`-reglen i det monterede framework (v0.5.0 eller nyere). diff --git a/wiki/Home.md b/docs/wiki/Home.md similarity index 80% rename from wiki/Home.md rename to docs/wiki/Home.md index 49afc80..da10251 100644 --- a/wiki/Home.md +++ b/docs/wiki/Home.md @@ -13,20 +13,22 @@ A collection of reusable Gitea Actions workflows for DevOps professionals and so This repository is the central collection of reusable automation for TirSystem repositories. The primary repository lives at `git.tirsystem.com` (Gitea) and is push-mirrored to GitHub. -It contains eight workflows: metadata sync to the GitHub mirror, wiki publishing, shared quality checks for Python and shell, for C and C++ and for C#, a release workflow, the publishing of accepted milestones and the repository's own validation. They are listed with their purpose and a diagram under [Workflows](#workflows). +It contains ten workflows: metadata sync to the GitHub mirror, wiki publishing (scoped, and reusable for repositories that call it), shared quality checks for Python and shell, for C and C++ and for C#, a release workflow, the publishing of accepted milestones and the repository's own validation. They are listed with their purpose and a diagram under [Workflows](#workflows). ## Workflows -Eight workflows live in this repository. A **scoped** workflow is delivered by the instance to every repository of the TirSystem organizations and needs nothing in the repository; a **reusable** workflow is called by a repository with `uses:`; the others run only here. The diagrams are PlantUML source. +Ten workflows live in this repository. A **scoped** workflow is delivered by the instance to every repository of the TirSystem organizations and needs nothing in the repository; a **reusable** workflow is called by a repository with `uses:`; the others run only here. The diagrams are PlantUML source. | Workflow | File | Kind | Starts on | Purpose | | --- | --- | --- | --- | --- | | Sync GitHub mirror metadata | [`sync-github-metadata.yml`](https://git.tirsystem.com/TirSystem/github-action/src/branch/main/.gitea/scoped_workflows/sync-github-metadata.yml) | Scoped | push to `main`, manual, daily 03:17 UTC | Copies the description and topics of a Gitea repository to its GitHub push mirror | -| Publish wiki | [`publish-wiki.yml`](https://git.tirsystem.com/TirSystem/github-action/src/branch/main/.gitea/scoped_workflows/publish-wiki.yml) | Scoped, opt-in with `wiki/.publish` | push to `main` that changes `wiki/**`, manual | Publishes the pages in `wiki/` to the repository wiki | +| Publish wiki | [`publish-wiki.yml`](https://git.tirsystem.com/TirSystem/github-action/src/branch/main/.gitea/scoped_workflows/publish-wiki.yml) | Scoped, opt-in with `wiki/.publish`; deprecated, replaced by the reusable workflow below (ADR-0009) | push to `main` that changes `wiki/**`, manual | Publishes the pages in `wiki/` to the repository wiki | +| Publish wiki pages | [`publish-wiki-pages.yml`](https://git.tirsystem.com/TirSystem/github-action/src/branch/main/.gitea/workflows/publish-wiki-pages.yml) | Reusable (`workflow_call`) | a call from another repository | Publishes the pages in `docs/wiki/` (or the folder named by `wiki_dir`) to the wiki of the calling repository | | Quality checks | [`quality-checks.yml`](https://git.tirsystem.com/TirSystem/github-action/src/branch/main/.gitea/workflows/quality-checks.yml) | Reusable (`workflow_call`) | a call from another repository | Runs ruff, mypy, shellcheck and shfmt on the tracked files and changes nothing | | Quality checks C++ | [`quality-checks-cpp.yml`](https://git.tirsystem.com/TirSystem/github-action/src/branch/main/.gitea/workflows/quality-checks-cpp.yml) | Reusable (`workflow_call`) | a call from another repository | Runs clang-format and clang-tidy at exact versions on the tracked C and C++ files and changes nothing | | Quality checks C# | [`quality-checks-csharp.yml`](https://git.tirsystem.com/TirSystem/github-action/src/branch/main/.gitea/workflows/quality-checks-csharp.yml) | Reusable (`workflow_call`) | a call from another repository | Runs `dotnet format` and `dotnet build` on an exact .NET SDK 10 or later and changes nothing | +| Publish own wiki | [`publish-own-wiki.yml`](https://git.tirsystem.com/TirSystem/github-action/src/branch/main/.gitea/workflows/publish-own-wiki.yml) | This repository only | push to `main` that changes `docs/wiki/**`, manual | Calls the reusable Publish wiki pages workflow for the wiki of this repository | | Release | [`release.yml`](https://git.tirsystem.com/TirSystem/github-action/src/branch/main/.gitea/workflows/release.yml) | This repository only | manual | Creates the version tag, the release page and the major tag after the checks | | Publish accepted milestones | [`sync-milestones.yml`](https://git.tirsystem.com/TirSystem/github-action/src/branch/main/.gitea/workflows/sync-milestones.yml) | This repository only | push to `main` that changes `docs/milestones/**` or `docs/sqa/reviews/**`, manual (dry run by default) | Creates or updates the Gitea milestone and issues of every milestone that is Accepted with a Go review | | Validate workflows | [`validate-workflows.yml`](https://git.tirsystem.com/TirSystem/github-action/src/branch/main/.gitea/workflows/validate-workflows.yml) | This repository only | pull request, push to `main`, manual | Parses every workflow and runs the offline tests | @@ -97,7 +99,7 @@ deactivate Workflow @enduml ``` -### Publish wiki +### Publish wiki (scoped, deprecated) Publishes `wiki/` to the repository wiki, only in a repository that has opted in with `wiki/.publish`. The word `prune` in that file also deletes pages that are not in `wiki/`. @@ -326,6 +328,90 @@ deactivate Workflow @enduml ``` +### Publish wiki pages + +A reusable workflow (ADR-0009). A repository calls it from its own workflow, so the call is the opt-in and no marker file is needed. It publishes the Markdown pages of `wiki_dir` (default `docs/wiki`) to the wiki of the calling repository, and deletes pages that are not in the folder only when `prune` is `true`. + +```yaml +on: + push: + branches: [ main ] + paths: [ "docs/wiki/**" ] +jobs: + wiki: + uses: TirSystem/github-action/.gitea/workflows/publish-wiki-pages.yml@v1 + secrets: + TOKEN_FOR_GITEA_WIKI: ${{ secrets.TOKEN_FOR_GITEA_WIKI }} +``` + +#### Workflow + +```plantuml +@startuml +title Publish docs/wiki to the wiki of the calling repository + +autonumber + +actor "Calling repository\nuses: ...publish-wiki-pages.yml@v1" as Caller +participant "Gitea Actions\npublish-wiki-pages" as Workflow +participant "shared-scripts\n(tools/publish_wiki.py at tools-ref)" as Script +participant "Gitea wiki API" as Wiki + +Caller -> Workflow: Call with wiki_dir, prune and the secret +activate Workflow +Workflow -> Script: Check out the repository and the script, run it +activate Script + +alt wiki_dir does not exist, or has no Markdown pages + Script --> Workflow: Fail with [configuration]\n(an empty folder never deletes pages) +else + Script -> Script: Read prune and TOKEN_FOR_GITEA_WIKI + Script -> Wiki: GET repository (preflight) + Wiki --> Script: Wiki is enabled, token accepted + Script -> Wiki: GET pages + Wiki --> Script: Existing pages + Script -> Wiki: Create new pages, update changed pages + opt prune is true + Script -> Wiki: Delete pages that are not in wiki_dir + end + Script --> Workflow: Log created, updated and deleted counts +end +deactivate Script +Workflow --> Caller: Workflow result +deactivate Workflow +@enduml +``` + +### Publish own wiki + +The wiki of this repository is `docs/wiki/`. This workflow calls the reusable workflow above by its local path, with `prune` set to `true` so the wiki always equals the folder and `tools-ref` set to `main` so that the script of the same commit runs. It is the caller that a project copies from the framework's `templates/ci/publish-wiki.yml`. + +#### Workflow + +```plantuml +@startuml +title Publish the wiki of this repository (docs/wiki) + +autonumber + +actor "Push to main that changes docs/wiki/**,\nor manual trigger" as Trigger +participant "Gitea Actions\npublish-own-wiki" as Caller +participant "Gitea Actions\npublish-wiki-pages\n(called by its local path)" as Workflow +participant "Gitea wiki API" as Wiki + +Trigger -> Caller: Start workflow +activate Caller +Caller -> Workflow: Call with wiki_dir docs/wiki, prune true,\ntools-ref main and TOKEN_FOR_GITEA_WIKI +activate Workflow +Workflow -> Wiki: Create, update and delete pages\nso the wiki equals docs/wiki +Wiki --> Workflow: Done +Workflow --> Caller: Workflow result +deactivate Workflow +Caller --> Trigger: Workflow result +deactivate Caller +@enduml +``` + ### Publish accepted milestones Standing authorization to publish: on a push to `main` that changes the milestones or their reviews, every milestone whose latest Version History row is Accepted and whose latest review is a Go is created or updated on Gitea with its tasks as issues. Nothing is closed or deleted. A manual run is a dry run unless `dry_run` is switched off. It uses the secret `TOKEN_FOR_GITEA` and the `--accepted-only` rule of the mounted framework (v0.5.0 or later). diff --git a/wiki/Home.ms.md b/docs/wiki/Home.ms.md similarity index 78% rename from wiki/Home.ms.md rename to docs/wiki/Home.ms.md index 6c9d0dd..6e389fe 100644 --- a/wiki/Home.ms.md +++ b/docs/wiki/Home.ms.md @@ -1,4 +1,4 @@ - + > Ini ialah terjemahan [`Home`](Home). Halaman bahasa Inggeris ialah teks yang sah, dan perubahan di sini akan ditimpa pada penerbitan wiki yang seterusnya. @@ -13,20 +13,22 @@ Koleksi aliran kerja (workflow) Gitea Actions yang boleh digunakan semula untuk Repositori ini ialah koleksi pusat bagi automasi yang boleh digunakan semula untuk repositori TirSystem. Repositori utama berada di `git.tirsystem.com` (Gitea) dan dicerminkan dengan push ke GitHub. -Ia mengandungi lapan aliran kerja: penyegerakan metadata ke cermin GitHub, penerbitan wiki, semakan kualiti bersama untuk Python dan shell, untuk C dan C++ serta untuk C#, aliran kerja keluaran, penerbitan pencapaian (milestone) yang diterima dan pengesahan repositori sendiri. Ia disenaraikan dengan tujuan dan rajah di bawah [Aliran kerja](#aliran-kerja). +Ia mengandungi sepuluh aliran kerja: penyegerakan metadata ke cermin GitHub, penerbitan wiki (scoped, dan boleh guna semula bagi repositori yang memanggilnya), semakan kualiti bersama untuk Python dan shell, untuk C dan C++ serta untuk C#, aliran kerja keluaran, penerbitan pencapaian (milestone) yang diterima dan pengesahan repositori sendiri. Ia disenaraikan dengan tujuan dan rajah di bawah [Aliran kerja](#aliran-kerja). ## Aliran kerja -Terdapat lapan aliran kerja dalam repositori ini. Aliran kerja **scoped** dihantar oleh instans ke setiap repositori organisasi TirSystem dan tidak memerlukan apa-apa dalam repositori; aliran kerja **boleh guna semula** dipanggil oleh sebuah repositori dengan `uses:`; yang lain hanya berjalan di sini. Rajah ialah kod sumber PlantUML dan dalam bahasa Inggeris. +Terdapat sepuluh aliran kerja dalam repositori ini. Aliran kerja **scoped** dihantar oleh instans ke setiap repositori organisasi TirSystem dan tidak memerlukan apa-apa dalam repositori; aliran kerja **boleh guna semula** dipanggil oleh sebuah repositori dengan `uses:`; yang lain hanya berjalan di sini. Rajah ialah kod sumber PlantUML dan dalam bahasa Inggeris. | Aliran kerja | Fail | Jenis | Bermula apabila | Tujuan | | --- | --- | --- | --- | --- | | Sync GitHub mirror metadata | [`sync-github-metadata.yml`](https://git.tirsystem.com/TirSystem/github-action/src/branch/main/.gitea/scoped_workflows/sync-github-metadata.yml) | Scoped | push ke `main`, manual, setiap hari 03:17 UTC | Menyalin penerangan dan topik repositori Gitea ke push mirror GitHub-nya | -| Publish wiki | [`publish-wiki.yml`](https://git.tirsystem.com/TirSystem/github-action/src/branch/main/.gitea/scoped_workflows/publish-wiki.yml) | Scoped, pilih menyertai dengan `wiki/.publish` | push ke `main` yang mengubah `wiki/**`, manual | Menerbitkan halaman dalam `wiki/` ke wiki repositori | +| Publish wiki | [`publish-wiki.yml`](https://git.tirsystem.com/TirSystem/github-action/src/branch/main/.gitea/scoped_workflows/publish-wiki.yml) | Scoped, pilih menyertai dengan `wiki/.publish`; usang, sedang diganti oleh aliran kerja boleh guna semula di bawah (ADR-0009) | push ke `main` yang mengubah `wiki/**`, manual | Menerbitkan halaman dalam `wiki/` ke wiki repositori | +| Publish wiki pages | [`publish-wiki-pages.yml`](https://git.tirsystem.com/TirSystem/github-action/src/branch/main/.gitea/workflows/publish-wiki-pages.yml) | Boleh guna semula (`workflow_call`) | panggilan daripada repositori lain | Menerbitkan halaman dalam `docs/wiki/` (atau folder yang dinamakan oleh `wiki_dir`) ke wiki repositori pemanggil | | Quality checks | [`quality-checks.yml`](https://git.tirsystem.com/TirSystem/github-action/src/branch/main/.gitea/workflows/quality-checks.yml) | Boleh guna semula (`workflow_call`) | panggilan daripada repositori lain | Menjalankan ruff, mypy, shellcheck dan shfmt pada fail yang dijejaki dan tidak mengubah apa-apa | | Quality checks C++ | [`quality-checks-cpp.yml`](https://git.tirsystem.com/TirSystem/github-action/src/branch/main/.gitea/workflows/quality-checks-cpp.yml) | Boleh guna semula (`workflow_call`) | panggilan daripada repositori lain | Menjalankan clang-format dan clang-tidy pada versi tepat pada fail C dan C++ yang dijejaki dan tidak mengubah apa-apa | | Quality checks C# | [`quality-checks-csharp.yml`](https://git.tirsystem.com/TirSystem/github-action/src/branch/main/.gitea/workflows/quality-checks-csharp.yml) | Boleh guna semula (`workflow_call`) | panggilan daripada repositori lain | Menjalankan `dotnet format` dan `dotnet build` pada .NET SDK 10 atau lebih baharu yang tepat dan tidak mengubah apa-apa | +| Publish own wiki | [`publish-own-wiki.yml`](https://git.tirsystem.com/TirSystem/github-action/src/branch/main/.gitea/workflows/publish-own-wiki.yml) | Repositori ini sahaja | push ke `main` yang mengubah `docs/wiki/**`, manual | Memanggil aliran kerja boleh guna semula Publish wiki pages untuk wiki repositori ini | | Release | [`release.yml`](https://git.tirsystem.com/TirSystem/github-action/src/branch/main/.gitea/workflows/release.yml) | Repositori ini sahaja | manual | Mencipta tag versi, halaman keluaran dan tag major selepas semakan | | Menerbitkan milestone yang diterima | [`sync-milestones.yml`](https://git.tirsystem.com/TirSystem/github-action/src/branch/main/.gitea/workflows/sync-milestones.yml) | Repositori ini sahaja | push ke `main` yang mengubah `docs/milestones/**` atau `docs/sqa/reviews/**`, manual (larian percubaan secara lalai) | Mencipta atau mengemas kini milestone Gitea dan isu bagi setiap milestone yang Accepted dengan semakan Go | | Validate workflows | [`validate-workflows.yml`](https://git.tirsystem.com/TirSystem/github-action/src/branch/main/.gitea/workflows/validate-workflows.yml) | Repositori ini sahaja | pull request, push ke `main`, manual | Menghurai setiap aliran kerja sebagai YAML dan menjalankan ujian luar talian | @@ -97,7 +99,7 @@ deactivate Workflow @enduml ``` -### Menerbitkan wiki +### Menerbitkan wiki (scoped, usang) Menerbitkan `wiki/` ke wiki repositori, hanya dalam repositori yang telah menyertai dengan `wiki/.publish`. Perkataan `prune` dalam fail itu juga memadam halaman yang tiada dalam `wiki/`. @@ -326,6 +328,90 @@ deactivate Workflow @enduml ``` +### Menerbitkan halaman wiki + +Aliran kerja boleh guna semula (ADR-0009). Sesebuah repositori memanggilnya daripada aliran kerjanya sendiri, jadi panggilan itu ialah pilihan menyertai dan tiada fail penanda diperlukan. Ia menerbitkan halaman Markdown dalam `wiki_dir` (lalai `docs/wiki`) ke wiki repositori pemanggil, dan memadam halaman yang tiada dalam folder hanya apabila `prune` ialah `true`. + +```yaml +on: + push: + branches: [ main ] + paths: [ "docs/wiki/**" ] +jobs: + wiki: + uses: TirSystem/github-action/.gitea/workflows/publish-wiki-pages.yml@v1 + secrets: + TOKEN_FOR_GITEA_WIKI: ${{ secrets.TOKEN_FOR_GITEA_WIKI }} +``` + +#### Aliran kerja + +```plantuml +@startuml +title Publish docs/wiki to the wiki of the calling repository + +autonumber + +actor "Calling repository\nuses: ...publish-wiki-pages.yml@v1" as Caller +participant "Gitea Actions\npublish-wiki-pages" as Workflow +participant "shared-scripts\n(tools/publish_wiki.py at tools-ref)" as Script +participant "Gitea wiki API" as Wiki + +Caller -> Workflow: Call with wiki_dir, prune and the secret +activate Workflow +Workflow -> Script: Check out the repository and the script, run it +activate Script + +alt wiki_dir does not exist, or has no Markdown pages + Script --> Workflow: Fail with [configuration]\n(an empty folder never deletes pages) +else + Script -> Script: Read prune and TOKEN_FOR_GITEA_WIKI + Script -> Wiki: GET repository (preflight) + Wiki --> Script: Wiki is enabled, token accepted + Script -> Wiki: GET pages + Wiki --> Script: Existing pages + Script -> Wiki: Create new pages, update changed pages + opt prune is true + Script -> Wiki: Delete pages that are not in wiki_dir + end + Script --> Workflow: Log created, updated and deleted counts +end +deactivate Script +Workflow --> Caller: Workflow result +deactivate Workflow +@enduml +``` + +### Menerbitkan wiki sendiri + +Wiki repositori ini ialah `docs/wiki/`. Aliran kerja ini memanggil aliran kerja boleh guna semula di atas melalui laluan tempatannya, dengan `prune` ditetapkan kepada `true` supaya wiki sentiasa sama dengan folder dan `tools-ref` ditetapkan kepada `main` supaya skrip daripada commit yang sama dijalankan. Ia ialah pemanggil yang disalin oleh projek daripada `templates/ci/publish-wiki.yml` framework. + +#### Aliran kerja + +```plantuml +@startuml +title Publish the wiki of this repository (docs/wiki) + +autonumber + +actor "Push to main that changes docs/wiki/**,\nor manual trigger" as Trigger +participant "Gitea Actions\npublish-own-wiki" as Caller +participant "Gitea Actions\npublish-wiki-pages\n(called by its local path)" as Workflow +participant "Gitea wiki API" as Wiki + +Trigger -> Caller: Start workflow +activate Caller +Caller -> Workflow: Call with wiki_dir docs/wiki, prune true,\ntools-ref main and TOKEN_FOR_GITEA_WIKI +activate Workflow +Workflow -> Wiki: Create, update and delete pages\nso the wiki equals docs/wiki +Wiki --> Workflow: Done +Workflow --> Caller: Workflow result +deactivate Workflow +Caller --> Trigger: Workflow result +deactivate Caller +@enduml +``` + ### Menerbitkan milestone yang diterima Kebenaran tetap untuk menerbitkan: pada push ke `main` yang mengubah milestone atau semakannya, setiap milestone yang baris terkini Version History-nya Accepted dan semakan terkininya Go dicipta atau dikemas kini di Gitea dengan tugasnya sebagai isu. Tiada apa-apa ditutup atau dipadam. Larian manual ialah larian percubaan kecuali `dry_run` dimatikan. Ia menggunakan secret `TOKEN_FOR_GITEA` dan peraturan `--accepted-only` framework yang dipasang (v0.5.0 atau lebih baharu). diff --git a/wiki/Onboarding.da.md b/docs/wiki/Onboarding.da.md similarity index 76% rename from wiki/Onboarding.da.md rename to docs/wiki/Onboarding.da.md index bf05f55..f1b8692 100644 --- a/wiki/Onboarding.da.md +++ b/docs/wiki/Onboarding.da.md @@ -1,4 +1,4 @@ - + > Dette er en oversættelse af [`Onboarding`](Onboarding). Den engelske side er autoritativ, og ændringer her bliver overskrevet, næste gang wikien publiceres. @@ -32,15 +32,31 @@ Leveringen er automatisk, så et repository behøver ingen kopi af workflowet. S ## Publicér en wiki (valgfrit) -Workflowet **Publish wiki** kopierer Markdown-siderne i `wiki/` til repositoryets wiki, når en ændring af `wiki/` flettes til `main`. Det leveres som synkroniseringsworkflowet, men skriver kun, hvor et repository har meldt sig til. +Det genbrugelige workflow **Publish wiki pages** kopierer Markdown-siderne i `docs/wiki/` til repositoryets wiki, når en ændring af `docs/wiki/` flettes til `main`. Repositoryet kalder det, så der skrives intet, hvor der ikke findes et kald. Wikien findes som minimum på engelsk og på produktejerens sprog. 1. Aktivér wikien i repositoryets indstillinger. -2. Tilføj Markdown-sider til `wiki/`. Filnavnet er sidens navn: `Home.md` er forsiden. En bindestreg i navnet er et mellemrum i sidens navn: `Home-da.md` er siden "Home da", og et link til den er `[Dansk](Home-da)`. -3. Tilføj markøren `wiki/.publish`. Lad den være tom for kun at oprette og opdatere sider. Skriv det ene ord `prune` i den for også at slette wiki-sider, der ikke findes i `wiki/`, så wikien altid er lig med mappen. +2. Tilføj Markdown-sider til `docs/wiki/`. Filnavnet er sidens navn: `Home.md` er forsiden. En bindestreg i navnet er et mellemrum i sidens navn: `Home-da.md` er siden "Home da", og et link til den er `[Dansk](Home-da)`. +3. Tilføj et workflow, for eksempel `.gitea/workflows/publish-wiki.yml`, der kalder det genbrugelige workflow: + + ```yaml + on: + push: + branches: [ main ] + paths: [ "docs/wiki/**" ] + jobs: + wiki: + uses: TirSystem/github-action/.gitea/workflows/publish-wiki-pages.yml@v1 + with: + prune: "true" + secrets: + TOKEN_FOR_GITEA_WIKI: ${{ secrets.TOKEN_FOR_GITEA_WIKI }} + ``` + + `wiki_dir` er som standard `docs/wiki`. `prune: "true"` sletter også wiki-sider, der ikke findes i mappen, så wikien altid er lig med mappen; standarden `false` beholder dem. 4. Gem `TOKEN_FOR_GITEA_WIKI` som en secret i repositoryets organisation med det scope, der står i [credentials.md](Credentials.da). 5. Flet ændringen til `main`. Loggen skal slutte med `Published page(s) to the wiki of /`. -Et repository uden `wiki/.publish` springes over med linjen `No wiki/.publish marker in /`: intet bliver skrevet, og der skal ingen secret til. +Et repository, der stadig har markøren `wiki/.publish`, publiceres af det ældre scoped workflow, som fjernes, når alle repositories har et kald. Flyt siderne til `docs/wiki/` og tilføj kaldet, før det sker. ## Runners diff --git a/wiki/Onboarding.md b/docs/wiki/Onboarding.md similarity index 76% rename from wiki/Onboarding.md rename to docs/wiki/Onboarding.md index 6a81378..077ca6c 100644 --- a/wiki/Onboarding.md +++ b/docs/wiki/Onboarding.md @@ -51,25 +51,43 @@ Delivery is automatic, so a repository needs no copy of the workflow. Secrets ar ## Publish a wiki (optional) -The **Publish wiki** workflow copies the Markdown pages in `wiki/` to the -repository wiki when a change to `wiki/` is merged to `main`. It is delivered -like the sync workflow, but it writes only where a repository opts in. +The reusable workflow **Publish wiki pages** copies the Markdown pages in +`docs/wiki/` to the repository wiki when a change to `docs/wiki/` is merged to +`main`. The repository calls it, so nothing is written where no call exists. +The wiki has English and the product owner's language as a minimum. 1. Enable the wiki in the repository settings. -2. Add Markdown pages to `wiki/`. The file name is the page name: `Home.md` is - the home page. A hyphen in the name is a space in the page name: `Home-da.md` - is the page "Home da", and a link to it is `[Dansk](https://git.tirsystem.com/TirSystem/github-action/src/branch/main/guides/Home-da)`. -3. Add the marker `wiki/.publish`. Leave it empty to create and update pages - only. Put the single word `prune` in it to also delete wiki pages that are - not in `wiki/`, so the wiki always equals the folder. +2. Add Markdown pages to `docs/wiki/`. The file name is the page name: `Home.md` + is the home page. A hyphen in the name is a space in the page name: + `Home-da.md` is the page "Home da", and a link to it is `[Dansk](https://git.tirsystem.com/TirSystem/github-action/src/branch/main/guides/Home-da)`. +3. Add a workflow, for example `.gitea/workflows/publish-wiki.yml`, that calls + the reusable workflow: + + ```yaml + on: + push: + branches: [ main ] + paths: [ "docs/wiki/**" ] + jobs: + wiki: + uses: TirSystem/github-action/.gitea/workflows/publish-wiki-pages.yml@v1 + with: + prune: "true" + secrets: + TOKEN_FOR_GITEA_WIKI: ${{ secrets.TOKEN_FOR_GITEA_WIKI }} + ``` + + `wiki_dir` defaults to `docs/wiki`. `prune: "true"` also deletes wiki pages + that are not in the folder, so the wiki always equals the folder; the + default `false` keeps them. 4. Store `TOKEN_FOR_GITEA_WIKI` as a secret of the repository's organization, using the scope in [credentials.md](Credentials). 5. Merge the change to `main`. The log must end with `Published page(s) to the wiki of /`. -A repository without `wiki/.publish` is skipped with the line `No -wiki/.publish marker in /`: nothing is written and no secret is -needed. +A repository that still has the marker `wiki/.publish` is published by the +older scoped workflow, which is removed once every repository has a call. +Move the pages to `docs/wiki/` and add the call before that. ## Runners diff --git a/wiki/Onboarding.ms.md b/docs/wiki/Onboarding.ms.md similarity index 76% rename from wiki/Onboarding.ms.md rename to docs/wiki/Onboarding.ms.md index 4003987..8c9ba5b 100644 --- a/wiki/Onboarding.ms.md +++ b/docs/wiki/Onboarding.ms.md @@ -1,4 +1,4 @@ - + > Ini ialah terjemahan [`Onboarding`](Onboarding). Halaman bahasa Inggeris ialah teks yang sah, dan perubahan di sini akan ditimpa pada penerbitan wiki yang seterusnya. @@ -32,15 +32,31 @@ Penghantaran adalah automatik, jadi repositori tidak memerlukan salinan aliran k ## Menerbitkan wiki (pilihan) -Aliran kerja **Publish wiki** menyalin halaman Markdown dalam `wiki/` ke wiki repositori apabila perubahan pada `wiki/` digabungkan ke `main`. Ia dihantar seperti aliran kerja penyegerakan, tetapi hanya menulis di tempat repositori telah memilih untuk menyertainya. +Aliran kerja boleh guna semula **Publish wiki pages** menyalin halaman Markdown dalam `docs/wiki/` ke wiki repositori apabila perubahan pada `docs/wiki/` digabungkan ke `main`. Repositori memanggilnya, jadi tiada apa-apa ditulis di tempat yang tiada panggilan. Wiki ada dalam bahasa Inggeris dan bahasa pemilik produk sekurang-kurangnya. 1. Aktifkan wiki dalam tetapan repositori. -2. Tambah halaman Markdown ke `wiki/`. Nama fail ialah nama halaman: `Home.md` ialah halaman utama. Tanda sempang dalam nama ialah ruang dalam nama halaman: `Home-da.md` ialah halaman "Home da", dan pautan kepadanya ialah `[Dansk](Home-da)`. -3. Tambah penanda `wiki/.publish`. Biarkan kosong untuk mencipta dan mengemas kini halaman sahaja. Letakkan satu perkataan `prune` di dalamnya untuk turut memadam halaman wiki yang tiada dalam `wiki/`, supaya wiki sentiasa sama dengan folder itu. +2. Tambah halaman Markdown ke `docs/wiki/`. Nama fail ialah nama halaman: `Home.md` ialah halaman utama. Tanda sempang dalam nama ialah ruang dalam nama halaman: `Home-da.md` ialah halaman "Home da", dan pautan kepadanya ialah `[Dansk](Home-da)`. +3. Tambah aliran kerja, contohnya `.gitea/workflows/publish-wiki.yml`, yang memanggil aliran kerja boleh guna semula: + + ```yaml + on: + push: + branches: [ main ] + paths: [ "docs/wiki/**" ] + jobs: + wiki: + uses: TirSystem/github-action/.gitea/workflows/publish-wiki-pages.yml@v1 + with: + prune: "true" + secrets: + TOKEN_FOR_GITEA_WIKI: ${{ secrets.TOKEN_FOR_GITEA_WIKI }} + ``` + + `wiki_dir` lalai ialah `docs/wiki`. `prune: "true"` turut memadam halaman wiki yang tiada dalam folder itu, supaya wiki sentiasa sama dengan folder; lalai `false` mengekalkannya. 4. Simpan `TOKEN_FOR_GITEA_WIKI` sebagai secret organisasi repositori, dengan skop yang tertera dalam [credentials.md](Credentials.ms). 5. Gabungkan perubahan ke `main`. Log mesti berakhir dengan `Published page(s) to the wiki of /`. -Repositori tanpa `wiki/.publish` dilangkau dengan baris `No wiki/.publish marker in /`: tiada apa-apa ditulis dan tiada secret diperlukan. +Repositori yang masih mempunyai penanda `wiki/.publish` diterbitkan oleh aliran kerja scoped yang lebih lama, yang dibuang apabila setiap repositori mempunyai panggilan. Alihkan halaman ke `docs/wiki/` dan tambah panggilan sebelum itu. ## Runners diff --git a/wiki/QualityChecksCSharp.da.md b/docs/wiki/QualityChecksCSharp.da.md similarity index 100% rename from wiki/QualityChecksCSharp.da.md rename to docs/wiki/QualityChecksCSharp.da.md diff --git a/wiki/QualityChecksCSharp.md b/docs/wiki/QualityChecksCSharp.md similarity index 100% rename from wiki/QualityChecksCSharp.md rename to docs/wiki/QualityChecksCSharp.md diff --git a/wiki/QualityChecksCSharp.ms.md b/docs/wiki/QualityChecksCSharp.ms.md similarity index 100% rename from wiki/QualityChecksCSharp.ms.md rename to docs/wiki/QualityChecksCSharp.ms.md diff --git a/wiki/QualityChecksCpp.da.md b/docs/wiki/QualityChecksCpp.da.md similarity index 100% rename from wiki/QualityChecksCpp.da.md rename to docs/wiki/QualityChecksCpp.da.md diff --git a/wiki/QualityChecksCpp.md b/docs/wiki/QualityChecksCpp.md similarity index 100% rename from wiki/QualityChecksCpp.md rename to docs/wiki/QualityChecksCpp.md diff --git a/wiki/QualityChecksCpp.ms.md b/docs/wiki/QualityChecksCpp.ms.md similarity index 100% rename from wiki/QualityChecksCpp.ms.md rename to docs/wiki/QualityChecksCpp.ms.md diff --git a/wiki/QualityChecksPythonShell.da.md b/docs/wiki/QualityChecksPythonShell.da.md similarity index 100% rename from wiki/QualityChecksPythonShell.da.md rename to docs/wiki/QualityChecksPythonShell.da.md diff --git a/wiki/QualityChecksPythonShell.md b/docs/wiki/QualityChecksPythonShell.md similarity index 100% rename from wiki/QualityChecksPythonShell.md rename to docs/wiki/QualityChecksPythonShell.md diff --git a/wiki/QualityChecksPythonShell.ms.md b/docs/wiki/QualityChecksPythonShell.ms.md similarity index 100% rename from wiki/QualityChecksPythonShell.ms.md rename to docs/wiki/QualityChecksPythonShell.ms.md diff --git a/wiki/Troubleshooting.da.md b/docs/wiki/Troubleshooting.da.md similarity index 77% rename from wiki/Troubleshooting.da.md rename to docs/wiki/Troubleshooting.da.md index b05c6b4..1590aff 100644 --- a/wiki/Troubleshooting.da.md +++ b/docs/wiki/Troubleshooting.da.md @@ -1,4 +1,4 @@ - + > Dette er en oversættelse af [`Troubleshooting`](Troubleshooting). Den engelske side er autoritativ, og ændringer her bliver overskrevet, næste gang wikien publiceres. @@ -30,11 +30,13 @@ Kategorien fortæller, hvor du skal kigge. En fejl uden for scriptet (jobbet sta | `TOKEN_FOR_GITEA is missing or empty.` | configuration | Tilføj secreten | | `Could not determine the Gitea source repository.` | configuration | Kørslen har intet repositorynavn; meld det som en defekt | | `Expected at most one GitHub push mirror ... found N` | configuration | Behold ét GitHub push-spejl | -| `TOKEN_FOR_GITEA_WIKI is missing or empty.` | configuration | Kun wiki-publicering: repositoryet har meldt sig til med `wiki/.publish`, men dets organisation har ingen sådan secret; gem den (se [credentials.md](Credentials.da)) | -| `wiki/.publish may only be empty or contain the word 'prune'.` | configuration | Kun wiki-publicering: lad markøren være tom, eller skriv kun ordet `prune` i den | +| `TOKEN_FOR_GITEA_WIKI is missing or empty.` | configuration | Kun wiki-publicering: repositoryet kalder workflowet, men dets organisation har ingen sådan secret, eller kaldet sender den ikke; gem den og send den i `secrets:` (se [credentials.md](Credentials.da)) | +| `wiki/.publish may only be empty or contain the word 'prune'.` | configuration | Kun wiki-publicering gennem det ældre scoped workflow: lad markøren være tom, eller skriv kun ordet `prune` i den | +| `The prune input must be 'true' or 'false'` | configuration | Kun wiki-publicering: sæt `prune` i kaldet til `"true"` eller `"false"` | +| `The wiki folder ... does not exist` | configuration | Kun wiki-publicering: sæt `wiki_dir` i kaldet til mappen med siderne (standard `docs/wiki`) | | `... HTTP 403 ...` ved publicering af wikien | permissions | Kun wiki-publicering: tokenet skal have `write:repository` og skriveadgang til dette repository | | `The wiki is not enabled on ` | configuration | Kun wiki-publicering: aktivér wikien i repositoryets indstillinger | -| `The wiki source directory ... has no Markdown pages` | configuration | Kun wiki-publicering: `wiki/` er tom eller mangler; intet blev ændret | +| `The wiki source directory ... has no Markdown pages` | configuration | Kun wiki-publicering: mappen har ingen Markdown-sider; intet blev ændret | | `Could not determine the GitHub owner and repository ...` | configuration | Spejlets adresse skal se ud som `https://github.com//.git` | | `Gitea API request failed with HTTP 401` | credentials | Opret et nyt Gitea-token, og opdatér `TOKEN_FOR_GITEA` | | `GitHub API request failed with HTTP 401` | credentials | Opret et nyt GitHub-token, og opdatér `PAT_FOR_GITHUB`; værdien skal kun være tokenet (intet navn, ingen anførselstegn eller JSON) | @@ -51,9 +53,9 @@ Kategorien fortæller, hvor du skal kigge. En fejl uden for scriptet (jobbet sta `WARNING: Gitea returned an invalid push mirror list; GitHub metadata was not synced.` Kørslen lykkes, men intet blev synkroniseret. Kontroller, at Gitea-versionen understøtter push mirror-API'et, og kør igen. -`No wiki/.publish marker in /; wiki publishing is not enabled for this repository.` Kørslen af Publish wiki lykkes og skriver intet. Repositoryet har ikke meldt sig til; tilføj `wiki/.publish`, hvis det skal publicere. +`No wiki/.publish marker in /; wiki publishing is not enabled for this repository.` Kørslen af det ældre scoped Publish wiki lykkes og skriver intet. Repositoryet har ikke meldt sig til; kald det genbrugelige workflow **Publish wiki pages** (se [onboarding.md](Onboarding.da)), hvis det skal publicere. -` page(s) are in the wiki but not in wiki/ and were kept; put the word 'prune' in wiki/.publish to delete them.` Kørslen lykkes. Sider, der kun findes i wikien, lades i fred, medmindre markøren indeholder `prune`. +` page(s) are in the wiki but not in / and were kept; set the prune input to true to delete them.` Kørslen lykkes. Sider, der kun findes i wikien, lades i fred, medmindre kaldet sætter `prune: "true"` (med det ældre scoped workflow: ordet `prune` i `wiki/.publish`). ## Runner-problemer diff --git a/wiki/Troubleshooting.md b/docs/wiki/Troubleshooting.md similarity index 78% rename from wiki/Troubleshooting.md rename to docs/wiki/Troubleshooting.md index cebe8e6..8f17492 100644 --- a/wiki/Troubleshooting.md +++ b/docs/wiki/Troubleshooting.md @@ -32,11 +32,13 @@ never starts, or stops before the step) is a **runner** problem. | `TOKEN_FOR_GITEA is missing or empty.` | configuration | Add the secret | | `Could not determine the Gitea source repository.` | configuration | The run has no repository name; report as a defect | | `Expected at most one GitHub push mirror ... found N` | configuration | Keep one GitHub push mirror | -| `TOKEN_FOR_GITEA_WIKI is missing or empty.` | configuration | Wiki publishing only: the repository opted in with `wiki/.publish` but its organization has no such secret; store it (see [credentials.md](Credentials)) | -| `wiki/.publish may only be empty or contain the word 'prune'.` | configuration | Wiki publishing only: leave the marker empty, or put only the word `prune` in it | +| `TOKEN_FOR_GITEA_WIKI is missing or empty.` | configuration | Wiki publishing only: the repository calls the workflow but its organization has no such secret, or the call does not pass it; store it and pass it in `secrets:` (see [credentials.md](Credentials)) | +| `wiki/.publish may only be empty or contain the word 'prune'.` | configuration | Wiki publishing through the older scoped workflow only: leave the marker empty, or put only the word `prune` in it | +| `The prune input must be 'true' or 'false'` | configuration | Wiki publishing only: set `prune` in the call to `"true"` or `"false"` | +| `The wiki folder ... does not exist` | configuration | Wiki publishing only: set `wiki_dir` in the call to the folder with the pages (default `docs/wiki`) | | `... HTTP 403 ...` while publishing the wiki | permissions | Wiki publishing only: the token needs `write:repository` and write access to this repository | | `The wiki is not enabled on ` | configuration | Wiki publishing only: enable the wiki in the repository settings | -| `The wiki source directory ... has no Markdown pages` | configuration | Wiki publishing only: `wiki/` is empty or missing; nothing was changed | +| `The wiki source directory ... has no Markdown pages` | configuration | Wiki publishing only: the folder has no Markdown pages; nothing was changed | | `Could not determine the GitHub owner and repository ...` | configuration | The mirror address must look like `https://github.com//.git` | | `Gitea API request failed with HTTP 401` | credentials | Create a new Gitea token and update `TOKEN_FOR_GITEA` | | `GitHub API request failed with HTTP 401` | credentials | Create a new GitHub token and update `PAT_FOR_GITHUB`; the value must be the token only (no name, quotes or JSON) | @@ -59,12 +61,14 @@ synced.` The run succeeds but nothing was synced. Check that the Gitea version supports the push mirror API and re-run. `No wiki/.publish marker in /; wiki publishing is not enabled for -this repository.` The Publish wiki run succeeds and writes nothing. The -repository has not opted in; add `wiki/.publish` if it should publish. +this repository.` The older scoped Publish wiki run succeeds and writes +nothing. The repository has not opted in; call the reusable workflow +**Publish wiki pages** (see [onboarding.md](Onboarding)) if it should publish. -` page(s) are in the wiki but not in wiki/ and were kept; put the word -'prune' in wiki/.publish to delete them.` The run succeeds. Pages that exist -only in the wiki are left alone unless the marker contains `prune`. +` page(s) are in the wiki but not in / and were kept; set the prune +input to true to delete them.` The run succeeds. Pages that exist only in the +wiki are left alone unless the call sets `prune: "true"` (with the older scoped +workflow: the word `prune` in `wiki/.publish`). ## Runner problems diff --git a/wiki/Troubleshooting.ms.md b/docs/wiki/Troubleshooting.ms.md similarity index 75% rename from wiki/Troubleshooting.ms.md rename to docs/wiki/Troubleshooting.ms.md index b0cad32..9db874b 100644 --- a/wiki/Troubleshooting.ms.md +++ b/docs/wiki/Troubleshooting.ms.md @@ -1,4 +1,4 @@ - + > Ini ialah terjemahan [`Troubleshooting`](Troubleshooting). Halaman bahasa Inggeris ialah teks yang sah, dan perubahan di sini akan ditimpa pada penerbitan wiki yang seterusnya. @@ -30,11 +30,13 @@ Kategori menunjukkan di mana perlu dilihat. Kegagalan di luar skrip (kerja tidak | `TOKEN_FOR_GITEA is missing or empty.` | configuration | Tambah secret | | `Could not determine the Gitea source repository.` | configuration | Larian tiada nama repositori; laporkan sebagai kecacatan | | `Expected at most one GitHub push mirror ... found N` | configuration | Kekalkan satu push mirror GitHub | -| `TOKEN_FOR_GITEA_WIKI is missing or empty.` | configuration | Penerbitan wiki sahaja: repositori telah memilih menyertainya dengan `wiki/.publish` tetapi organisasinya tiada secret itu; simpannya (lihat [credentials.md](Credentials.ms)) | -| `wiki/.publish may only be empty or contain the word 'prune'.` | configuration | Penerbitan wiki sahaja: biarkan penanda kosong, atau letakkan hanya perkataan `prune` di dalamnya | +| `TOKEN_FOR_GITEA_WIKI is missing or empty.` | configuration | Penerbitan wiki sahaja: repositori memanggil aliran kerja tetapi organisasinya tiada secret itu, atau panggilan tidak menghantarnya; simpannya dan hantar dalam `secrets:` (lihat [credentials.md](Credentials.ms)) | +| `wiki/.publish may only be empty or contain the word 'prune'.` | configuration | Penerbitan wiki melalui aliran kerja scoped yang lebih lama sahaja: biarkan penanda kosong, atau letakkan hanya perkataan `prune` di dalamnya | +| `The prune input must be 'true' or 'false'` | configuration | Penerbitan wiki sahaja: tetapkan `prune` dalam panggilan kepada `"true"` atau `"false"` | +| `The wiki folder ... does not exist` | configuration | Penerbitan wiki sahaja: tetapkan `wiki_dir` dalam panggilan kepada folder yang mengandungi halaman (lalai `docs/wiki`) | | `... HTTP 403 ...` semasa menerbitkan wiki | permissions | Penerbitan wiki sahaja: token memerlukan `write:repository` dan akses tulis kepada repositori ini | | `The wiki is not enabled on ` | configuration | Penerbitan wiki sahaja: aktifkan wiki dalam tetapan repositori | -| `The wiki source directory ... has no Markdown pages` | configuration | Penerbitan wiki sahaja: `wiki/` kosong atau tiada; tiada apa-apa diubah | +| `The wiki source directory ... has no Markdown pages` | configuration | Penerbitan wiki sahaja: folder itu tiada halaman Markdown; tiada apa-apa diubah | | `Could not determine the GitHub owner and repository ...` | configuration | Alamat cermin mesti kelihatan seperti `https://github.com//.git` | | `Gitea API request failed with HTTP 401` | credentials | Cipta token Gitea baharu dan kemas kini `TOKEN_FOR_GITEA` | | `GitHub API request failed with HTTP 401` | credentials | Cipta token GitHub baharu dan kemas kini `PAT_FOR_GITHUB`; nilai mesti token sahaja (tiada nama, tanda petikan atau JSON) | @@ -51,9 +53,9 @@ Kategori menunjukkan di mana perlu dilihat. Kegagalan di luar skrip (kerja tidak `WARNING: Gitea returned an invalid push mirror list; GitHub metadata was not synced.` Larian berjaya tetapi tiada apa-apa disegerakkan. Semak bahawa versi Gitea menyokong API push mirror dan jalankan semula. -`No wiki/.publish marker in /; wiki publishing is not enabled for this repository.` Larian Publish wiki berjaya dan tidak menulis apa-apa. Repositori belum memilih menyertainya; tambah `wiki/.publish` jika ia sepatutnya menerbitkan. +`No wiki/.publish marker in /; wiki publishing is not enabled for this repository.` Larian Publish wiki scoped yang lebih lama berjaya dan tidak menulis apa-apa. Repositori belum memilih menyertainya; panggil aliran kerja boleh guna semula **Publish wiki pages** (lihat [onboarding.md](Onboarding.ms)) jika ia sepatutnya menerbitkan. -` page(s) are in the wiki but not in wiki/ and were kept; put the word 'prune' in wiki/.publish to delete them.` Larian berjaya. Halaman yang hanya ada dalam wiki dibiarkan melainkan penanda mengandungi `prune`. +` page(s) are in the wiki but not in / and were kept; set the prune input to true to delete them.` Larian berjaya. Halaman yang hanya ada dalam wiki dibiarkan melainkan panggilan menetapkan `prune: "true"` (dengan aliran kerja scoped yang lebih lama: perkataan `prune` dalam `wiki/.publish`). ## Masalah runner diff --git a/wiki/Upgrading.da.md b/docs/wiki/Upgrading.da.md similarity index 100% rename from wiki/Upgrading.da.md rename to docs/wiki/Upgrading.da.md diff --git a/wiki/Upgrading.md b/docs/wiki/Upgrading.md similarity index 100% rename from wiki/Upgrading.md rename to docs/wiki/Upgrading.md diff --git a/wiki/Upgrading.ms.md b/docs/wiki/Upgrading.ms.md similarity index 100% rename from wiki/Upgrading.ms.md rename to docs/wiki/Upgrading.ms.md diff --git a/wiki/_Sidebar.md b/docs/wiki/_Sidebar.md similarity index 100% rename from wiki/_Sidebar.md rename to docs/wiki/_Sidebar.md diff --git a/guides/credentials.md b/guides/credentials.md index 7b2feb0..cbf6866 100644 --- a/guides/credentials.md +++ b/guides/credentials.md @@ -82,29 +82,30 @@ is ever printed. ## Wiki publishing secret -The workflow **Publish wiki** copies `wiki/` to the Gitea wiki of a repository -that has opted in with `wiki/.publish` (see [onboarding.md](onboarding.md)). It -uses its own secret, so the metadata sync token stays read-only. +The workflow **Publish wiki pages** copies `docs/wiki/` to the Gitea wiki of a +repository that calls it (see [onboarding.md](onboarding.md)). It uses its own +secret, so the metadata sync token stays read-only. The caller passes the +secret in `secrets:`; it is not inherited. | Secret | Content | Used for | | --- | --- | --- | | `TOKEN_FOR_GITEA_WIKI` | The Gitea token, nothing else | Writing the wiki pages of the repositories of an organization that opt in | - Store it as a secret of the organization of each repository that publishes. - There is no fallback to `TOKEN_FOR_GITEA`: a repository that opted in and has - no such secret fails with a configuration error, and a repository that did - not opt in does not need it. + There is no fallback to `TOKEN_FOR_GITEA`: a repository that calls the + workflow and has no such secret fails with a configuration error, and a + repository that does not call it does not need it. - The token needs scope `write:repository`, and its user needs write access to the repositories. Gitea has no wiki-only scope, so create the token for a dedicated user. S05 approves the scope and S03 stores the secret. - Calls made: `GET /repos/{owner}/{repo}`, `GET /repos/{owner}/{repo}/wiki/pages`, `GET`, `POST` and `PATCH /repos/{owner}/{repo}/wiki/...` and, for a page that - no longer exists in `wiki/`, `DELETE /repos/{owner}/{repo}/wiki/page/{name}`. + no longer exists in `docs/wiki/`, `DELETE /repos/{owner}/{repo}/wiki/page/{name}`. - The wiki must be enabled in the repository settings. The workflow refuses to run when it is not. -- Pages that are in `wiki/` are always overwritten from it, so a change made - in the Gitea web UI is lost on the next publish. Pages that are only in the - wiki are removed only when `wiki/.publish` contains the word `prune`. +- Pages that are in `docs/wiki/` are always overwritten from it, so a change + made in the Gitea web UI is lost on the next publish. Pages that are only in + the wiki are removed only when the call sets `prune: "true"`. ## Rotating a token diff --git a/guides/onboarding.md b/guides/onboarding.md index 101a9c9..75eac9b 100644 --- a/guides/onboarding.md +++ b/guides/onboarding.md @@ -45,25 +45,43 @@ Delivery is automatic, so a repository needs no copy of the workflow. Secrets ar ## Publish a wiki (optional) -The **Publish wiki** workflow copies the Markdown pages in `wiki/` to the -repository wiki when a change to `wiki/` is merged to `main`. It is delivered -like the sync workflow, but it writes only where a repository opts in. +The reusable workflow **Publish wiki pages** copies the Markdown pages in +`docs/wiki/` to the repository wiki when a change to `docs/wiki/` is merged to +`main`. The repository calls it, so nothing is written where no call exists. +The wiki has English and the product owner's language as a minimum. 1. Enable the wiki in the repository settings. -2. Add Markdown pages to `wiki/`. The file name is the page name: `Home.md` is - the home page. A hyphen in the name is a space in the page name: `Home-da.md` - is the page "Home da", and a link to it is `[Dansk](Home-da)`. -3. Add the marker `wiki/.publish`. Leave it empty to create and update pages - only. Put the single word `prune` in it to also delete wiki pages that are - not in `wiki/`, so the wiki always equals the folder. +2. Add Markdown pages to `docs/wiki/`. The file name is the page name: `Home.md` + is the home page. A hyphen in the name is a space in the page name: + `Home-da.md` is the page "Home da", and a link to it is `[Dansk](Home-da)`. +3. Add a workflow, for example `.gitea/workflows/publish-wiki.yml`, that calls + the reusable workflow: + + ```yaml + on: + push: + branches: [ main ] + paths: [ "docs/wiki/**" ] + jobs: + wiki: + uses: TirSystem/github-action/.gitea/workflows/publish-wiki-pages.yml@v1 + with: + prune: "true" + secrets: + TOKEN_FOR_GITEA_WIKI: ${{ secrets.TOKEN_FOR_GITEA_WIKI }} + ``` + + `wiki_dir` defaults to `docs/wiki`. `prune: "true"` also deletes wiki pages + that are not in the folder, so the wiki always equals the folder; the + default `false` keeps them. 4. Store `TOKEN_FOR_GITEA_WIKI` as a secret of the repository's organization, using the scope in [credentials.md](credentials.md). 5. Merge the change to `main`. The log must end with `Published page(s) to the wiki of /`. -A repository without `wiki/.publish` is skipped with the line `No -wiki/.publish marker in /`: nothing is written and no secret is -needed. +A repository that still has the marker `wiki/.publish` is published by the +older scoped workflow, which is removed once every repository has a call. +Move the pages to `docs/wiki/` and add the call before that. ## Runners diff --git a/guides/troubleshooting.md b/guides/troubleshooting.md index 82fc5e4..759da13 100644 --- a/guides/troubleshooting.md +++ b/guides/troubleshooting.md @@ -26,11 +26,13 @@ never starts, or stops before the step) is a **runner** problem. | `TOKEN_FOR_GITEA is missing or empty.` | configuration | Add the secret | | `Could not determine the Gitea source repository.` | configuration | The run has no repository name; report as a defect | | `Expected at most one GitHub push mirror ... found N` | configuration | Keep one GitHub push mirror | -| `TOKEN_FOR_GITEA_WIKI is missing or empty.` | configuration | Wiki publishing only: the repository opted in with `wiki/.publish` but its organization has no such secret; store it (see [credentials.md](credentials.md)) | -| `wiki/.publish may only be empty or contain the word 'prune'.` | configuration | Wiki publishing only: leave the marker empty, or put only the word `prune` in it | +| `TOKEN_FOR_GITEA_WIKI is missing or empty.` | configuration | Wiki publishing only: the repository calls the workflow but its organization has no such secret, or the call does not pass it; store it and pass it in `secrets:` (see [credentials.md](credentials.md)) | +| `wiki/.publish may only be empty or contain the word 'prune'.` | configuration | Wiki publishing through the older scoped workflow only: leave the marker empty, or put only the word `prune` in it | +| `The prune input must be 'true' or 'false'` | configuration | Wiki publishing only: set `prune` in the call to `"true"` or `"false"` | +| `The wiki folder ... does not exist` | configuration | Wiki publishing only: set `wiki_dir` in the call to the folder with the pages (default `docs/wiki`) | | `... HTTP 403 ...` while publishing the wiki | permissions | Wiki publishing only: the token needs `write:repository` and write access to this repository | | `The wiki is not enabled on ` | configuration | Wiki publishing only: enable the wiki in the repository settings | -| `The wiki source directory ... has no Markdown pages` | configuration | Wiki publishing only: `wiki/` is empty or missing; nothing was changed | +| `The wiki source directory ... has no Markdown pages` | configuration | Wiki publishing only: the folder has no Markdown pages; nothing was changed | | `Could not determine the GitHub owner and repository ...` | configuration | The mirror address must look like `https://github.com//.git` | | `Gitea API request failed with HTTP 401` | credentials | Create a new Gitea token and update `TOKEN_FOR_GITEA` | | `GitHub API request failed with HTTP 401` | credentials | Create a new GitHub token and update `PAT_FOR_GITHUB`; the value must be the token only (no name, quotes or JSON) | @@ -53,12 +55,14 @@ synced.` The run succeeds but nothing was synced. Check that the Gitea version supports the push mirror API and re-run. `No wiki/.publish marker in /; wiki publishing is not enabled for -this repository.` The Publish wiki run succeeds and writes nothing. The -repository has not opted in; add `wiki/.publish` if it should publish. +this repository.` The older scoped Publish wiki run succeeds and writes +nothing. The repository has not opted in; call the reusable workflow +**Publish wiki pages** (see [onboarding.md](onboarding.md)) if it should publish. -` page(s) are in the wiki but not in wiki/ and were kept; put the word -'prune' in wiki/.publish to delete them.` The run succeeds. Pages that exist -only in the wiki are left alone unless the marker contains `prune`. +` page(s) are in the wiki but not in / and were kept; set the prune +input to true to delete them.` The run succeeds. Pages that exist only in the +wiki are left alone unless the call sets `prune: "true"` (with the older scoped +workflow: the word `prune` in `wiki/.publish`). ## Runner problems diff --git a/tests/test_build_wiki.py b/tests/test_build_wiki.py index 2c19048..7cf5958 100644 --- a/tests/test_build_wiki.py +++ b/tests/test_build_wiki.py @@ -271,7 +271,7 @@ def _shape(text: str) -> dict: @pytest.mark.parametrize("code", [code for code, _label in build_wiki.LANGUAGES]) def test_committed_translations_follow_the_english_structure(page, code): """A translation has the same code blocks, table rows and heading levels.""" - wiki = REPO_ROOT / "wiki" + wiki = REPO_ROOT / "docs" / "wiki" english = _shape((wiki / f"{page}.md").read_text(encoding="utf-8")) translated = _shape((wiki / f"{page}.{code}.md").read_text(encoding="utf-8")) assert translated == english @@ -306,7 +306,7 @@ class TestSidebar: def test_home_lists_every_workflow_file_with_a_diagram(): """The Home page names each workflow file of the repository and draws it.""" - home = (REPO_ROOT / "wiki" / "Home.md").read_text(encoding="utf-8") + home = (REPO_ROOT / "docs" / "wiki" / "Home.md").read_text(encoding="utf-8") files = sorted( path.name for folder in (".gitea/scoped_workflows", ".gitea/workflows") diff --git a/tests/test_publish_wiki.py b/tests/test_publish_wiki.py index 2d395ba..7dab8ae 100644 --- a/tests/test_publish_wiki.py +++ b/tests/test_publish_wiki.py @@ -1,4 +1,4 @@ -"""Offline tests for tools/publish_wiki.py and the scoped publish-wiki workflow.""" +"""Offline tests for tools/publish_wiki.py and the publish-wiki workflows.""" import base64 import io @@ -9,6 +9,8 @@ import yaml from workflow_source import PUBLISH_WORKFLOW, REPO_ROOT, load_publish_module +REUSABLE_WORKFLOW = REPO_ROOT / ".gitea" / "workflows" / "publish-wiki-pages.yml" + API = "https://git.example.test/api/v1" REPO_URL = f"{API}/repos/TirSystem/repo" WIKI_URL = f"{REPO_URL}/wiki" @@ -450,6 +452,121 @@ class TestRequestJson: assert caught.value.category == "api" +class TestExplicitPrune: + """The reusable workflow sets WIKI_PRUNE: the caller is the opt-in (MIL-008).""" + + @pytest.fixture() + def explicit(self, environment, monkeypatch): + (environment / ".publish").unlink() + monkeypatch.setenv("WIKI_PRUNE", "false") + return environment + + @pytest.mark.parametrize( + ("text", "expected"), [("true", True), (" TRUE\n", True), ("false", False)] + ) + def test_reads_true_and_false(self, publish_wiki, text, expected): + assert publish_wiki.parse_prune_setting(text) is expected + + @pytest.mark.parametrize("text", ["", "yes", "prune", None]) + def test_rejects_anything_else(self, publish_wiki, text): + with pytest.raises(publish_wiki.WorkflowError) as caught: + publish_wiki.parse_prune_setting(text) + assert caught.value.category == "configuration" + + def test_publishes_without_a_marker_and_keeps_other_pages( + self, publish_wiki, explicit, capsys + ): + gitea = FakeGitea(publish_wiki, wiki={"Old": b64("hand written")}) + + assert run_main(publish_wiki, gitea) == 0 + + assert set(gitea.wiki) == {"Old", "Home", "Credentials"} + assert "set the prune input to true" in capsys.readouterr().out + + def test_prune_true_deletes_pages_outside_the_folder( + self, publish_wiki, explicit, monkeypatch + ): + monkeypatch.setenv("WIKI_PRUNE", "true") + gitea = FakeGitea(publish_wiki, wiki={"Old": b64("stale")}) + + assert run_main(publish_wiki, gitea) == 0 + + assert set(gitea.wiki) == {"Home", "Credentials"} + + def test_a_missing_folder_is_a_configuration_error_before_any_request( + self, publish_wiki, explicit, monkeypatch, tmp_path + ): + monkeypatch.setenv("WIKI_DIR", str(tmp_path / "docs" / "wiki")) + gitea = FakeGitea(publish_wiki) + + with pytest.raises(publish_wiki.WorkflowError, match="wiki_dir") as caught: + run_main(publish_wiki, gitea) + + assert caught.value.category == "configuration" + assert gitea.calls == [] + + def test_an_empty_folder_never_deletes_pages_even_with_prune( + self, publish_wiki, explicit, monkeypatch + ): + monkeypatch.setenv("WIKI_PRUNE", "true") + for page in explicit.glob("*.md"): + page.unlink() + gitea = FakeGitea(publish_wiki, wiki={"Home": b64("home")}) + + with pytest.raises(publish_wiki.WorkflowError) as caught: + run_main(publish_wiki, gitea) + + assert caught.value.category == "configuration" + assert gitea.writes == [] + + def test_a_missing_secret_fails_before_any_request( + self, publish_wiki, explicit, monkeypatch + ): + monkeypatch.setenv("WIKI_CREDENTIALS", "") + gitea = FakeGitea(publish_wiki) + + with pytest.raises(publish_wiki.WorkflowError, match="TOKEN_FOR_GITEA_WIKI"): + run_main(publish_wiki, gitea) + + assert gitea.calls == [] + + +class TestReusableWorkflow: + @pytest.fixture() + def document(self): + return yaml.safe_load(REUSABLE_WORKFLOW.read_text(encoding="utf-8")) + + def test_is_called_and_has_no_other_trigger(self, document): + assert list(document[True]) == ["workflow_call"] + + def test_the_folder_defaults_to_docs_wiki_and_nothing_is_pruned_by_default(self, document): + inputs = document[True]["workflow_call"]["inputs"] + assert inputs["wiki_dir"]["default"] == "docs/wiki" + assert inputs["prune"]["default"] == "false" + + def test_the_token_is_a_declared_secret_without_a_fallback(self, document): + text = REUSABLE_WORKFLOW.read_text(encoding="utf-8") + assert document[True]["workflow_call"]["secrets"]["TOKEN_FOR_GITEA_WIKI"]["required"] + assert "secrets.TOKEN_FOR_GITEA }}" not in text + assert "github.token" not in text + + def test_job_has_read_only_permissions(self, document): + assert document["jobs"]["publish-wiki"]["permissions"] == {"contents": "read"} + + def test_the_inputs_reach_the_script_through_the_environment(self, document): + step = document["jobs"]["publish-wiki"]["steps"][-1] + assert step["env"]["WIKI_DIR"] == "${{ inputs.wiki_dir }}" + assert step["env"]["WIKI_PRUNE"] == "${{ inputs.prune }}" + assert step["env"]["WIKI_CREDENTIALS"] == "${{ secrets.TOKEN_FOR_GITEA_WIKI }}" + assert step["run"] == "python3 shared-scripts/tools/publish_wiki.py" + assert "inputs." not in step["run"] + + def test_the_script_is_fetched_at_the_tools_ref(self, document): + fetch = document["jobs"]["publish-wiki"]["steps"][1]["with"] + assert fetch["repository"] == "TirSystem/github-action" + assert fetch["ref"] == "${{ inputs.tools-ref }}" + + class TestWorkflow: @pytest.fixture() def document(self): @@ -471,8 +588,7 @@ class TestWorkflow: assert publish_step["env"]["WIKI_CREDENTIALS"] == "${{ secrets.TOKEN_FOR_GITEA_WIKI }}" assert "secrets" not in publish_step["run"] - def test_the_workflow_has_one_source_and_runs_the_script_file(self, document): - assert not (REPO_ROOT / ".gitea" / "workflows" / "publish-wiki.yml").exists() + def test_the_scoped_workflow_runs_the_script_file(self, document): assert (REPO_ROOT / "tools" / "publish_wiki.py").is_file() steps = document["jobs"]["publish-wiki"]["steps"] assert "python3 - <<" not in PUBLISH_WORKFLOW.read_text(encoding="utf-8") @@ -485,7 +601,15 @@ class TestWorkflow: assert steps[-1]["run"] == "python3 shared-scripts/tools/publish_wiki.py" -def test_this_repository_opts_in_and_prunes(): - """The wiki of this repository must equal wiki/ (ADR-0001, ADR-0004).""" - marker = REPO_ROOT / "wiki" / ".publish" - assert marker.read_text(encoding="utf-8").strip() == "prune" +def test_this_repository_publishes_docs_wiki_through_the_reusable_workflow(): + """The wiki of this repository equals docs/wiki/ (ADR-0009, MIL-008 task 4).""" + assert not (REPO_ROOT / "wiki").exists() + assert (REPO_ROOT / "docs" / "wiki" / "Home.md").is_file() + caller = yaml.safe_load( + (REPO_ROOT / ".gitea" / "workflows" / "publish-own-wiki.yml").read_text(encoding="utf-8") + ) + job = caller["jobs"]["wiki"] + assert job["uses"] == "./.gitea/workflows/publish-wiki-pages.yml" + assert job["with"]["wiki_dir"] == "docs/wiki" + assert job["with"]["prune"] == "true" + assert caller[True]["push"]["paths"] == ["docs/wiki/**"] diff --git a/tests/test_tool_entrypoints.py b/tests/test_tool_entrypoints.py index 6df4531..0cf423b 100644 --- a/tests/test_tool_entrypoints.py +++ b/tests/test_tool_entrypoints.py @@ -281,7 +281,7 @@ class TestBuildWikiCommandLine: monkeypatch.setattr(build_wiki._module, "check_translations", lambda: []) assert build_wiki["main"](["--check"]) == 1 err = capsys.readouterr().err - assert "ERROR: wiki/Home.md: missing" in err + assert "ERROR: docs/wiki/Home.md: missing" in err assert "python tools/build_wiki.py" in err def test_generate_reports_the_changed_pages(self, monkeypatch, capsys): @@ -320,7 +320,7 @@ class TestRunAsAProcess: assert result.stderr.startswith("ERROR: [configuration]") def test_publish_wiki_without_a_repository_exits_1(self): - result = run_tool("publish_wiki.py", WIKI_DIR=str(REPO_ROOT / "wiki"), GITEA_API_URL="https://x") + result = run_tool("publish_wiki.py", WIKI_DIR=str(REPO_ROOT / "docs" / "wiki"), GITEA_API_URL="https://x") assert result.returncode == 1 assert "ERROR:" in result.stderr diff --git a/tests/test_workflows.py b/tests/test_workflows.py index 5d249e4..cd2bd38 100644 --- a/tests/test_workflows.py +++ b/tests/test_workflows.py @@ -29,7 +29,8 @@ class TestEachWorkflow: def test_every_job_declares_permissions_and_runner(self, path): document = yaml.safe_load(path.read_text(encoding="utf-8")) for name, job in document["jobs"].items(): - assert "runs-on" in job, f"job {name} has no runs-on" + if "uses" not in job: # a called workflow has its own runner + assert "runs-on" in job, f"job {name} has no runs-on" assert "permissions" in job, f"job {name} has no explicit permissions" diff --git a/tools/build_wiki.py b/tools/build_wiki.py index c007265..66e6440 100644 --- a/tools/build_wiki.py +++ b/tools/build_wiki.py @@ -1,4 +1,4 @@ -"""Build the English wiki pages in ``wiki/`` from ``README.md`` and ``guides/``. +"""Build the English wiki pages in ``docs/wiki/`` from ``README.md`` and ``guides/``. The wiki source lives in this repository (MIL-005). The English pages are generated, never edited by hand; ``--check`` reports a page that differs from @@ -18,7 +18,7 @@ from dataclasses import dataclass from pathlib import Path REPO_ROOT = Path(__file__).resolve().parent.parent -WIKI_DIR = REPO_ROOT / "wiki" +WIKI_DIR = REPO_ROOT / "docs" / "wiki" SOURCE_BASE_URL = "https://git.tirsystem.com/TirSystem/github-action/src/branch/main" GENERATOR = "tools/build_wiki.py" @@ -50,7 +50,7 @@ PAGES: tuple[Page, ...] = ( Page("Capabilities", "README.md", ("Capabilities",)), ) -# Translations (ADR-0001): `.` written by hand in wiki/. +# Translations (ADR-0001): `.` written by hand in docs/wiki/. LANGUAGES: tuple[tuple[str, str], ...] = (("da", "Dansk"), ("ms", "Bahasa Melayu")) HASH_LENGTH = 12 _TRANSLATION_HEADER = re.compile( @@ -304,9 +304,9 @@ def main(argv: list[str] | None = None) -> int: if args.check: problems = check_pages() + check_translations() for problem in problems: - print(f"ERROR: wiki/{problem}", file=sys.stderr) + print(f"ERROR: docs/wiki/{problem}", file=sys.stderr) if problems: - print(f"Run `python {GENERATOR}` and commit wiki/.", file=sys.stderr) + print(f"Run `python {GENERATOR}` and commit docs/wiki/.", file=sys.stderr) return 1 print("Wiki pages are up to date.") return 0 diff --git a/tools/publish_wiki.py b/tools/publish_wiki.py index f6fb657..7069512 100644 --- a/tools/publish_wiki.py +++ b/tools/publish_wiki.py @@ -1,15 +1,19 @@ -"""Publish the pages in wiki/ to the Gitea wiki of the repository. +"""Publish the pages of a folder to the Gitea wiki of the repository. -Run by the scoped workflow publish-wiki.yml, which checks out the repository -that owns the wiki and this repository, and runs this file (MIL-004 task 6). -A repository publishes only when it has opted in with wiki/.publish -(ADR-0004); the word prune in that file lets the run delete wiki pages that -are not in wiki/. It reads its settings from the environment: +Run by the reusable workflow publish-wiki.yml, which a repository calls +(MIL-008), and by the scoped workflow of the same name until it is removed. +The reusable workflow sets WIKI_PRUNE: the caller is the opt-in, and the +folder must exist. The scoped workflow leaves WIKI_PRUNE unset: a repository +publishes only when it has opted in with WIKI_DIR/.publish (ADR-0004), and the +word prune in that file lets the run delete wiki pages that are not in the +folder. It reads its settings from the environment: GITEA_API_URL Gitea API base, for example https://host/api/v1 SOURCE_REPOSITORY owner/repo of the repository whose wiki is written WIKI_CREDENTIALS the Gitea token, as clear text (TOKEN_FOR_GITEA_WIKI) WIKI_DIR directory with the pages (default: wiki) + WIKI_PRUNE true or false: delete pages that are not in the + folder; when set, no .publish marker is read Every failure is printed as ``ERROR: [category] message`` with the categories configuration, credentials, permissions and api; no secret value is printed. @@ -90,6 +94,16 @@ def parse_marker(text): ) +def parse_prune_setting(text): + """Return the boolean of the WIKI_PRUNE input: true or false, nothing else.""" + word = (text or "").strip().lower() + if word in ("true", "false"): + return word == "true" + raise WorkflowError( + "configuration", f"The prune input must be 'true' or 'false', not '{(text or '').strip()}'." + ) + + def parse_gitea_token(raw_token): token = (raw_token or "").strip() if not token: @@ -243,14 +257,24 @@ def main(): wiki_dir = Path(os.environ.get("WIKI_DIR", "wiki")) owner, repo = split_repository(os.environ.get("SOURCE_REPOSITORY")) - marker = wiki_dir / MARKER_NAME - if not marker.is_file(): - print( - f"No {wiki_dir}/{MARKER_NAME} marker in {owner}/{repo}; " - "wiki publishing is not enabled for this repository." - ) - return 0 - prune = parse_marker(marker.read_text(encoding="utf-8")) + prune_setting = os.environ.get("WIKI_PRUNE") + if prune_setting is None: + marker = wiki_dir / MARKER_NAME + if not marker.is_file(): + print( + f"No {wiki_dir}/{MARKER_NAME} marker in {owner}/{repo}; " + "wiki publishing is not enabled for this repository." + ) + return 0 + prune = parse_marker(marker.read_text(encoding="utf-8")) + else: + prune = parse_prune_setting(prune_setting) + if not wiki_dir.is_dir(): + raise WorkflowError( + "configuration", + f"The wiki folder {wiki_dir} does not exist in {owner}/{repo}; " + "set the wiki_dir input to the folder with the pages.", + ) pages = read_pages(wiki_dir) token = parse_gitea_token(os.environ.get("WIKI_CREDENTIALS")) @@ -292,8 +316,12 @@ def main(): if result["kept"]: print( f"{len(result['kept'])} page(s) are in the wiki but not in " - f"{wiki_dir}/ and were kept; put the word '{PRUNE_WORD}' in " - f"{wiki_dir}/{MARKER_NAME} to delete them." + f"{wiki_dir}/ and were kept; " + + ( + f"put the word '{PRUNE_WORD}' in {wiki_dir}/{MARKER_NAME} to delete them." + if prune_setting is None + else "set the prune input to true to delete them." + ) ) return 0 diff --git a/wiki/.publish b/wiki/.publish deleted file mode 100644 index 9c920ae..0000000 --- a/wiki/.publish +++ /dev/null @@ -1 +0,0 @@ -prune