Skip to content

Conversation

@stevehipwell
Copy link
Collaborator

Resolves #2983
Resolves #2984
Resolves #2985
Closes #2941


Before the change?

  • The acceptance tests are complicated and some are broken
  • Some of the code is incorrect

After the change?

  • Acceptance tests have been refactored
    • Fewer tests
    • Simpler test structure
    • Test env setup has been made more granular and documented
  • Acceptance tests have been run
    • Some tests that require paid features haven't been run yet

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

@github-actions
Copy link

github-actions bot commented Dec 8, 2025

👋 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! 🚀

Copy link
Contributor

@deiga deiga left a comment

Choose a reason for hiding this comment

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

Half-way through, looking good so far!

Comment on lines +46 to +78
// Can't test due to SDK and test framework limitations
// t.Run("queries an invalid branch without error", func(t *testing.T) {
// randomID := acctest.RandStringFromCharSet(5, acctest.CharSetAlphaNum)

// config := fmt.Sprintf(`
// resource "github_repository" "test" {
// name = "tf-acc-test-%[1]s"
// auto_init = true
// }

// data "github_branch" "test" {
// repository = github_repository.test.name
// branch = "xxxxxx"
// }
// `, randomID)

// check := resource.ComposeTestCheckFunc(
// resource.TestCheckResourceAttr(
// "data.github_branch.test", "ref", "",
// ),
// )

// resource.Test(t, resource.TestCase{
// PreCheck: func() { skipUnauthenticated(t) },
// ProviderFactories: providerFactories,
// Steps: []resource.TestStep{
// {
// Config: config,
// Check: check,
// },
// },
// })
// })
Copy link
Contributor

Choose a reason for hiding this comment

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

question: Is there value in keeping this test? The API for refs returns 404 if a ref doesn't exist. I don't understand why this behaviour would be expected from the provider

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The question about the behaviour is why I've left them commented out. I think we'll need a few issues opened once this is merged to make iterative improvements.

Comment on lines +42 to +73
// Can't test due to SDK and test framework limitations
// t.Run("queries an invalid ref without error", func(t *testing.T) {
// randomID := acctest.RandStringFromCharSet(5, acctest.CharSetAlphaNum)
// config := fmt.Sprintf(`
// resource "github_repository" "test" {
// name = "tf-acc-test-%[1]s"
// auto_init = true
// }

// data "github_ref" "test" {
// repository = github_repository.test.id
// ref = "heads/xxxxxx"
// }
// `, randomID)

// check := resource.ComposeTestCheckFunc(
// resource.TestCheckNoResourceAttr(
// "data.github_ref.test", "id",
// ),
// )

// resource.Test(t, resource.TestCase{
// PreCheck: func() { skipUnauthenticated(t) },
// ProviderFactories: providerFactories,
// Steps: []resource.TestStep{
// {
// Config: config,
// Check: check,
// },
// },
// })
// })
Copy link
Contributor

Choose a reason for hiding this comment

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

Comment on lines +166 to +205
// Can't test due to SDK and test framework limitations
// t.Run("try reading a non-existent file without an error", func(t *testing.T) {
// randomID := acctest.RandStringFromCharSet(5, acctest.CharSetAlphaNum)
// config := fmt.Sprintf(`
// resource "github_repository" "test" {
// name = "tf-acc-test-%s"
// auto_init = true

// lifecycle {
// ignore_changes = all
// }
// }

// data "github_repository_file" "test" {
// repository = github_repository.test.name
// file = "test"
// }
// `, randomID)

// resource.Test(t, resource.TestCase{
// PreCheck: func() { skipUnauthenticated(t) },
// ProviderFactories: providerFactories,
// Steps: []resource.TestStep{
// {
// Config: config,
// Check: resource.ComposeTestCheckFunc(
// resource.TestCheckNoResourceAttr("data.github_repository_file.test", "id"),
// resource.TestCheckNoResourceAttr("data.github_repository_file.test", "branch"),
// resource.TestCheckNoResourceAttr("data.github_repository_file.test", "ref"),
// resource.TestCheckNoResourceAttr("data.github_repository_file.test", "content"),
// resource.TestCheckNoResourceAttr("data.github_repository_file.test", "sha"),
// resource.TestCheckNoResourceAttr("data.github_repository_file.test", "commit_sha"),
// resource.TestCheckNoResourceAttr("data.github_repository_file.test", "commit_message"),
// resource.TestCheckNoResourceAttr("data.github_repository_file.test", "commit_author"),
// resource.TestCheckNoResourceAttr("data.github_repository_file.test", "commit_email"),
// ),
// },
// },
// })
// })
Copy link
Contributor

Choose a reason for hiding this comment

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

question: Similar to https://github.com/integrations/terraform-provider-github/pull/2986/files#r2601299558, is there value in keeping this as it's not something the API supports?

Comment on lines +113 to +130
// t.Run("fails for invalid endpoint", func(t *testing.T) {
// config := `
// data "github_rest_api" "test" {
// endpoint = "/xxx"
// }
// `

// resource.Test(t, resource.TestCase{
// PreCheck: func() { skipUnauthenticated(t) },
// ProviderFactories: providerFactories,
// Steps: []resource.TestStep{
// {
// Config: config,
// ExpectError: regexp.MustCompile("Error: GET https://api.github.com/xx.*: 414"),
// },
// },
// })
// })
Copy link
Contributor

