Skip to content

feat: add github_organization_private_registry resource and data source - #3424

Closed
Gaardsholt wants to merge 29 commits into
integrations:mainfrom
Gaardsholt:private-registries
Closed

Gaardsholt wants to merge 29 commits into
integrations:mainfrom
Gaardsholt:private-registries

Conversation

@Gaardsholt

@Gaardsholt Gaardsholt commented May 13, 2026 •

Copy link
Copy Markdown
Contributor

This introduces the github_organization_private_registry resource and data source, allowing users to configure and manage centralized private registries at the organization level for Dependabot. Includes full CRUD acceptance tests, examples, and documentation.

Resolves #2720
Resolves #3339


Before the change?

  • New resource, no current behavior.

After the change?

  • You can now create a private registry with the following:
    resource "github_organization_private_registry" "docker_registry" {
      registry_type = "docker_registry"
      url           = "https://docker.pkg.github.com"
      username      = "my-docker-user"
      value         = "super-secret-password"
      visibility    = "all"
    }

Pull request checklist

  • Schema migrations have been created if needed (example)
  • Tests for the changes have been added (for bug fixes / features)
  • Docs have been reviewed and added / updated if needed (for bug fixes / features)

Does this introduce a breaking change?

Please see our docs on breaking changes to help!

  • Yes
  • No

I have run the acceptance tests myself with the following command, which ran successfully:

make testacc T=TestAccGithubOrganizationPrivateRegistry
make testacc T=TestAccGithubDataSourceOrganizationPrivateRegistry

I have also tested it by building the provider and using it with the following terraform:

resource "github_organization_private_registry" "maven_repository" {
  registry_type = "maven_repository"
  url           = "https://docker.pkg.github.com"
  username      = "my-docker-user"
  value         = "super-secret-password"
  visibility    = "all"
}
resource "github_organization_private_registry" "nuget_feed" {
  registry_type = "nuget_feed"
  url           = "https://docker.pkg.github.com"
  username      = "my-docker-user"
  value         = "super-secret-password"
  visibility    = "all"
}
resource "github_organization_private_registry" "goproxy_server" {
  registry_type = "goproxy_server"
  url           = "https://docker.pkg.github.com"
  username      = "my-docker-user"
  value         = "super-secret-password"
  visibility    = "all"
}
resource "github_organization_private_registry" "npm_registry" {
  registry_type = "npm_registry"
  url           = "https://docker.pkg.github.com"
  username      = "my-docker-user"
  value         = "super-secret-password"
  visibility    = "all"
}
resource "github_organization_private_registry" "rubygems_server" {
  registry_type = "rubygems_server"
  url           = "https://docker.pkg.github.com"
  username      = "my-docker-user"
  value         = "super-secret-password"
  visibility    = "all"
}
resource "github_organization_private_registry" "cargo_registry" {
  registry_type = "cargo_registry"
  url           = "https://docker.pkg.github.com"
  username      = "my-docker-user"
  value         = "super-secret-password"
  visibility    = "all"
}
resource "github_organization_private_registry" "composer_repository" {
  registry_type = "composer_repository"
  url           = "https://docker.pkg.github.com"
  username      = "my-docker-user"
  value         = "super-secret-password"
  visibility    = "all"
}
resource "github_organization_private_registry" "docker_registry" {
  registry_type = "docker_registry"
  url           = "https://docker.pkg.github.com"
  username      = "my-docker-user"
  value         = "super-secret-password"
  visibility    = "all"
}
resource "github_organization_private_registry" "git_source" {
  registry_type = "git_source"
  url           = "https://docker.pkg.github.com"
  username      = "my-docker-user"
  value         = "super-secret-password"
  visibility    = "all"
}
resource "github_organization_private_registry" "helm_registry" {
  registry_type = "helm_registry"
  url           = "https://docker.pkg.github.com"
  username      = "my-docker-user"
  value         = "super-secret-password"
  visibility    = "all"
}
resource "github_organization_private_registry" "pub_repository" {
  registry_type = "pub_repository"
  url           = "https://docker.pkg.github.com"
  username      = "my-docker-user"
  value         = "super-secret-password"
  visibility    = "all"
}
resource "github_organization_private_registry" "python_index" {
  registry_type = "python_index"
  url           = "https://docker.pkg.github.com"
  username      = "my-docker-user"
  value         = "super-secret-password"
  visibility    = "all"
}
resource "github_organization_private_registry" "terraform_registry" {
  registry_type           = "terraform_registry"
  url                     = "https://docker.pkg.github.com"
  username                = "my-docker-user"
  value                   = "super-secret-password"
  visibility              = "selected"
  selected_repository_ids = ["1225387540"]
}

data "github_organization_private_registry" "maven_repository" {
  name = github_organization_private_registry.maven_repository.name
}

