Fix the defects found by the live end-to-end run, add RC-017
- Close stdin for ssh, git, curl and the framework scripts, so a real ssh no longer swallows answers meant for later prompts. - Count LICENSE and LICENSE + README.md (what Gitea creates) as content the script made, so a partly created repository can be reused. - Document the observed token scopes (write:user for user-owned Gitea repositories) and the Gitea README.md in the README. - Correct criterion 2 of MIL-002 (new Proposed version row). - Record the run and the final security review as RC-017. - Tests: stdin regression, initial_only reuse, other files count as content, example config needs its address edited. Task: MIL-003#6 Task: MIL-002#1 Refs #20 Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -15,8 +15,12 @@ and owner (a user or an organization, separately on each host), shows a plan,
|
||||
and only creates anything after you pass `--apply` and answer yes.
|
||||
|
||||
> **Status.** The script is tested with stubbed host APIs and real git against
|
||||
> local repositories (see [Development](#development)). A first run against
|
||||
> real GitHub and Gitea repositories is still to be recorded.
|
||||
> local repositories (see [Development](#development)). A first end-to-end run
|
||||
> on real GitHub and Gitea repositories, with organization owners on both, has
|
||||
> passed (2026-10-05, review record RC-017). Creating a repository under your
|
||||
> own Gitea account needs the `write:user` token scope (see
|
||||
> [Token permissions](#token-permissions)); that path has not been completed
|
||||
> yet.
|
||||
|
||||
## Contents
|
||||
|
||||
@@ -63,7 +67,7 @@ are accepted, and anything else stops the run with a message that names the key
|
||||
and the line, never the value.
|
||||
|
||||
```bash
|
||||
cp config.env.example config.env # service addresses, not secret
|
||||
cp config.env.example config.env # service addresses, not secret: set GITEA_URL (and GITEA_API_URL)
|
||||
cp .env.example .env # credentials: keep private
|
||||
chmod 600 .env # Linux and macOS
|
||||
```
|
||||
@@ -195,7 +199,7 @@ repositories for the chosen owner and to push to the new one.
|
||||
| Create a private repository | classic token with the `repo` scope | GitHub REST documentation, "Create a repository" |
|
||||
| Create a public repository only | classic token with `public_repo` is enough | same |
|
||||
| Push from the Gitea mirror | covered by `repo` | |
|
||||
| Check that you belong to the organization owner | probably `read:org` | **Not confirmed**: the GitHub documentation names no scope for this call. If the script says you do not belong to an organization that you do belong to, add `read:org`. |
|
||||
| Check that you belong to the organization owner | worked with a classic token that has `repo` and `admin:org` | `read:org` alone was **not tested**: the GitHub documentation names no scope for this call. If the script says you do not belong to an organization that you do belong to, add `read:org`. |
|
||||
|
||||
- **Organization owners:** you must be an active member who is allowed to
|
||||
create repositories in the organization. Organizations that require SSO or
|
||||
@@ -211,9 +215,9 @@ repositories for the chosen owner and to push to the new one.
|
||||
| Need | Scope | Source |
|
||||
| --- | --- | --- |
|
||||
| Read the account the token belongs to | `read:user` | Gitea documentation |
|
||||
| Create repositories, manage the push mirror | `write:repository` | Gitea documentation |
|
||||
| Look up an organization and your permissions in it | `read:organization` | Gitea documentation |
|
||||
| Create a repository in an organization | probably `write:organization` as well | **Not confirmed**: expected from how the Gitea API groups organization calls; to be confirmed in the first end-to-end run. |
|
||||
| Create a repository **under your own account** | `write:user` | **Confirmed by a real server**: without it Gitea answers `required=[write:user]` |
|
||||
| Create a repository in an organization, manage its push mirror | `write:organization` and `write:repository` | worked with a token that has both, plus `read:user`; the minimum was not narrowed down |
|
||||
| Look up an organization and your permissions in it | covered by the scopes above | worked in the end-to-end run |
|
||||
|
||||
A missing scope shows up as an HTTP 403 with the server's own message. The
|
||||
script stops before it creates anything when a preflight check is refused.
|
||||
@@ -256,7 +260,7 @@ step, `2` a usage error.
|
||||
| A tool, a config key or a token is missing or invalid | stops before any request | fix it and run again |
|
||||
| A token is refused, an owner is unknown, a name is taken, the license is missing | stops in the preflight; nothing was created | fix the cause |
|
||||
| The host cannot be reached | stops with the host name | try again |
|
||||
| A repository already exists and is empty (Gitea: or holds only the license) | offers to reuse it (default no) | answer, or choose another name |
|
||||
| A repository already exists and is empty (Gitea: or holds only the license and the README Gitea adds) | offers to reuse it (default no) | answer, or choose another name |
|
||||
| A repository already has content | stops | choose another name or remove it |
|
||||
| A step fails after another succeeded | stops and prints what exists, what failed and how to continue | fix the cause and run the **same command again with `--apply`**: what was created is offered for reuse |
|
||||
| The mirror is refused (disabled, interval too short) | keeps the repositories and reports it | change `MIRROR_INTERVAL` or ask the Gitea administrator, then run again |
|
||||
@@ -285,17 +289,20 @@ web interface and the project directory by hand.
|
||||
this, and revoke it if the Gitea server is ever in doubt.
|
||||
- **`sync_on_commit` may be ignored.** When a push mirror is created through
|
||||
the API, some Gitea versions ignore `sync_on_commit` (upstream issue
|
||||
go-gitea/gitea#22990). The script reads the mirror back and warns if the
|
||||
setting was not applied; the mirror then syncs on its interval
|
||||
go-gitea/gitea#22990). On Gitea 1.27.3 it was applied: a branch pushed to
|
||||
Gitea reached GitHub within seconds. The script reads the mirror back and
|
||||
warns if the setting was not applied; the mirror then syncs on its interval
|
||||
(`MIRROR_INTERVAL`, default 10 minutes). The first sync is requested right
|
||||
after the mirror is created.
|
||||
- **The server decides the shortest interval** and whether push mirrors are
|
||||
allowed at all. A refused mirror stops the run with the server's message;
|
||||
the repositories created so far are kept.
|
||||
- **The license commit.** Gitea adds the license file when the repository is
|
||||
created with `auto_init`. The script sends no README, so the repository
|
||||
should hold only `LICENSE`; this is still to be confirmed against a real
|
||||
server.
|
||||
created with `auto_init`, and on the real server it also adds a generated
|
||||
`README.md`. Both are mirrored to GitHub and become the first commit of the
|
||||
local project. A Gitea repository that holds only these files counts as
|
||||
content this script created and is offered for reuse; a repository with
|
||||
anything else counts as having content and is refused.
|
||||
- **No rollback.** See [Error handling and recovery](#error-handling-and-recovery).
|
||||
- **Mirror direction is Gitea to GitHub only.** Push to Gitea; GitHub is a
|
||||
copy.
|
||||
|
||||
Reference in New Issue
Block a user