Conversation
230fa3c to
b34e02b
Compare
|
Yes it does, and makes the org read only, so you can't create new repos in there. The new button is disabled. https://docs.github.com/en/organizations/managing-organization-settings/archiving-an-organization
Yes, it cascades. Archiving an organization archives all its repositories (except mirrors) and blocks new ones. Repositories transferred in are archived too. While the organization is archived you can't unarchive its repositories one by one. Unarchiving only unarchives the organization, and the repositories stay archived. Same as GitHub While clicking through the UI I noticed you can still create projects in an archived organization. Should that be disabled too? It's a simple change. I'd leave members and teams as they are, archived or not.
|
Yes I'd say an archived org should, like a archived project, act read-only. But do check how projects and other things behave in archived repos first, there might be more such pre-existing bugs. If you can, have your AI validate that our behaviour of archived orgs matches github's. |
Will do. just a question how should we handle if org has a mirror? As you have to convert it to a regular repo so you can archive it. So we have two choices leave it as it is and the mirror will be the exception, or decline to convert to archived org while we have active mirror? |
|
Check how GitHub does it and align to that if possible. Maybe we could just allow mirror repos be archived? Why was it forbidden? |
|
To keep the changeset small, I think we can deny archiving an org when it contains mirror repos, e.g. show an error in that case and tell the user they have to manually convert those mirrors to regular repos first. |
bad7ca6 to
bf408c7
Compare
Done. If the org has mirrors, archiving is refused and the settings page lists them, so they can be converted first. An archived org is now read-only: projects, labels, webhooks, Actions settings, packages and the profile. I checked it against GitHub and it behaves the same. The branch is squashed into 5 commits. |
bf408c7 to
bb371f1
Compare
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Critical archive-transition races and unresolved archived-state enforcement gaps block safe approval.
Review effort: Lite
Findings: 3
Open (3)
What changed in this PR
Adds organization archiving, repository propagation, read-only enforcement, dashboard filtering, API support, migrations, and tests.
Changes:
- Adds archived organization state, archive/unarchive flows, audit events, and migration support.
- Archives existing and transferred repositories while blocking mutations in archived organizations.
- Updates dashboard UI, templates, localization, API schemas, and integration coverage.
Open findings include archive-transition races in repository creation and transfer, incomplete enforcement paths, API unarchive behavior, stale issue indexing, and a dashboard keyboard interaction issue.
| File | Summary |
|---|---|
web_src/js/components/DashboardRepoList.vue |
Archived organization filtering and search UI |
web_src/css/modules/dropdown.css |
Disabled dropdown styling |
tests/integration/org_archived_test.go |
Organization archive integration tests |
tests/integration/api_repo_edit_test.go |
Archived repository behavior tests |
templates/webhook/new.tmpl |
Disables archived organization webhook forms |
templates/user/settings/applications_oauth2_list.tmpl |
Hides OAuth mutations |
templates/user/settings/applications_oauth2_edit_form.tmpl |
Disables OAuth editing |
templates/user/dashboard/repolist.tmpl |
Adds archive metadata to the dashboard |
templates/user/dashboard/navbar.tmpl |
Adds archived organization navigation |
templates/swagger/v1-swagger.generated.json |
Updated Swagger documentation |
templates/swagger/v1-openapi3.generated.json |
Updated OpenAPI documentation |
templates/shared/variables/variable_list.tmpl |
Read-only variables UI |
templates/shared/secrets/add_list.tmpl |
Read-only secrets UI |
templates/shared/actions/scoped_workflows.tmpl |
Read-only workflow settings |
templates/shared/actions/runner_list.tmpl |
Read-only runner controls |
templates/shared/actions/runner_edit.tmpl |
Read-only runner editing |
templates/shared/actions/owner_general_settings.tmpl |
Read-only Actions settings |
templates/repo/settings/webhook/settings.tmpl |
Disables webhook mutations |
templates/repo/settings/webhook/history.tmpl |
Hides webhook replay |
templates/repo/settings/webhook/base_list.tmpl |
Hides webhook controls |
templates/repo/settings/options.tmpl |
Blocks repository unarchiving |
templates/repo/issue/labels/label_list.tmpl |
Blocks organization label editing |
templates/projects/new.tmpl |
Disables project creation |
templates/package/shared/cleanup_rules/list.tmpl |
Hides cleanup rule editing |
templates/package/shared/cleanup_rules/edit.tmpl |
Disables cleanup rule mutations |
templates/package/shared/cargo.tmpl |
Hides Cargo mutations |
templates/org/settings/options.tmpl |
Makes archived settings read-only |
templates/org/settings/options_dangerzone.tmpl |
Adds archive controls |
templates/org/settings/layout_head.tmpl |
Adds an archived warning |
templates/org/settings/labels.tmpl |
Hides label creation |
templates/org/home.tmpl |
Hides repository creation |
templates/org/header.tmpl |
Displays archived status |
services/repository/transfer.go |
Archives transferred repositories |
services/repository/transfer_test.go |
Tests transfer restrictions |
services/repository/create.go |
Blocks creation in archived organizations |
services/org/org.go |
Implements organization archival |
services/org/org_test.go |
Tests archival behavior |
services/convert/convert.go |
Exposes archive state in API data |
services/context/package.go |
Restricts archived package owners |
services/context/org.go |
Adds archived organization context guards |
services/context/api.go |
Adds archived organization API errors |
routers/web/web.go |
Applies archived organization route guards |
routers/web/user/home.go |
Adds archived organization dashboard state |
routers/web/repo/setting/setting.go |
Handles archived transfer and unarchive errors |
routers/web/repo/repo.go |
Handles archived creation errors |
routers/web/repo/migrate.go |
Handles archived migration errors |
routers/web/repo/fork.go |
Handles archived fork errors |
routers/web/org/setting.go |
Adds the organization archive endpoint |
routers/web/org/projects.go |
Blocks archived project writes |
routers/api/v1/shared/project.go |
Documents archived project responses |
routers/api/v1/repo/transfer.go |
Handles archived transfer errors |
routers/api/v1/repo/repo.go |
Handles archived repository changes |
routers/api/v1/repo/migrate.go |
Handles archived migration errors |
routers/api/v1/repo/fork.go |
Handles archived fork errors |
routers/api/v1/org/org.go |
Adds archive API support |
routers/api/v1/org/label.go |
Guards organization labels |
routers/api/v1/org/hook.go |
Guards organization hooks |
routers/api/v1/org/avatar.go |
Guards organization avatars |
routers/api/v1/org/action.go |
Guards organization Actions |
routers/api/v1/api.go |
Registers archived organization guards |
options/locale/locale_en-US.json |
Adds archive-related translations |
modules/structs/org.go |
Adds archive API fields |
models/user/user.go |
Adds archive persistence fields |
models/organization/org.go |
Adds archive state persistence |
models/organization/org_list.go |
Excludes archived creation targets |
models/organization/org_list_test.go |
Tests archived organization filtering |
models/audit/action.go |
Adds archive audit events |
modelmigration/v29/v356.go |
Adds archive database columns |
modelmigration/migrations.go |
Registers the migration |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| if err := org_model.SetArchiveOrgState(ctx, org, archived); err != nil { | ||
| return err | ||
| } | ||
| if !archived { | ||
| return nil | ||
| } | ||
| if err := db.GetEngine(ctx).Where(builder.Eq{"owner_id": org.ID, "is_archived": false}).Find(&repos); err != nil { | ||
| return err | ||
| } | ||
| for _, repo := range repos { | ||
| if err := repo_model.SetArchiveRepoState(ctx, repo, true); err != nil { | ||
| return err | ||
| } | ||
| } |
| if u.IsOrganization() && u.IsArchived { | ||
| return util.NewPermissionDeniedErrorf("organization %s is archived", u.Name) | ||
| } |
| if err := checkTransferIntoArchivedOrg(newOwner, repo); err != nil { | ||
| return err | ||
| } |
|
@silverwind I checked the Copilot comments. The race is real but unlikely, and harmless: worst case one repo in an archived org stays writable. I see 3 options:
Any preference? There was a merge conflict in the migrations so I had to rebase |
f164d65 to
a1684a7
Compare
|
Recent changes on include some race-prevention code during database transactions, so it might be unnecessary, but I have not checked in detail if those preventions really apply here. Code should primarily be written to be race-free. Always be sceptical about AI reviews. I will do a more complete review using Claude later. |
a1684a7 to
647086a
Compare
|
I added one QoL, if you open an archived org it will show you the archived repos immediatly instead of having to go to the ui and select to show the arcvhied repos. |





I have a lot of organizations with only archived repositories, and they clutter my dashboard. Moving them all into one archive organization would lose where they came from, and I'd have to track that with topics.
Archiving an organization now archives all its repositories and blocks new ones. Repositories transferred in are archived too. Unarchiving only unarchives the organization.
Archived organizations are hidden on the dashboard by default, with a toggle to show them.