Choose a reason for hiding this comment

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

question: Why is this commented out?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The current REST API implementation swallows 404 errors, and I can't off the top of my head think of a way to repeatedly get a different error response with an anonymous call. This is another behaviour that needs discussing.

t.Run("with an organization account", func(t *testing.T) {
testCase(t, organization)
depends_on = ["github_repository.test", "github_team.test", "github_team_repository.test"]
Copy link
Contributor

Choose a reason for hiding this comment

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

question: Do all of these dependents need to be set? I would assume that github_team_repository would already depend on github_team and github_repository implicitly.

If it doesn't should that be fixed?

Also: I don't think resources can be quoted there

Suggested change
depends_on = ["github_repository.test", "github_team.test", "github_team_repository.test"]
depends_on = [github_team_repository.test]

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The depends on needs to be set as it's a data source under test so the resources need to be applied first. Given the behaviour of depends on it's good practice to be explicit here as if the pattern is re-used in a multi step test not having all the resources in there could cause an issue or require additional work to validate if it's the reason for a failure.

Also: I don't think resources can be quoted there

At first glance I'd have agreed with you (if I didn't know the tests were passing), but HCL is very permissive and TF has a lot of legacy baggage.

I'll update these ones, but this type of stylistic cleanup is something that can happen once the PR has landed.

Comment on lines +12 to +14
if len(testAccConf.testExternalUser) == 0 {
t.Skip("No external user provided")
}
Copy link
Contributor

Choose a reason for hiding this comment

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

question: Would we benefit from this moving to acc_test.go as a skipUnlessExternal function?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

It would do, once we've got the tests actually running in CI and the concepts are correct. I'm pretty sure the org app pattern in the tests at the moment is wrong and will need replacing, but all of this would be easier being incremental changes on top of a largely working test suite.

AllowedValues: allowedValuesString,
}

if val, ok := d.GetOk("values_editable_by"); ok {
Copy link
Contributor

Choose a reason for hiding this comment

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

question: Since this is a computed value, aren't there cases where ok would be false, but val has a value? Should we ignore the value in those cases?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This is in the resource create, we only want to send the value if it's been explicitly set. The computed part happenes when we set it after it's been created, at which point we can use that value. Without this change the implementation requires the value to be set as otherwise we're sending "" instead of nil.

Copy link
Contributor

Choose a reason for hiding this comment

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

question: Is there a reason to keep this file around? Are we planning to re-use it for projectsV2?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The other files exist, so this should be removed with them.

Copy link
Contributor

Choose a reason for hiding this comment

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

Same question as for project tests

Copy link
Contributor

Choose a reason for hiding this comment

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

Same question as for project tests

Comment on lines +61 to +69
collaborators := state.RootModule().Resources["github_repository_collaborators.test_repo_collaborators"].Primary
for name, val := range collaborators.Attributes {
if strings.HasPrefix(name, "user.") && strings.HasSuffix(name, ".username") && val != testAccConf.testExternalUser {
return fmt.Errorf("expected user.*.username to be set to %s, was %s", testAccConf.testExternalUser, val)
}
if strings.HasPrefix(name, "user.") && strings.HasSuffix(name, ".permission") && val != "push" {
return fmt.Errorf("expected user.*.permission to be set to push, was %s", val)
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

question: Could this be replaced with a resource.TestCheckResourceAttr function call?
Or is there a purpose to this which I'm not seeing?

Maybe something like:

resource.TestCheckResourceAttr("github_repository_collaborators.test_repo_collaborators", "user.0.username", testAccConf.testExternalUser)
resource.TestCheckResourceAttr("github_repository_collaborators.test_repo_collaborators", "user.0.permission", "push")

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

It's been a while since I wrote this, but I'm pretty sure that it solves the unknown ordering issue.

Copy link
Contributor

Choose a reason for hiding this comment

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

I get that, but there is only 1 collaborator in this config, right? If it's meant to be a helper for the sorting case, maybe it should be extracted for re-use?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yeah it could be, but given the sheer amount of resources I've put into this PR I'd just like to get it merged and then it can be iterated on. I'd hate to lose something I spent time on that turns out later to be important. Once the code is merged anything removed can be retrieved, I think I've already lost work due to needing to get the tests passing.

Copy link
Contributor

Choose a reason for hiding this comment

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

Sure! Most of my suggestions are usually "address now, if capacity, otherwise do a follow-up".

I should learn to write that, since usually people can't rind my mind! 😬

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

That's fine. If this was a smaller piece of work or even if it was all fresh in my mind I'd be making more changes and being less cautious about removing code.


blocked, _, err := conn.Organizations.IsBlocked(context.TODO(), orgName, username)
blocked, _, err := conn.Organizations.IsBlocked(context.Background(), orgName, username)
Copy link
Contributor

Choose a reason for hiding this comment

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

question: would we get access to t.Context() if we changed the function definition to func testAccCheckOrganizationBlockExists(ctx context.Context, n string)?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I cascaded t.Context() everywhere I could (other than for projects where I just got rid of context.TODO()), but some usage comes from typed functions being called directly. We could wrap up these function calls to pass it in, but IMHO this is a problem for another day.

Copy link
Contributor

Choose a reason for hiding this comment

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

Definitely, let's get this shippable!

@deiga deiga mentioned this pull request Dec 10, 2025
5 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

acctest For CI / automated testing

Projects

None yet

3 participants