output "registry_generated_name" {
  value       = github_organization_private_registry.npm_registry.name
  description = "The name that GitHub auto-generated for this registry."
}

output "retrieved_registry_url" {
  value       = data.github_organization_private_registry.maven_repository.url
  description = "URL retrieved from the registry data source."
}

Note

Full disclosure: This has been developed with the help of AI.

This introduces the `github_organization_private_registry` resource and data source, allowing users to configure and manage centralized private registries at the organization level for Dependabot. Includes full CRUD acceptance tests, examples, and documentation.

Signed-off-by: Lasse Gaardsholt <lasse.gaardsholt@bestseller.com>
@github-actions

Copy link
Copy Markdown

👋 Hi! Thank you for this contribution! Just to let you know, our GitHub SDK team does a round of issue and PR reviews twice a week, every Monday and Friday! We have a process in place for prioritizing and responding to your input. Because you are a part of this community please feel free to comment, add to, or pick up any issues/PRs that are labeled with Status: Up for grabs. You & others like you are the reason all of this works! So thank you & happy coding! 🚀

@Gaardsholt
Gaardsholt marked this pull request as ready for review May 13, 2026 13:52
@Gaardsholt

Copy link
Copy Markdown
Contributor Author

A small note, I didn't add hex_organization and hex_repository as when I tried I was getting the following error:

{
  "message": "Failed to create private registry configuration",
  "errors": [
    "registry_type must be one of: maven_repository, nuget_feed, goproxy_server, npm_registry, rubygems_server, cargo_registry, composer_repository, docker_registry, git_source, helm_registry, pub_repository, python_index, terraform_registry"
  ],
  "documentation_url": "https://docs.github.com/rest/private-registries/organization-configurations#create-a-private-registry-for-an-organization",
  "status": "422"
}

@Gaardsholt

Copy link
Copy Markdown
Contributor Author

Did I miss anything or what can we do to get this merged? :)

…b into private-registries

Signed-off-by: Lasse Gaardsholt <lasse.gaardsholt@bestseller.com>
Signed-off-by: Lasse Gaardsholt <lasse.gaardsholt@bestseller.com>
@deiga deiga added Type: Feature New feature or request New resource labels May 26, 2026
@deiga

deiga commented May 26, 2026

Copy link
Copy Markdown
Collaborator

@Gaardsholt Sorry, we are currently short on capacity and thus are focus mainly on improving the foundations to reduce maintenance workload

@deiga deiga left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a full review, just noticed the most likely unnecessary docs templates

Signed-off-by: Lasse Gaardsholt <lasse.gaardsholt@bestseller.com>
@Gaardsholt
Gaardsholt requested a review from deiga May 27, 2026 08:05

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

These provider review instructions are being used.

This PR introduces a new github_organization_private_registry resource and data source to manage centralized private registry configurations for Dependabot at the organization level. It resolves issues #2720 and #3339, enabling users to configure registry credentials (including OIDC auth) and visibility settings via Terraform.

Changes:

  • New resource (github_organization_private_registry) with full CRUD support, including secret encryption, multiple auth types (token, username_password, OIDC), and visibility control.
  • New data source (github_organization_private_registry) to read existing registry configurations.
  • Documentation, examples, and acceptance tests for both the resource and data source.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
github/resource_github_organization_private_registry.go New resource implementation with CRUD operations, schema, and secret encryption
github/data_source_github_organization_private_registry.go New data source implementation for reading registry info
github/resource_github_organization_private_registry_test.go Acceptance test for the resource (basic create + data source read)
github/data_source_github_organization_private_registry_test.go Acceptance test for the data source
github/provider.go Registers the new resource and data source
examples/resources/github_organization_private_registry/resource.tf Example snippet for tfplugindocs
examples/data-sources/github_organization_private_registry/data-source.tf Example snippet for tfplugindocs
docs/resources/organization_private_registry.md Resource documentation
docs/data-sources/organization_private_registry.md Data source documentation

Signed-off-by: Lasse Gaardsholt <lasse.gaardsholt@bestseller.com>
Signed-off-by: Lasse Gaardsholt <lasse.gaardsholt@bestseller.com>
Signed-off-by: Lasse Gaardsholt <lasse.gaardsholt@bestseller.com>
…make sure `secret` or `encrypted_value` is set when `auth_type` is `token` or `username_password`

Signed-off-by: Lasse Gaardsholt <lasse.gaardsholt@bestseller.com>
Signed-off-by: Lasse Gaardsholt <lasse.gaardsholt@bestseller.com>
@Gaardsholt
Gaardsholt requested a review from Copilot June 8, 2026 12:44

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 3 comments.

}

