40 Commits

Author SHA1 Message Date
benvin 1b2e62701d Merge pull request 'Drop ci/woodpecker/pr/test status check from container-base and container-gobuilder' (#104) from container-protection-test-context into main
ci/woodpecker/push/apply Pipeline was successful
Reviewed-on: #104
2026-09-27 20:22:45 +10:00
unkin-agent 707e01efcd Drop ci/woodpecker/pr/test status check from container-base and container-gobuilder
ci/woodpecker/pr/plan Pipeline was successful
ci/woodpecker/pr/pre-commit Pipeline was successful
Neither repo has a test workflow, so the required ci/woodpecker/pr/test
context never reports and every PR stays permanently unmergeable.

- Remove ci/woodpecker/pr/test from status_check_contexts on both repos
- Keep ci/woodpecker/pr/build and ci/woodpecker/pr/pre-commit
2026-09-27 20:14:06 +10:00
benvin 9e94938031 Merge pull request 'Drop obsolete vector-test status check from argocd-apps' (#103) from benvin/argocd-apps-drop-vector-test into main
ci/woodpecker/push/apply Pipeline was successful
Reviewed-on: #103
2026-09-27 18:27:48 +10:00
unkin-agent 922b256af7 Retrigger CI
ci/woodpecker/pr/plan Pipeline was successful
ci/woodpecker/pr/pre-commit Pipeline was successful
2026-09-27 18:11:18 +10:00
unkin-agent 1584c2169d Drop obsolete vector-test status check from argocd-apps
ci/woodpecker/pr/plan Pipeline was successful
ci/woodpecker/pr/pre-commit Pipeline failed
The vector-test pipeline is being removed from argocd-apps, so the
context will never report again and would block every merge.
2026-09-27 18:08:36 +10:00
benvin f6536db7bd Merge pull request 'Add container-base and container-gobuilder image repos' (#102) from benvin/container-image-repos into main
ci/woodpecker/push/apply Pipeline was successful
Reviewed-on: #102
2026-09-27 17:29:30 +10:00
unkin-agent 14aa732e41 Rename repos to container-base and container-gobuilder
ci/woodpecker/pr/plan Pipeline was successful
ci/woodpecker/pr/pre-commit Pipeline was successful
2026-09-27 17:28:03 +10:00
unkin-agent 2827e749dd Rename almalinux9-base repo to almalinux9
ci/woodpecker/pr/plan Pipeline was successful
ci/woodpecker/pr/pre-commit Pipeline was successful
2026-09-27 17:24:00 +10:00
unkin-agent 19bb5da00c Add almalinux9-base and gobuilder repos
ci/woodpecker/pr/plan Pipeline was successful
ci/woodpecker/pr/pre-commit Pipeline was successful
Split the first two container images out of the packer-images monorepo into
one repo per image.
2026-09-27 17:14:12 +10:00
benvin 41168df5fd Merge pull request 'Declare go-cache-plugin build repo' (#101) from benvin/go-cache-plugin-repo into main
ci/woodpecker/push/apply Pipeline was successful
Reviewed-on: #101
2026-09-26 21:04:25 +10:00
unkin-agent 98f80d58f8 Declare go-cache-plugin build repo
ci/woodpecker/pr/plan Pipeline was successful
ci/woodpecker/pr/pre-commit Pipeline was successful
Adds the Gitea repo that builds and releases the tailscale go-cache-plugin
GOCACHEPROG binary for the estate.
2026-09-26 19:06:06 +10:00
benvin f4e7dbd1ff Merge pull request 'Protect main on the jellyfin-plugin-sso fork' (#100) from benvin/jellyfin-plugin-sso-protection into main
ci/woodpecker/push/apply Pipeline was successful
Reviewed-on: #100
2026-09-19 22:29:11 +10:00
unkin-agent ac5604ec92 Protect main on the jellyfin-plugin-sso fork
ci/woodpecker/pr/plan Pipeline was successful
ci/woodpecker/pr/pre-commit Pipeline was successful
Require the PR pipeline and Owners merge approval on main, keeping owner push for upstream syncs.
2026-09-19 22:28:09 +10:00
benvin c26a432769 Merge pull request 'Fork the Jellyfin SSO plugin mirror into unkin' (#99) from benvin/fork-jellyfin-plugin-sso into main
ci/woodpecker/push/apply Pipeline was successful
Reviewed-on: #99
2026-09-19 17:17:31 +10:00
unkin-agent 289ebc84d6 Fork the Jellyfin SSO plugin mirror into unkin
ci/woodpecker/pr/plan Pipeline was successful
ci/woodpecker/pr/pre-commit Pipeline was successful
Add config/git.unkin.net/unkin/repository/jellyfin-plugin-sso.yaml forking mirrors/jellyfin-plugin-sso.
2026-09-19 17:11:06 +10:00
benvin 25ef56fc30 Merge pull request 'Use plain git migration service for the SSO plugin mirror' (#98) from benvin/mirror-sso-plain-git into main
ci/woodpecker/push/apply Pipeline was successful
Reviewed-on: #98
2026-09-19 17:03:48 +10:00
unkin-agent 112f7c8042 Use plain git migration service for the SSO plugin mirror
ci/woodpecker/pr/plan Pipeline was successful
ci/woodpecker/pr/pre-commit Pipeline was successful
2026-09-19 16:47:41 +10:00
benvin b126fffe17 Merge pull request 'Mirror the upstream Jellyfin SSO plugin' (#97) from benvin/mirror-jellyfin-plugin-sso into main
ci/woodpecker/push/apply Pipeline failed
Reviewed-on: #97
2026-09-19 16:36:09 +10:00
unkin-agent 8207d8cc8a Mirror the upstream Jellyfin SSO plugin
ci/woodpecker/pr/plan Pipeline was successful
ci/woodpecker/pr/pre-commit Pipeline was successful
Add a pull mirror of github.com/9p4/jellyfin-plugin-sso into the mirrors
organisation, syncing every 8h with issues, pull requests and release
migration disabled.
2026-09-19 16:18:55 +10:00
benvin 55151a8796 Merge pull request 'Add declarative fork support to repository config' (#96) from benvin/gitea-fork-from into main
ci/woodpecker/push/apply Pipeline was successful
Reviewed-on: #96
2026-09-19 16:13:06 +10:00
unkin-agent 8bc04e2c7d Reject fork_from alongside unsupported repository keys
ci/woodpecker/pr/plan Pipeline was successful
ci/woodpecker/pr/pre-commit Pipeline was successful
gitea_fork can only express the source repo and owning organisation, so any
other setting in a fork's yaml is silently dropped.

- validate fork_from entries carry no other repository attributes, naming the
  offending config key and attributes
- note that gitea_fork has no archive_on_destroy
2026-09-19 16:03:44 +10:00
benvin 2cb056cbac Merge pull request 'Add Gitea pull-mirror support and a mirrors organisation' (#95) from benvin/gitea-mirror-repos into main
ci/woodpecker/push/apply Pipeline was successful
Reviewed-on: #95
2026-09-19 15:58:01 +10:00
unkin-agent 9ab540719e Add fork_from to repository config
ci/woodpecker/pr/plan Pipeline was successful
ci/woodpecker/pr/pre-commit Pipeline was successful
Express a fork as an optional fork_from key on the repository yaml, so a
forked repo is declared the same way as any other repo.

- add fork_from "<owner>/<repo>" to the repository module and object type
- create gitea_fork instead of gitea_repository when fork_from is set
- validate the source repo name matches the config file name, since a fork
  inherits the source name
- move gitea_repository.this to index 0 for the count refactor
- index existing repository import targets to match
2026-09-19 15:55:12 +10:00
unkin-agent 66823a939a Add pull-mirror support and a mirrors organisation
ci/woodpecker/pr/plan Pipeline was successful
ci/woodpecker/pr/pre-commit Pipeline was successful
Expose the non-secret gitea_repository mirror/migration attributes through
the repository module and add the mirrors org for public upstream mirrors.
2026-09-19 15:47:32 +10:00
benvin 26e7723251 Merge pull request 'Add sshsignhost repository and scope certmanager to X.509' (#94) from benvin/puppet-vault-signers-repo into main
ci/woodpecker/push/apply Pipeline was successful
Reviewed-on: #94
2026-09-19 10:25:37 +10:00
unkin-agent 1a43ed6a47 repository: add sshsignhost and scope certmanager to X.509
ci/woodpecker/pr/plan Pipeline was successful
ci/woodpecker/pr/pre-commit Pipeline was successful
Puppet calls /usr/local/bin/certmanager and /usr/local/bin/sshsignhost at
hardcoded paths, so each tool needs a repo named for its binary.
2026-09-19 10:21:14 +10:00
unkin-agent de2b8acf8a Add puppet-vault-signers repository
ci/woodpecker/pr/plan Pipeline was successful
ci/woodpecker/pr/pre-commit Pipeline was successful
Host the Go rewrites of the certmanager and sshsignhost Vault signing
helpers.

- Add config/git.unkin.net/unkin/repository/puppet-vault-signers.yaml
- Protect main with Owners-only merge and the standard woodpecker checks
2026-09-14 23:30:11 +10:00
benvin 93b47c0941 Merge pull request 'Add puppet-catalog-tools repository' (#93) from benvin/puppet-catalog-tools-repo into main
ci/woodpecker/push/apply Pipeline was successful
Reviewed-on: #93
2026-09-12 15:35:20 +10:00
unkin-agent 73cc875373 Add puppet-catalog-tools repository
ci/woodpecker/pr/plan Pipeline was successful
ci/woodpecker/pr/pre-commit Pipeline was successful
2026-09-12 15:32:55 +10:00
benvin 4424abad17 Merge pull request 'Make arti-pack repo description vendor-neutral' (#92) from benvin/arti-pack-neutral-description into main
ci/woodpecker/push/apply Pipeline was successful
Reviewed-on: #92
2026-09-09 23:12:29 +10:00
unkin-agent 96ca0630d5 Make arti-pack repo description vendor-neutral
ci/woodpecker/pr/plan Pipeline was successful
ci/woodpecker/pr/pre-commit Pipeline was successful
2026-09-09 22:39:34 +10:00
benvin deaa0f003d Merge pull request 'Add arti-pack repository' (#91) from benvin/arti-pack-repo into main
ci/woodpecker/push/apply Pipeline was successful
Reviewed-on: #91
2026-09-08 22:59:29 +10:00
unkin-agent d0c1f7f6bd Add arti-pack repository
ci/woodpecker/pr/pre-commit Pipeline was successful
ci/woodpecker/pr/plan Pipeline was successful
2026-09-07 23:49:12 +10:00
benvin 9230ece23a Merge pull request 'Add vimpack repository' (#90) from benvin/vimpack-repo into main
ci/woodpecker/push/apply Pipeline was successful
Reviewed-on: #90
2026-09-05 13:06:55 +10:00
unkin-agent 62b8ab4e9c Add vimpack repository
ci/woodpecker/pr/plan Pipeline was successful
ci/woodpecker/pr/pre-commit Pipeline was successful
2026-09-05 11:13:50 +10:00
benvin 7b699c36b7 Merge pull request 'Add golib repository' (#89) from benvin/golib-repo into main
ci/woodpecker/push/apply Pipeline was successful
Reviewed-on: #89
2026-08-31 06:58:05 +10:00
unkin-agent c731f89dd4 Add golib repository
ci/woodpecker/pr/plan Pipeline was successful
ci/woodpecker/pr/pre-commit Pipeline was successful
Shared Go library for estate services, starting with a postgres pool and
migrations module.
2026-08-31 04:15:59 +10:00
benvin 2e9a5fb8d4 Merge pull request 'Add repospawner machine user scoped to terraform-git' (#88) from benvin/repospawner-user into main
ci/woodpecker/push/apply Pipeline was successful
Reviewed-on: #88
2026-08-30 09:34:47 +10:00
unkin-agent dd26c861fc repospawner: mark the account restricted
ci/woodpecker/pr/plan Pipeline was successful
ci/woodpecker/pr/pre-commit Pipeline was successful
Defense in depth for the repo-creation bot: a restricted Gitea account can
only see repositories and organisations it is explicitly added to, so a
leaked repospawner token cannot enumerate or read the rest of the estate.
The repospawner team grant on terraform-git already covers everything the
bot does, so nothing it needs is lost.
2026-08-30 00:55:01 +10:00
unkin-agent 4b30ba0cfd Add repospawner machine user scoped to terraform-git
ci/woodpecker/pr/plan Pipeline was successful
ci/woodpecker/pr/pre-commit Pipeline was successful
repospawner opens repo-creation PRs against terraform-git and needs no other
access, so give it its own identity and a per-repo team instead of adding it to
the org-wide agents team.

- add config/git.unkin.net/user/repospawner.yaml (limited visibility, not admin,
  no org/repo creation), mirroring the unkin-agent bot posture
- add config/git.unkin.net/unkin/team/repospawner.yaml granting write on the
  terraform-git repository only (include_all_repositories false)
2026-08-30 00:48:10 +10:00
21 changed files with 345 additions and 37 deletions
+3
View File
@@ -0,0 +1,3 @@
description: "Pull mirrors of upstream repositories"
visibility: public
repo_admin_change_team_access: true
@@ -0,0 +1,11 @@
description: "Pull mirror of github.com/9p4/jellyfin-plugin-sso, the Jellyfin SSO/OIDC authentication plugin"
private: false
has_issues: false
has_pull_requests: false
mirror: true
migration_clone_address: "https://github.com/9p4/jellyfin-plugin-sso"
migration_service: "git"
migration_mirror_interval: "8h0m0s"
migration_issue_labels: false
migration_milestones: false
migration_releases: false
@@ -10,6 +10,5 @@ branch_protection:
status_check_contexts:
- "ci/woodpecker/pr/pre-commit"
- "ci/woodpecker/pr/kubeconform"
- "ci/woodpecker/pr/vector-test"
approval_whitelist_users:
- "benvin"
@@ -0,0 +1,14 @@
description: "Neovim plugin manager that installs plugins from tagged archives in an HTTP artifact repository into nvim's native package path"
private: false
default_branch: "main"
default_delete_branch_after_merge: true
default_merge_style: "squash"
branch_protection:
- rule_name: "main"
merge_whitelist_teams:
- "Owners"
enable_push: false
status_check_contexts:
- "ci/woodpecker/pr/test"
- "ci/woodpecker/pr/lint"
- "ci/woodpecker/pr/pre-commit"
@@ -1,4 +1,4 @@
description: "Vault PKI certificate issuance and SSH host key signing tool for Puppet-managed infrastructure"
description: "Vault-backed X.509 certificate signing helper for Puppet"
private: false
default_branch: "master"
default_delete_branch_after_merge: true
@@ -0,0 +1,15 @@
description: "Base container images for the estate, carrying internal CA trust and dnf/repo configuration, built as a matrix across the supported distros."
private: false
default_branch: "main"
default_delete_branch_after_merge: true
default_merge_style: "squash"
branch_protection:
- rule_name: "main"
merge_whitelist_teams:
- "Owners"
enable_push: false
status_check_contexts:
- "ci/woodpecker/pr/build"
- "ci/woodpecker/pr/pre-commit"
approval_whitelist_users:
- "benvin"
@@ -0,0 +1,15 @@
description: "Go toolchain builder container image, built on each supported container-base distro image, used by Woodpecker pipelines to compile Go projects."
private: false
default_branch: "main"
default_delete_branch_after_merge: true
default_merge_style: "squash"
branch_protection:
- rule_name: "main"
merge_whitelist_teams:
- "Owners"
enable_push: false
status_check_contexts:
- "ci/woodpecker/pr/build"
- "ci/woodpecker/pr/pre-commit"
approval_whitelist_users:
- "benvin"
@@ -0,0 +1,16 @@
description: "Build repo that compiles the tailscale/go-cache-plugin GOCACHEPROG S3 Go build cache from a pinned upstream module version and publishes static binaries as Gitea releases."
private: false
default_branch: "main"
default_delete_branch_after_merge: true
default_merge_style: "squash"
branch_protection:
- rule_name: "main"
merge_whitelist_teams:
- "Owners"
enable_push: false
status_check_contexts:
- "ci/woodpecker/pr/build"
- "ci/woodpecker/pr/test"
- "ci/woodpecker/pr/pre-commit"
approval_whitelist_users:
- "benvin"
@@ -0,0 +1,14 @@
description: "Shared Go library for estate services: postgres, http service kit, vault and gitea clients"
private: false
default_branch: "main"
default_delete_branch_after_merge: true
default_merge_style: "squash"
branch_protection:
- rule_name: "main"
merge_whitelist_teams:
- "Owners"
enable_push: false
status_check_contexts:
- "ci/woodpecker/pr/build"
- "ci/woodpecker/pr/test"
- "ci/woodpecker/pr/pre-commit"
@@ -0,0 +1,15 @@
fork_from: "mirrors/jellyfin-plugin-sso"
branch_protection:
- rule_name: "main"
merge_whitelist_teams:
- "Owners"
# Whitelist-push: the owner pushes main directly when syncing upstream;
# everyone else must open a PR.
enable_push: true
push_whitelist_users:
- "unkinben"
# PRs to main must pass the plugin build pipeline before merge.
status_check_contexts:
- "ci/woodpecker/pr/ci"
approval_whitelist_teams:
- "Owners"
@@ -0,0 +1,14 @@
description: "Go CLIs to diff Puppet catalogs between branches and map puppet-prod changes to affected hosts"
private: false
default_branch: "main"
default_delete_branch_after_merge: true
default_merge_style: "squash"
branch_protection:
- rule_name: "main"
merge_whitelist_teams:
- "Owners"
enable_push: false
status_check_contexts:
- "ci/woodpecker/pr/build"
- "ci/woodpecker/pr/test"
- "ci/woodpecker/pr/pre-commit"
@@ -0,0 +1,14 @@
description: "Vault-backed SSH host certificate signing helper for Puppet"
private: false
default_branch: "main"
default_delete_branch_after_merge: true
default_merge_style: "squash"
branch_protection:
- rule_name: "main"
merge_whitelist_teams:
- "Owners"
enable_push: false
status_check_contexts:
- "ci/woodpecker/pr/build"
- "ci/woodpecker/pr/test"
- "ci/woodpecker/pr/pre-commit"
@@ -0,0 +1,14 @@
description: "Neovim plugin manager installing plugins from tagged archives on artifactapi/Artifactory instead of git clones"
private: false
default_branch: "main"
default_delete_branch_after_merge: true
default_merge_style: "squash"
branch_protection:
- rule_name: "main"
merge_whitelist_teams:
- "Owners"
enable_push: false
status_check_contexts:
- "ci/woodpecker/pr/test"
- "ci/woodpecker/pr/lint"
- "ci/woodpecker/pr/pre-commit"
@@ -0,0 +1,16 @@
# Least-privilege access for the repospawner bot: Write on terraform-git only,
# which is the minimum Gitea permission that allows pushing a branch and opening
# a pull request. repospawner does its whole job here (repo-creation PRs), so it
# is kept out of the org-wide "agents" team (include_all_repositories: true).
#
# Merge stays reserved for Ben: branch protection on terraform-git's main sets a
# merge whitelist of the Owners team only. Keep this team out of every merge and
# approval whitelist.
description: "repospawner bot -- push branches + open PRs on terraform-git only"
permission: write
include_all_repositories: false
can_create_repos: false
repositories:
- terraform-git
members:
- repospawner
@@ -0,0 +1,22 @@
# Service identity for repospawner, which opens pull requests against this
# repository (terraform-git) to add new Gitea repositories on request. It is
# deliberately separate from unkin-agent so its access can stay scoped to the
# single repository it needs: the "repospawner" team (unkin/team/repospawner.yaml)
# grants Write on terraform-git and nothing else.
#
# Auth is via ephemeral API tokens minted by the vault-plugin-secrets-gitea
# engine -- no usable credential lives in this repo's state beyond the generated
# placeholder. Merge stays blocked by branch protection (merge whitelist =
# Owners only), so it can push branches and open PRs but never merge.
email: repospawner@unkin.net
full_name: "Repo Spawner"
description: "repospawner service identity -- opens repo-creation PRs against terraform-git"
# Conservative bot posture: not a site admin, cannot create orgs or repos,
# profile visible only to signed-in users.
visibility: limited
admin: false
# Restricted: account can only see repos/orgs it is explicitly added to -- the
# repospawner team grant on terraform-git is all it needs.
restricted: true
allow_create_organization: false
max_repo_creation: 0
+34 -34
View File
@@ -4,167 +4,167 @@ import {
}
import {
to = module.repository["git.unkin.net/unkin/puppet-prod"].gitea_repository.this
to = module.repository["git.unkin.net/unkin/puppet-prod"].gitea_repository.this[0]
id = "2"
}
import {
to = module.repository["git.unkin.net/unkin/puppet-r10k"].gitea_repository.this
to = module.repository["git.unkin.net/unkin/puppet-r10k"].gitea_repository.this[0]
id = "3"
}
import {
to = module.repository["git.unkin.net/unkin/rpmbuild-gonic"].gitea_repository.this
to = module.repository["git.unkin.net/unkin/rpmbuild-gonic"].gitea_repository.this[0]
id = "23"
}
import {
to = module.repository["git.unkin.net/unkin/docker-almalinux-base"].gitea_repository.this
to = module.repository["git.unkin.net/unkin/docker-almalinux-base"].gitea_repository.this[0]
id = "24"
}
import {
to = module.repository["git.unkin.net/unkin/rpmbuild-internal-ca-certificates"].gitea_repository.this
to = module.repository["git.unkin.net/unkin/rpmbuild-internal-ca-certificates"].gitea_repository.this[0]
id = "27"
}
import {
to = module.repository["git.unkin.net/unkin/rpmbuild-template"].gitea_repository.this
to = module.repository["git.unkin.net/unkin/rpmbuild-template"].gitea_repository.this[0]
id = "29"
}
import {
to = module.repository["git.unkin.net/unkin/rpmbuild-jellyfin-web"].gitea_repository.this
to = module.repository["git.unkin.net/unkin/rpmbuild-jellyfin-web"].gitea_repository.this[0]
id = "31"
}
import {
to = module.repository["git.unkin.net/unkin/rpmbuild-proxlb"].gitea_repository.this
to = module.repository["git.unkin.net/unkin/rpmbuild-proxlb"].gitea_repository.this[0]
id = "33"
}
import {
to = module.repository["git.unkin.net/unkin/docker-almalinux-buildrunner"].gitea_repository.this
to = module.repository["git.unkin.net/unkin/docker-almalinux-buildrunner"].gitea_repository.this[0]
id = "36"
}
import {
to = module.repository["git.unkin.net/unkin/docker-template"].gitea_repository.this
to = module.repository["git.unkin.net/unkin/docker-template"].gitea_repository.this[0]
id = "38"
}
import {
to = module.repository["git.unkin.net/unkin/terraform-vault"].gitea_repository.this
to = module.repository["git.unkin.net/unkin/terraform-vault"].gitea_repository.this[0]
id = "39"
}
import {
to = module.repository["git.unkin.net/unkin/docker-almalinux-jupyterinstance"].gitea_repository.this
to = module.repository["git.unkin.net/unkin/docker-almalinux-jupyterinstance"].gitea_repository.this[0]
id = "40"
}
import {
to = module.repository["git.unkin.net/unkin/rpmbuilder"].gitea_repository.this
to = module.repository["git.unkin.net/unkin/rpmbuilder"].gitea_repository.this[0]
id = "41"
}
import {
to = module.repository["git.unkin.net/unkin/docker-almalinux-runnerdnd"].gitea_repository.this
to = module.repository["git.unkin.net/unkin/docker-almalinux-runnerdnd"].gitea_repository.this[0]
id = "43"
}
import {
to = module.repository["git.unkin.net/unkin/initbuilder"].gitea_repository.this
to = module.repository["git.unkin.net/unkin/initbuilder"].gitea_repository.this[0]
id = "47"
}
import {
to = module.repository["git.unkin.net/unkin/puppetapi"].gitea_repository.this
to = module.repository["git.unkin.net/unkin/puppetapi"].gitea_repository.this[0]
id = "50"
}
import {
to = module.repository["git.unkin.net/unkin/terraform-nomad"].gitea_repository.this
to = module.repository["git.unkin.net/unkin/terraform-nomad"].gitea_repository.this[0]
id = "53"
}
import {
to = module.repository["git.unkin.net/unkin/packer-images"].gitea_repository.this
to = module.repository["git.unkin.net/unkin/packer-images"].gitea_repository.this[0]
id = "59"
}
import {
to = module.repository["git.unkin.net/unkin/app-sudaporn-research-normalised"].gitea_repository.this
to = module.repository["git.unkin.net/unkin/app-sudaporn-research-normalised"].gitea_repository.this[0]
id = "60"
}
import {
to = module.repository["git.unkin.net/unkin/app-sudaporn-research-individual"].gitea_repository.this
to = module.repository["git.unkin.net/unkin/app-sudaporn-research-individual"].gitea_repository.this[0]
id = "63"
}
import {
to = module.repository["git.unkin.net/unkin/terraform-incus"].gitea_repository.this
to = module.repository["git.unkin.net/unkin/terraform-incus"].gitea_repository.this[0]
id = "66"
}
import {
to = module.repository["git.unkin.net/unkin/artifactapi"].gitea_repository.this
to = module.repository["git.unkin.net/unkin/artifactapi"].gitea_repository.this[0]
id = "67"
}
import {
to = module.repository["git.unkin.net/unkin/argocd-apps"].gitea_repository.this
to = module.repository["git.unkin.net/unkin/argocd-apps"].gitea_repository.this[0]
id = "100"
}
import {
to = module.repository["git.unkin.net/unkin/certmanager"].gitea_repository.this
to = module.repository["git.unkin.net/unkin/certmanager"].gitea_repository.this[0]
id = "101"
}
import {
to = module.repository["git.unkin.net/unkin/node-lookup"].gitea_repository.this
to = module.repository["git.unkin.net/unkin/node-lookup"].gitea_repository.this[0]
id = "102"
}
import {
to = module.repository["git.unkin.net/unkin/container-devcompute"].gitea_repository.this
to = module.repository["git.unkin.net/unkin/container-devcompute"].gitea_repository.this[0]
id = "135"
}
import {
to = module.repository["git.unkin.net/unkin/streamstack"].gitea_repository.this
to = module.repository["git.unkin.net/unkin/streamstack"].gitea_repository.this[0]
id = "136"
}
import {
to = module.repository["git.unkin.net/unkin/terraform-provider-artifactapi"].gitea_repository.this
to = module.repository["git.unkin.net/unkin/terraform-provider-artifactapi"].gitea_repository.this[0]
id = "137"
}
import {
to = module.repository["git.unkin.net/unkin/forgebot"].gitea_repository.this
to = module.repository["git.unkin.net/unkin/forgebot"].gitea_repository.this[0]
id = "139"
}
import {
to = module.repository["git.unkin.net/unkin/forgebot-skills"].gitea_repository.this
to = module.repository["git.unkin.net/unkin/forgebot-skills"].gitea_repository.this[0]
id = "140"
}
import {
to = module.repository["git.unkin.net/unkin/container-agent-base"].gitea_repository.this
to = module.repository["git.unkin.net/unkin/container-agent-base"].gitea_repository.this[0]
id = "141"
}
import {
to = module.repository["git.unkin.net/unkin/container-agent-dev"].gitea_repository.this
to = module.repository["git.unkin.net/unkin/container-agent-dev"].gitea_repository.this[0]
id = "142"
}
import {
to = module.repository["git.unkin.net/unkin/container-agent-infra"].gitea_repository.this
to = module.repository["git.unkin.net/unkin/container-agent-infra"].gitea_repository.this[0]
id = "143"
}
@@ -199,7 +199,7 @@ import {
}
import {
to = module.repository["git.unkin.net/unkin/terraform-git"].gitea_repository.this
to = module.repository["git.unkin.net/unkin/terraform-git"].gitea_repository.this[0]
id = "144"
}
+11
View File
@@ -19,6 +19,7 @@ module "repository" {
name = each.value.name
organisation = each.value.organisation
fork_from = each.value.fork_from
description = each.value.description
private = each.value.private
default_branch = each.value.default_branch
@@ -35,6 +36,16 @@ module "repository" {
website = each.value.website
autodetect_manual_merge = each.value.autodetect_manual_merge
mirror = each.value.mirror
migration_clone_address = each.value.migration_clone_address
migration_service = each.value.migration_service
migration_mirror_interval = each.value.migration_mirror_interval
migration_lfs = each.value.migration_lfs
migration_lfs_endpoint = each.value.migration_lfs_endpoint
migration_issue_labels = each.value.migration_issue_labels
migration_milestones = each.value.migration_milestones
migration_releases = each.value.migration_releases
depends_on = [module.organisation]
}
@@ -1,4 +1,10 @@
locals {
fork_source = var.fork_from == null ? null : split("/", var.fork_from)
}
resource "gitea_repository" "this" {
count = var.fork_from == null ? 1 : 0
username = var.organisation
name = var.name
description = var.description
@@ -18,8 +24,32 @@ resource "gitea_repository" "this" {
autodetect_manual_merge = var.autodetect_manual_merge
archive_on_destroy = true
mirror = var.mirror
migration_clone_address = var.migration_clone_address
migration_service = var.migration_service
migration_mirror_interval = var.migration_mirror_interval
migration_lfs = var.migration_lfs
migration_lfs_endpoint = var.migration_lfs_endpoint
migration_issue_labels = var.migration_issue_labels
migration_milestones = var.migration_milestones
migration_releases = var.migration_releases
lifecycle {
# migration_mirror_interval defaults to "8h0m0s" but Gitea returns an empty MirrorInterval for non-mirror repos, so the read-back never matches and plans a spurious update every run; it is a migration-only knob with no drift to track here.
ignore_changes = [migration_mirror_interval]
}
}
moved {
from = gitea_repository.this
to = gitea_repository.this[0]
}
# gitea_fork has no archive_on_destroy, so removing a fork from the config deletes the repository instead of archiving it.
resource "gitea_fork" "this" {
count = var.fork_from == null ? 0 : 1
owner = local.fork_source[0]
repo = local.fork_source[1]
organization = var.organisation
}
@@ -1,3 +1,3 @@
output "id" {
value = gitea_repository.this.id
value = one(concat(gitea_repository.this[*].id, gitea_fork.this[*].id))
}
@@ -6,6 +6,22 @@ variable "organisation" {
type = string
}
variable "fork_from" {
description = "Source repository to fork, as \"<owner>/<repo>\". When set, a fork is created instead of a new repository."
type = string
default = null
validation {
condition = var.fork_from == null || can(regex("^[^/]+/[^/]+$", var.fork_from))
error_message = "fork_from must be \"<owner>/<repo>\"."
}
validation {
condition = var.fork_from == null || try(split("/", var.fork_from)[1], null) == var.name
error_message = "fork_from source repository must be named \"${var.name}\": a fork inherits the source name, so it cannot differ from the config file name."
}
}
variable "description" {
type = string
default = null
@@ -80,3 +96,48 @@ variable "autodetect_manual_merge" {
type = bool
default = null
}
variable "mirror" {
type = bool
default = null
}
variable "migration_clone_address" {
type = string
default = null
}
variable "migration_service" {
type = string
default = null
}
variable "migration_mirror_interval" {
type = string
default = null
}
variable "migration_lfs" {
type = bool
default = null
}
variable "migration_lfs_endpoint" {
type = string
default = null
}
variable "migration_issue_labels" {
type = bool
default = null
}
variable "migration_milestones" {
type = bool
default = null
}
variable "migration_releases" {
type = bool
default = null
}
+24
View File
@@ -17,6 +17,7 @@ variable "repository" {
type = map(object({
name = string
organisation = string
fork_from = optional(string)
description = optional(string)
private = optional(bool)
default_branch = optional(string)
@@ -32,8 +33,31 @@ variable "repository" {
repo_template = optional(bool)
website = optional(string)
autodetect_manual_merge = optional(bool)
mirror = optional(bool)
migration_clone_address = optional(string)
migration_service = optional(string)
migration_mirror_interval = optional(string)
migration_lfs = optional(bool)
migration_lfs_endpoint = optional(string)
migration_issue_labels = optional(bool)
migration_milestones = optional(bool)
migration_releases = optional(bool)
}))
default = {}
validation {
condition = alltrue([
for key, repo in var.repository :
length([for attribute, value in repo : attribute if value != null && !contains(["name", "organisation", "fork_from"], attribute)]) == 0
if repo.fork_from != null
])
error_message = "gitea_fork only takes the source repository and the owning organisation, so fork_from cannot be combined with other repository settings: ${join("; ", [
for key, repo in var.repository :
"${key} also sets ${join(", ", [for attribute, value in repo : attribute if value != null && !contains(["name", "organisation", "fork_from"], attribute)])}"
if repo.fork_from != null && length([for attribute, value in repo : attribute if value != null && !contains(["name", "organisation", "fork_from"], attribute)]) > 0
])}."
}
}
variable "branch_protection" {