Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c09106961c | ||
|
|
0f4c6989a4 | ||
|
|
2cfcd02588 | ||
|
|
332d65255c |
@@ -1,41 +0,0 @@
|
|||||||
# Publish the project's wiki pages to the git host's wiki.
|
|
||||||
#
|
|
||||||
# On a push to main that changes docs/wiki/, this workflow calls the reusable
|
|
||||||
# workflow of TirSystem/github-action, which copies the Markdown pages of
|
|
||||||
# docs/wiki/ to the wiki of this repository (framework/process/wiki.md says
|
|
||||||
# what the folder holds: English and the PO language as a minimum).
|
|
||||||
#
|
|
||||||
# INSTALLING THIS FILE IS THE OPT-IN. There is no marker file. A project that
|
|
||||||
# does not copy it publishes nothing.
|
|
||||||
#
|
|
||||||
# Copy it to .gitea/workflows/publish-wiki.yml. Then:
|
|
||||||
# 1. Create the secret TOKEN_FOR_GITEA_WIKI in the organization of the
|
|
||||||
# repository: a Gitea token with scope write:repository for a user that
|
|
||||||
# can write this repository (see guides/credentials.md of github-action).
|
|
||||||
# 2. Enable the wiki in the repository settings.
|
|
||||||
# 3. Keep @v1, or pin the exact release tag together with tools-ref.
|
|
||||||
# A runner must be registered for the repository (or its organization).
|
|
||||||
#
|
|
||||||
# prune: "true" deletes wiki pages that are not in docs/wiki/, so the wiki
|
|
||||||
# always equals the folder. Leave it "false" to keep hand-written pages.
|
|
||||||
|
|
||||||
name: Publish wiki
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [ main ]
|
|
||||||
paths:
|
|
||||||
- "docs/wiki/**"
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
wiki:
|
|
||||||
uses: TirSystem/git-workflows/.gitea/workflows/publish-wiki-pages.yml@v1
|
|
||||||
with:
|
|
||||||
wiki_dir: docs/wiki
|
|
||||||
prune: "true"
|
|
||||||
secrets:
|
|
||||||
TOKEN_FOR_GITEA_WIKI: ${{ secrets.TOKEN_FOR_GITEA_WIKI }}
|
|
||||||
@@ -14,7 +14,8 @@
|
|||||||
# Copy it to .gitea/workflows/sync-milestones.yml (Gitea Actions) or
|
# Copy it to .gitea/workflows/sync-milestones.yml (Gitea Actions) or
|
||||||
# .github/workflows/sync-milestones.yml (GitHub Actions). Then:
|
# .github/workflows/sync-milestones.yml (GitHub Actions). Then:
|
||||||
# 1. Create a CI secret and put its name in the two `secrets.` lines below
|
# 1. Create a CI secret and put its name in the two `secrets.` lines below
|
||||||
# (SYNC_TOKEN is a placeholder). Gitea does not accept secret names that
|
# (TOKEN_FOR_GITEA_ISSUES is the name the
|
||||||
|
# framework uses). Gitea does not accept secret names that
|
||||||
# start with GITEA_ or GITHUB_.
|
# start with GITEA_ or GITHUB_.
|
||||||
# 2. Give the token the smallest scope that works: read and write on issues
|
# 2. Give the token the smallest scope that works: read and write on issues
|
||||||
# and milestones. If the framework submodule is a private repository, the
|
# and milestones. If the framework submodule is a private repository, the
|
||||||
@@ -53,21 +54,32 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
timeout-minutes: 15
|
timeout-minutes: 15
|
||||||
steps:
|
steps:
|
||||||
- name: Check out the project and its framework submodule
|
- name: Check out the project
|
||||||
uses: actions/checkout@v4.2.2
|
uses: actions/checkout@v4.2.2
|
||||||
with:
|
with:
|
||||||
submodules: recursive
|
token: ${{ secrets.TOKEN_FOR_GITEA_ISSUES }}
|
||||||
token: ${{ secrets.SYNC_TOKEN }}
|
|
||||||
|
# The framework submodule is registered with an SSH address, which the runner
|
||||||
|
# cannot use. The address is rewritten to HTTPS for this step only, and the token
|
||||||
|
# goes in through the environment, never on a command line. .gitmodules stays.
|
||||||
|
- name: Fetch the framework submodule over HTTPS
|
||||||
|
env:
|
||||||
|
GIT_CONFIG_COUNT: "2"
|
||||||
|
GIT_CONFIG_KEY_0: url.https://git.tirsystem.com/.insteadOf
|
||||||
|
GIT_CONFIG_VALUE_0: ssh://git@git.tirsystem.com:10022/
|
||||||
|
GIT_CONFIG_KEY_1: http.https://git.tirsystem.com/.extraheader
|
||||||
|
GIT_CONFIG_VALUE_1: "Authorization: token ${{ secrets.TOKEN_FOR_GITEA_ISSUES }}"
|
||||||
|
run: git submodule update --init --recursive
|
||||||
|
|
||||||
- name: Make sure curl and jq are available
|
- name: Make sure curl and jq are available
|
||||||
run: bash framework/scripts/ci-publish-milestones.sh ensure-tools
|
run: bash framework/scripts/ci-publish-milestones.sh ensure-tools
|
||||||
|
|
||||||
- name: Publish accepted milestones
|
- name: Publish accepted milestones
|
||||||
env:
|
env:
|
||||||
# Gitea reads GITEA_TOKEN, GitHub's gh reads GH_TOKEN; both come from
|
# Gitea reads TOKEN_FOR_GITEA_ISSUES, GitHub's gh reads GH_TOKEN; both
|
||||||
# the one secret named above.
|
# come from the one secret named above.
|
||||||
GITEA_TOKEN: ${{ secrets.SYNC_TOKEN }}
|
TOKEN_FOR_GITEA_ISSUES: ${{ secrets.TOKEN_FOR_GITEA_ISSUES }}
|
||||||
GH_TOKEN: ${{ secrets.SYNC_TOKEN }}
|
GH_TOKEN: ${{ secrets.TOKEN_FOR_GITEA_ISSUES }}
|
||||||
# Empty on a push (a real run); "true" or "false" on a manual run.
|
# Empty on a push (a real run); "true" or "false" on a manual run.
|
||||||
DRY_RUN: ${{ inputs.dry_run }}
|
DRY_RUN: ${{ inputs.dry_run }}
|
||||||
run: bash framework/scripts/ci-publish-milestones.sh publish
|
run: bash framework/scripts/ci-publish-milestones.sh publish
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ document of a type. `Primary File` may contain a glob (e.g.
|
|||||||
| PP | Project Plan | docs/project-plan.md | 002 |
|
| PP | Project Plan | docs/project-plan.md | 002 |
|
||||||
| MIL | Milestone / Gateway | docs/milestones/*.md | 011 |
|
| MIL | Milestone / Gateway | docs/milestones/*.md | 011 |
|
||||||
| ADR | Architecture Decision Record | docs/adr/adr-NNNN-*.md | 0004 |
|
| ADR | Architecture Decision Record | docs/adr/adr-NNNN-*.md | 0004 |
|
||||||
| RC | SQA Review Record | docs/sqa/reviews/rc-*.md | 026 |
|
| RC | SQA Review Record | docs/sqa/reviews/rc-*.md | 028 |
|
||||||
| TM | Traceability Matrix | docs/sqa/traceability-matrix.md | 002 |
|
| TM | Traceability Matrix | docs/sqa/traceability-matrix.md | 002 |
|
||||||
| DICT | Domain Dictionary | docs/dictionary.md | 002 |
|
| DICT | Domain Dictionary | docs/dictionary.md | 002 |
|
||||||
|
|
||||||
|
|||||||
|
After Width: | Height: | Size: 878 KiB |
|
After Width: | Height: | Size: 76 KiB |
|
After Width: | Height: | Size: 76 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 73 KiB |
|
After Width: | Height: | Size: 29 KiB |
|
After Width: | Height: | Size: 53 KiB |
|
After Width: | Height: | Size: 878 KiB |
|
After Width: | Height: | Size: 76 KiB |
|
After Width: | Height: | Size: 76 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 73 KiB |
|
After Width: | Height: | Size: 29 KiB |
|
After Width: | Height: | Size: 53 KiB |
@@ -0,0 +1,69 @@
|
|||||||
|
# SQA Review Record
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
| Key | Value |
|
||||||
|
| --- | --- |
|
||||||
|
| ID | RC-027 |
|
||||||
|
| CrossReference | [MIL-008], [QC-WF-001] |
|
||||||
|
|
||||||
|
## Version History
|
||||||
|
| Date | Status | Author | Reviewer | Change | Commit |
|
||||||
|
| --- | --- | --- | --- | --- | --- |
|
||||||
|
| 2026-10-29 | Accepted | Jens Tirsvad Nielsen | AI as stand-in for S02 | Review record, the workflow sync-milestones.yml after the framework update to 0.18.0 and the removal of publish-wiki.yml | [2cfcd02] |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Artifact Under Review
|
||||||
|
|
||||||
|
- Instance reviewed: [MIL-008]
|
||||||
|
- Checklist used: [QC-WF-001] (`QC-WF-001`)
|
||||||
|
- Scope: the workflow sync-milestones.yml after the framework update to 0.18.0 and the removal of publish-wiki.yml
|
||||||
|
- Language and domain: n/a
|
||||||
|
- Language reviewer: none
|
||||||
|
- Mode: autonomous, not independent (the reviewer is `AI as stand-in for S02`)
|
||||||
|
|
||||||
|
## Checklist Results
|
||||||
|
|
||||||
|
| # | Criterion | Status | Evidence/Notes |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| 1 | The file meets the YAML checklist ([QC-YML-001]) | Pending | `yamllint` is not installed on the stand-in's machine, so the YAML checklist QC-YML-001 was not run; the files parse (actionlint reads them) and use 2-space indentation. |
|
||||||
|
| 2 | The file is in `.gitea/workflows/` or `.github/workflows/` with the extension `.yml` or `.yaml`, and the same workflow does not exist in both directories | Pass | `sync-milestones.yml` is in `.gitea/workflows/` with the extension `.yml` and not in `.github/workflows/`. `publish-wiki.yml` was removed (see the verdict). |
|
||||||
|
| 3 | The file declares `name`, `on` and `jobs`; `on` lists explicit events and, where it matters, `branches` or `paths` | Pass | The file declares `name`, `on` and `jobs`; `on` lists `push` on `main` with `paths`, and `workflow_dispatch`. |
|
||||||
|
| 4 | A header comment states the purpose, the triggers, the inputs, the secrets it needs, what it changes outside the repository, and the decision or milestone it implements | Pass | The header states the purpose, triggers, secrets, what changes outside the repository and the installation steps (from the framework template); the decision is MIL-008 task 5. The added step has its own comment. |
|
||||||
|
| 5 | Every job and step has a descriptive `name`, unique within its job | Pass | Every step has a descriptive name. |
|
||||||
|
| 6 | The file passes `actionlint` (or the project's workflow validation test) and the tool version is stated | Pass | `actionlint` 1.7.12 reports no finding (exit code 0). |
|
||||||
|
| 7 | Every job declares `permissions` explicitly with the least access that works (`contents: read` or none by default); write access only on the job that needs it | Pass | The job sets `contents: read`. |
|
||||||
|
| 8 | Every action used is pinned to a full commit SHA or an exact release tag, never to a branch; a moving major tag (`@v1`) is accepted only for an action published by the same organisation under a stated release policy | Pass | `actions/checkout@v4.2.2` is an exact release tag. |
|
||||||
|
| 9 | No secret is written in the file; a secret is read as `secrets.NAME`, passed to a step through `env:`, never placed on a command line or echoed | Pass | The file reads `secrets.TOKEN_FOR_GITEA_ISSUES` only; no secret value is in the repository. The token reaches git through `GIT_CONFIG_*` environment variables, never a command line. |
|
||||||
|
| 10 | Untrusted text (`inputs.*`, event fields such as a title, branch name or label, step outputs derived from them) is never interpolated into a `run:` script; it is passed through `env:` and used as a quoted variable | Pass | No `run:` block interpolates `inputs.*` or event text; `DRY_RUN` is passed through `env:`. |
|
||||||
|
| 11 | A trigger that gives a run secrets or a write token on code from a fork or an untrusted branch (`pull_request_target`, `workflow_run`) does not check out or execute that code | Pass | The workflow does not use `pull_request_target` or `workflow_run`. |
|
||||||
|
| 12 | A workflow that changes state outside the repository (release, tag, publish, sync, deploy) is started by hand or by a protected branch, and a manual run defaults to a dry run with an explicit input to apply | Pass | It runs on a push to `main` or by hand; the manual run defaults to a dry run. |
|
||||||
|
| 13 | The token the workflow uses has only the scope the job needs, and where the host's built-in token is enough it is used instead of a personal token | Pending | The scope of the token is set by S01; the dry run on 2026-10-28 got HTTP 403 on the framework repository, so the token lacks read access to it. |
|
||||||
|
| 14 | Every job sets `runs-on` to an explicit label and `timeout-minutes` | Pass | The job sets `runs-on: ubuntu-latest` and `timeout-minutes: 15`. |
|
||||||
|
| 15 | `concurrency` is set where two runs would conflict: a check cancels the older run (`cancel-in-progress: true`); a publishing job queues (`cancel-in-progress: false`) | Pass | `concurrency` is set with `cancel-in-progress: false`. |
|
||||||
|
| 16 | Triggers are filtered (`branches`, `paths`, `types`) so the workflow runs only for the changes it concerns | Pass | The triggers are filtered by `branches: [main]` and `paths`. |
|
||||||
|
| 17 | Tools and dependencies are installed at pinned versions; a version is a workflow input with a default or a value in one place | Pass | The workflow installs nothing itself; `curl` and `jq` are checked by the framework script. |
|
||||||
|
| 18 | A dependency cache is used where the install is slow enough to matter | N-A | No dependency is installed that a cache would speed up. |
|
||||||
|
| 19 | A failing step names the tool, the file and the reason in its log (annotation or `::error::` line) | Pending | Not verified: the log messages come from the framework script and the reusable workflow, which the stand-in did not run. |
|
||||||
|
| 20 | A `run:` block is within the limit on embedded program text of criterion 7 of [QC-YML-001]; a longer script is a file (`tools/`, or a shared repository fetched at a pinned ref) that the step calls with one command, and the workflow passes its settings through `env:` | Pass | Each `run:` block is one command; the logic is in `framework/scripts/ci-publish-milestones.sh`. |
|
||||||
|
| 21 | Logic used by more than one workflow or repository is a reusable workflow (`workflow_call`) or a composite action; each input has a `description`, a `type` and a `default` where one is sensible | Pass | The workflow calls one framework script; the input of `workflow_dispatch` has a description, type and default. |
|
||||||
|
| 22 | Every workflow feature used is verified on the instance that runs it, and the host and version are recorded; a feature the target hosts differ on is noted in the header | Pending | A dry run on the instance (2026-10-28, run 3034, branch `fix-sync-milestones-submodule`) passed the HTTPS rewrite and then failed with 403 on the framework repository, so the feature is not yet verified end to end. |
|
||||||
|
| 23 | A reusable workflow states, in its header, how a caller pins it and the script it fetches, so the workflow and its script are the same release | N-A | The file is not a reusable workflow. |
|
||||||
|
| 24 | A static test of the repository's workflows exists and runs on every pull request: valid YAML, required keys, explicit permissions and runner, no inline script above the limit | N-A | No static test of the workflows exists in this project; the checks are `actionlint` on request. |
|
||||||
|
|
||||||
|
## Overall Verdict
|
||||||
|
|
||||||
|
Go-with-conditions - the milestone workflow is the framework template (0.18.0) plus one step that fetches the framework submodule over HTTPS, and it passes `actionlint`. `publish-wiki.yml` is removed because the framework retired the caller: the instance publishes `docs/wiki/` with its own scoped workflow (RC-022 reviewed the old caller). Mandatory criteria 1 (`yamllint` was not run) and 22 (feature checked on the instance) are Pending: the token lacks read access to the framework repository. The review is not independent: the AI wrote and reviewed it as stand-in for S02, and S01 can challenge it in the end-of-run summary.
|
||||||
|
|
||||||
|
## Action Items
|
||||||
|
|
||||||
|
| Action | Owner | Due |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| Give the token `TOKEN_FOR_GITEA_ISSUES` read access to the repository TirSystem/SQA-QC-Framework, create the secret in the organization and run the workflow once by hand with dry_run on | S01 | before the next merge to main |
|
||||||
|
| Run `yamllint` on `.gitea/workflows/` | S01 | when convenient |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
[MIL-008]: ../../milestones/mil-008-documentation.md
|
||||||
|
[QC-WF-001]: ../../../framework/qc/code/qc-workflow.md
|
||||||
|
[2cfcd02]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/049-snack-and-lift/commit/2cfcd0258897aeb90cea48baf59a8af258df19dd
|
||||||
@@ -44,7 +44,7 @@ Tracks backward and forward links between artifact instances so that the Busines
|
|||||||
| Source and tests of [MIL-005] | Python source code | - | - | [MIL-005], [ADR-0002] | - | RC-019 (Go-with-conditions) |
|
| Source and tests of [MIL-005] | Python source code | - | - | [MIL-005], [ADR-0002] | - | RC-019 (Go-with-conditions) |
|
||||||
| Source and tests of [MIL-006] | Python source code | - | - | [MIL-006], [ADR-0002] | - | RC-020 (Go-with-conditions) |
|
| Source and tests of [MIL-006] | Python source code | - | - | [MIL-006], [ADR-0002] | - | RC-020 (Go-with-conditions) |
|
||||||
| Source and tests of [MIL-007] | Python source code | - | - | [MIL-007], [ADR-0002] | - | RC-021 (Go-with-conditions) |
|
| Source and tests of [MIL-007] | Python source code | - | - | [MIL-007], [ADR-0002] | - | RC-021 (Go-with-conditions) |
|
||||||
| Workflows and wiki of [MIL-008] | Workflow files, wiki pages | - | - | [MIL-008] | - | RC-022 (Go-with-conditions) |
|
| Workflows and wiki of [MIL-008] | Workflow files, wiki pages | - | - | [MIL-008] | - | RC-022, RC-027 (Go-with-conditions) |
|
||||||
|
|
||||||
## Concern Coverage
|
## Concern Coverage
|
||||||
|
|
||||||
|
|||||||