if v, ok := d.GetOk("username"); ok {
payload.Username = new(v.(string))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a compile error: go.mod is on Go 1.26, where the built-in new accepts an expression, and this package already uses new(d.Get(...)) in a hundred-plus places. Kept as is in #3650.

url = "https://npm.pkg.github.com"
auth_type = "username_password"
username = "github-actions"
secret = "super_secret_token_123"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in #3650: examples read the secret from a variable (var.npm_token, var.maven_password), plus an OIDC example that stores no secret at all.

Comment on lines +386 to +388
payload := github.UpdateOrganizationPrivateRegistry{
RegistryType: (*github.PrivateRegistryType)(new(d.Get("registry_type").(string))),
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in #3650: registry_type is no longer part of the update payload. auth_type became ForceNew too, since the API rejects changing it after creation, and it is likewise no longer sent on update.

@segarrt

segarrt commented Jun 22, 2026

Copy link
Copy Markdown

Hello @deiga, I am especially interested in this PR which I believe can resolve a big issue we have on our side. I understand you are working on others, but I would like to ask you if you have any ETA on merging the present one so that I can simply communicate internally.

@deiga deiga left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please make sure you read the Contribution guide and the Architecture guide, there are multiple aspects where you're going against the standard we expect

This is just a partial review

Signed-off-by: Lasse Gaardsholt <lasse.gaardsholt@bestseller.com>
@Gaardsholt

Copy link
Copy Markdown
Contributor Author

Please make sure you read the Contribution guide and the Architecture guide, there are multiple aspects where you're going against the standard we expect

This is just a partial review

I have read through both of the two guides, and have addressed most of your comments and hopefully I am now more closely following the standards.

The only comment I haven't resolved is #3424 (comment)

Signed-off-by: Lasse Gaardsholt <lasse.gaardsholt@bestseller.com>
@Gaardsholt
Gaardsholt requested a review from deiga July 3, 2026 21:09
@deiga
deiga requested a review from Copilot July 3, 2026 21:23

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 5 comments.

Comment on lines +84 to +91
"selected_repository_ids": {
Type: schema.TypeSet,
Optional: true,
Elem: &schema.Schema{
Type: schema.TypeInt,
},
Description: "An array of repository IDs that can access the organization private registry.",
},

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in #3650: Set: schema.HashInt declared. Also found that the GET endpoint never returns selected_repository_ids (only the POST 201 body does), so Read now keeps the configured list instead of wiping it, and the description says import cannot recover it.

Comment on lines +24 to +26
Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
},

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in #3650: import.sh and import-by-string-id.tf added, the generated doc now has an Import section.

@3rwww1

3rwww1 commented Sep 11, 2026 •

Copy link
Copy Markdown

Very Interested in contributing the requested changes to this PR, if @Gaardsholt you are otherwise swamped at the moment (and in that case, thanks for the work already done 🫶 )

I'd really want to give it a last push and ship it ;) !

@Gaardsholt

Copy link
Copy Markdown
Contributor Author

@3rwww1 I am quite swamped at the moment, so feel free to take this to the finish line :)

@3rwww1

3rwww1 commented Sep 21, 2026 •

Copy link
Copy Markdown

Thanks @Gaardsholt. Picked it up as agreed: #3650

Shape of that PR:

  • commit 1 is a squash of this branch, authored by you;
  • commit 2 addresses the open review threads and the guides (no Read after Create/Update, errors.AsType 404 handling, auth_type ForceNew, Set: schema.HashInt, remote_updated_at for secret drift, import docs, secret-free examples, t.Run tests). Acceptance tests pass against a sandbox organization.

If you would rather keep this PR as the one to merge, cherry-pick the second commit (53a10c8a on 3rwww1/terraform-provider-github, branch feat/organization-private-registry) onto your branch and I will close mine. Either way works for me.

@Gaardsholt

Copy link
Copy Markdown
Contributor Author

@3rwww1 I'll close this one and you can continue the work in your branch - thank you so much for finishing this one! :)

Superseded by #3650

@Gaardsholt Gaardsholt closed this Sep 21, 2026
@Gaardsholt
Gaardsholt deleted the private-registries branch September 21, 2026 12:05
3rwww1 pushed a commit to 3rwww1/terraform-provider-github that referenced this pull request Oct 11, 2026
3rwww1 added a commit to 3rwww1/terraform-provider-github that referenced this pull request Oct 28, 2026
Lets Terraform manage organization private registries (for example an
npm or Maven registry that Dependabot uses) and read them back through
a data source.

Builds on integrations#3424,
then follows provider conventions and addresses its review: no Read
after Create or Update, auth_type forces a new resource, registry_type
is not sent on update, and out-of-band secret changes are detected and
repaired.

Co-authored-by: Lasse Gaardsholt <lasse.gaardsholt@bestseller.com>
Signed-off-by: Erwan Queffélec <e.queffelec@go-electra.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

New resource Type: Feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEAT]: add new resource for private registries [FEAT]: Add organization private registries configuration

5 participants