Gitea is the only remote (MIL-008) and version 0.3.1 #58

Merged
Tirsvad merged 7 commits from mil-008-gitea-only-remote into main 2026-10-08 05:45:00 +02:00
4 changed files with 36 additions and 24 deletions
Showing only changes of commit 79f6edeb38 - Show all commits
+8 -6
View File
@@ -5,7 +5,7 @@ RepoFoundry (`src/create-project.sh`) sets up a new project in one run:
- a **Gitea** repository (the source of truth), - a **Gitea** repository (the source of truth),
- optionally an empty **GitHub** repository that receives everything through a - optionally an empty **GitHub** repository that receives everything through a
**push mirror from Gitea to GitHub**, **push mirror from Gitea to GitHub**,
- and a **local project** with credential-free remotes and the - and a **local project** with one credential-free remote, `origin` (Gitea), and the
[SQA-QC-Framework](https://git.tirsystem.com/TirSystem/SQA-QC-Framework) [SQA-QC-Framework](https://git.tirsystem.com/TirSystem/SQA-QC-Framework)
added as a git submodule, with its skills, git hooks (and optionally the plan added as a git submodule, with its skills, git hooks (and optionally the plan
gate) and templates installed. gate) and templates installed.
@@ -266,9 +266,9 @@ Without `--apply` that is all that happens. With `--apply` the script asks
1. the GitHub repository (empty), if chosen; 1. the GitHub repository (empty), if chosen;
2. the Gitea repository (with the license that applies: `PROJECT_LICENSE`, or AGPL-3.0 for a public project with GitHub); 2. the Gitea repository (with the license that applies: `PROJECT_LICENSE`, or AGPL-3.0 for a public project with GitHub);
3. the push mirror Gitea -> GitHub, and a request for its first sync; 3. the push mirror Gitea -> GitHub, and a request for its first sync;
4. the local directory, `git init` on `main`, the `origin` remote (and `github` 4. the local directory, `git init` on `main`, the `origin` remote (the only
if chosen), and, if the Gitea repository holds the license commit, that remote: a push to it reaches GitHub through the mirror) and, if the Gitea
history; repository holds the license commit, that history;
5. the framework as the submodule `framework`; 5. the framework as the submodule `framework`;
6. the framework's skills and git hooks, and the plan gate if chosen; 6. the framework's skills and git hooks, and the plan gate if chosen;
7. `AGENTS.md` and `docs/artifact-registry.md` from the framework's templates. 7. `AGENTS.md` and `docs/artifact-registry.md` from the framework's templates.
@@ -379,8 +379,10 @@ script stops before it creates anything when a preflight check is refused.
- **No destructive commands.** The script never deletes a repository or a - **No destructive commands.** The script never deletes a repository or a
file and never uses a recursive delete; temporary files are removed one by file and never uses a recursive delete; temporary files are removed one by
one. one.
- **Credential-free remotes.** `origin` is `ssh://git@host:port/owner/name.git` - **Credential-free remote.** `origin` is `ssh://git@host:port/owner/name.git`
(or plain HTTPS when SSH is not used) and `github` is a plain HTTPS address. (or plain HTTPS when SSH is not used). There is no `github` remote: push to
`origin` and the mirror carries it to GitHub. A `github` remote made by an
earlier version is left alone; remove it with `git remote remove github`.
- **Redirects are not followed,** so a token is only ever sent to the host in - **Redirects are not followed,** so a token is only ever sent to the host in
the URL it was meant for. Unknown SSH host keys are refused. the URL it was meant for. Unknown SSH host keys are refused.
- **Framework scripts run on the new project only.** They are run with - **Framework scripts run on the new project only.** They are run with
+1 -5
View File
@@ -4,7 +4,7 @@
# #
# Part of create-project.sh: sourced by it, never run on its own. # Part of create-project.sh: sourced by it, never run on its own.
# #
# Provides: is_reused, repo_owner, repo_url, gitea_host, origin_protocol, origin_url, github_remote_url, framework_url # Provides: is_reused, repo_owner, repo_url, gitea_host, origin_protocol, origin_url, framework_url
# is_reused HOST: succeed if the existing repository on HOST will be reused. # is_reused HOST: succeed if the existing repository on HOST will be reused.
is_reused() { is_reused() {
@@ -54,10 +54,6 @@ origin_url() {
fi fi
} }
github_remote_url() {
printf '%s/%s/%s.git' "${CONFIG[GITHUB_WEB_URL]}" "${PROJECT[github_owner]}" "${PROJECT[name]}"
}
# framework_url: where the framework submodule comes from (always SSH). # framework_url: where the framework submodule comes from (always SSH).
framework_url() { framework_url() {
printf 'ssh://git@%s:%s/%s.git' "$(gitea_host)" "${CONFIG[GITEA_SSH_PORT]}" \ printf 'ssh://git@%s:%s/%s.git' "$(gitea_host)" "${CONFIG[GITEA_SSH_PORT]}" \
+4 -5
View File
@@ -71,8 +71,10 @@ checkout_gitea_history() {
fi fi
} }
# create_local_project: the directory, the git repository on main, the # create_local_project: the directory, the git repository on main, the origin
# remotes and, when a license applies, the license history. No commit is made. # remote and, when a license applies, the license history. No commit is made.
# Gitea is the only remote: a push to it reaches GitHub through the push
# mirror, so no github remote is added (and none that exists is removed).
create_local_project() { create_local_project() {
local label="Local project" dir="${PROJECT[directory]}" local label="Local project" dir="${PROJECT[directory]}"
begin_step "$label" begin_step "$label"
@@ -82,9 +84,6 @@ create_local_project() {
git_project "$dir" symbolic-ref HEAD "refs/heads/$DEFAULT_BRANCH" git_project "$dir" symbolic-ref HEAD "refs/heads/$DEFAULT_BRANCH"
fi fi
ensure_remote "$dir" origin "$(origin_url)" ensure_remote "$dir" origin "$(origin_url)"
if ((PROJECT[has_github])); then
ensure_remote "$dir" github "$(github_remote_url)"
fi
if [[ -n ${PROJECT[license]} ]]; then if [[ -n ${PROJECT[license]} ]]; then
checkout_gitea_history "$dir" checkout_gitea_history "$dir"
fi fi
+23 -8
View File
@@ -35,7 +35,7 @@ readonly SSH_FRAMEWORK_URL="ssh://git@git.example.test:10022/TirSystem/SQA-QC-Fr
# ----------------------------------------------------- directory and remotes # ----------------------------------------------------- directory and remotes
test_local_project_gets_credential_free_remotes_and_the_license_history() { test_local_project_gets_the_origin_remote_only_and_the_license_history() {
setup_hosts setup_hosts
local dir="$WORK/project" local dir="$WORK/project"
local_answers "$dir" y n local_answers "$dir" y n
@@ -44,7 +44,9 @@ test_local_project_gets_credential_free_remotes_and_the_license_history() {
assert_file_exists "directory created" "$dir/.git" assert_file_exists "directory created" "$dir/.git"
assert_eq "branch is main" "main" "$(project_git "$dir" symbolic-ref --short HEAD)" assert_eq "branch is main" "main" "$(project_git "$dir" symbolic-ref --short HEAD)"
assert_eq "origin over SSH, no credential" "ssh://git@git.example.test:10022/TirSystem/my-app.git" "$(project_git "$dir" config --get remote.origin.url)" assert_eq "origin over SSH, no credential" "ssh://git@git.example.test:10022/TirSystem/my-app.git" "$(project_git "$dir" config --get remote.origin.url)"
assert_eq "github remote over HTTPS, no credential" "https://github.com/acme-org/my-app.git" "$(project_git "$dir" config --get remote.github.url)" assert_eq "origin is the only remote, also with GitHub" "origin" "$(project_git "$dir" remote)"
assert_eq "no github remote" "" "$(project_git "$dir" config --get remote.github.url || true)"
assert_not_contains "no GitHub address in the git config" "$(cat "$dir/.git/config")" "github.com"
assert_eq "the license commit is the whole history" "1" "$(project_git "$dir" rev-list --count HEAD)" assert_eq "the license commit is the whole history" "1" "$(project_git "$dir" rev-list --count HEAD)"
assert_eq "it is the Gitea commit" "Initial commit" "$(project_git "$dir" log -1 --format=%s)" assert_eq "it is the Gitea commit" "Initial commit" "$(project_git "$dir" log -1 --format=%s)"
assert_file_exists "LICENSE from Gitea" "$dir/LICENSE" assert_file_exists "LICENSE from Gitea" "$dir/LICENSE"
@@ -53,7 +55,7 @@ test_local_project_gets_credential_free_remotes_and_the_license_history() {
assert_contains "reported" "$OUT" "Local project : created $dir (origin over SSH)" assert_contains "reported" "$OUT" "Local project : created $dir (origin over SSH)"
} }
test_gitea_only_project_has_no_github_remote_and_no_commit() { test_gitea_only_project_has_the_origin_remote_only_and_no_commit() {
setup_hosts setup_hosts
printf 'GITEA_TOKEN=%s\n' "$FAKE_GITEA_TOKEN" >"$WORK/.env" printf 'GITEA_TOKEN=%s\n' "$FAKE_GITEA_TOKEN" >"$WORK/.env"
local dir="$WORK/project" local dir="$WORK/project"
@@ -61,7 +63,7 @@ test_gitea_only_project_has_no_github_remote_and_no_commit() {
run_apply "$LOCAL_ANSWERS"$'y\n' run_apply "$LOCAL_ANSWERS"$'y\n'
assert_status "apply" 0 "$STATUS" assert_status "apply" 0 "$STATUS"
assert_eq "origin" "ssh://git@git.example.test:10022/TirSystem/my-app.git" "$(project_git "$dir" config --get remote.origin.url)" assert_eq "origin" "ssh://git@git.example.test:10022/TirSystem/my-app.git" "$(project_git "$dir" config --get remote.origin.url)"
assert_eq "no github remote" "" "$(project_git "$dir" config --get remote.github.url || true)" assert_eq "origin is the only remote" "origin" "$(project_git "$dir" remote)"
assert_file_missing "no license file" "$dir/LICENSE" assert_file_missing "no license file" "$dir/LICENSE"
assert_eq "no commit was made" "0" "$(project_git "$dir" rev-list --all --count)" assert_eq "no commit was made" "0" "$(project_git "$dir" rev-list --all --count)"
assert_eq "no token in any file" "" "$(files_with_secret "$dir")" assert_eq "no token in any file" "" "$(files_with_secret "$dir")"
@@ -109,6 +111,20 @@ test_a_file_that_would_be_overwritten_by_the_license_history_is_kept() {
assert_contains "later steps not attempted" "$OUT" "Framework : not attempted" assert_contains "later steps not attempted" "$OUT" "Framework : not attempted"
} }
test_a_github_remote_from_an_earlier_version_is_left_alone() {
setup_hosts
local dir="$WORK/project"
mkdir -p "$dir"
project_git "$dir" init -q
project_git "$dir" remote add github https://github.com/acme-org/my-app.git
local_answers "$dir" y n
run_apply "$LOCAL_ANSWERS"$'y\ny\n'
assert_status "apply" 0 "$STATUS"
assert_eq "the github remote is kept as it was" "https://github.com/acme-org/my-app.git" "$(project_git "$dir" config --get remote.github.url)"
assert_eq "origin was added beside it" "ssh://git@git.example.test:10022/TirSystem/my-app.git" "$(project_git "$dir" config --get remote.origin.url)"
assert_eq "no other remote" $'github\norigin' "$(project_git "$dir" remote | sort)"
}
test_a_remote_with_another_address_is_never_replaced() { test_a_remote_with_another_address_is_never_replaced() {
setup_hosts setup_hosts
local dir="$WORK/project" local dir="$WORK/project"
@@ -379,16 +395,15 @@ test_a_project_path_that_is_a_file_is_refused_in_the_preflight() {
test_remote_addresses_are_built_from_the_configuration() { test_remote_addresses_are_built_from_the_configuration() {
run_lib "" 'CONFIG[GITEA_URL]=https://git.example.test/sub run_lib "" 'CONFIG[GITEA_URL]=https://git.example.test/sub
CONFIG[GITEA_SSH_PORT]=2222 CONFIG[FRAMEWORK_REPO]=Org/Fw CONFIG[GITHUB_WEB_URL]=https://github.com CONFIG[GITEA_SSH_PORT]=2222 CONFIG[FRAMEWORK_REPO]=Org/Fw
PROJECT[gitea_owner]=TirSystem PROJECT[github_owner]=acme PROJECT[name]=my-app PROJECT[gitea_owner]=TirSystem PROJECT[name]=my-app
STATE[is_ssh_ok]=1 STATE[is_ssh_ok]=1
origin_url; echo origin_url; echo
STATE[is_ssh_ok]=0 STATE[is_ssh_ok]=0
origin_url; echo origin_url; echo
github_remote_url; echo
framework_url; echo framework_url; echo
gitea_host; echo' gitea_host; echo'
assert_eq "addresses" $'ssh://git@git.example.test:2222/TirSystem/my-app.git\nhttps://git.example.test/sub/TirSystem/my-app.git\nhttps://github.com/acme/my-app.git\nssh://git@git.example.test:2222/Org/Fw.git\ngit.example.test' "$OUT" assert_eq "addresses" $'ssh://git@git.example.test:2222/TirSystem/my-app.git\nhttps://git.example.test/sub/TirSystem/my-app.git\nssh://git@git.example.test:2222/Org/Fw.git\ngit.example.test' "$OUT"
} }
test_the_https_fetch_hands_the_token_over_through_the_environment_only() { test_the_https_fetch_hands_the_token_over_through_the_environment_only() {