diff --git a/examples/repository_file/README.md b/examples/repository_file/README.md new file mode 100644 index 0000000000..4b6f8b588e --- /dev/null +++ b/examples/repository_file/README.md @@ -0,0 +1,24 @@ +# Repository File + +This provides a template for managing [repository files](https://docs.github.com/en/repositories/working-with-files/managing-files). + +This example will also create or update a file in the specified `repository`. See https://www.terraform.io/docs/providers/github/index.html for details on configuring [`providers.tf`](./providers.tf) accordingly. + +Alternatively, you may use variables passed via the command line or `auto.tfvars`: + +```tfvars +organization = "" +github_token = "" + +repository = "" +file = "" +content = "" +branch = "" +commit_author = "" +commit_message = "" +commit_email = "" +``` + +```console +terraform apply +``` diff --git a/examples/repository_file/main.tf b/examples/repository_file/main.tf new file mode 100644 index 0000000000..bab860326a --- /dev/null +++ b/examples/repository_file/main.tf @@ -0,0 +1,11 @@ +resource "github_repository_file" "this" { + repository = var.repository + file = var.file + content = var.content + + branch = var.branch + + commit_author = var.commit_author + commit_message = var.commit_message + commit_email = var.commit_email +} diff --git a/examples/repository_file/outputs.tf b/examples/repository_file/outputs.tf new file mode 100644 index 0000000000..e69de29bb2 diff --git a/examples/repository_file/providers.tf b/examples/repository_file/providers.tf new file mode 100644 index 0000000000..43f79f6456 --- /dev/null +++ b/examples/repository_file/providers.tf @@ -0,0 +1,12 @@ +terraform { + required_providers { + github = { + source = "integrations/github" + } + } +} + +provider "github" { + owner = var.organization + token = var.github_token +} diff --git a/examples/repository_file/variables.tf b/examples/repository_file/variables.tf new file mode 100644 index 0000000000..cd5ed6272e --- /dev/null +++ b/examples/repository_file/variables.tf @@ -0,0 +1,43 @@ +variable "organization" { + description = "GitHub organization used to configure the provider" + type = string +} + +variable "github_token" { + description = "GitHub access token used to configure the provider" + type = string +} + +variable "repository" { + description = "The name of the repository" + type = string +} + +variable "file" { + description = "The name of the file to create" + type = string +} +variable "content" { + description = "The content of the file to create" + type = string +} +variable "branch" { + description = "The branch to create the file in" + type = string + default = "main" +} +variable "commit_author" { + description = "The name of the author of the commit" + type = string + default = "" +} +variable "commit_message" { + description = "The message of the commit" + type = string + default = "" +} +variable "commit_email" { + description = "The email of the author of the commit" + type = string + default = "" +} diff --git a/github/resource_github_repository_file.go b/github/resource_github_repository_file.go index c84a8a1953..a9ee9440bb 100644 --- a/github/resource_github_repository_file.go +++ b/github/resource_github_repository_file.go @@ -3,13 +3,13 @@ package github import ( "context" "errors" + "fmt" "log" "net/http" "net/url" + "slices" "strings" - "fmt" - "github.com/google/go-github/v66/github" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) @@ -367,23 +367,34 @@ func resourceGithubRepositoryFileRead(d *schema.ResourceData, meta interface{}) return err } - commit_author := commit.Commit.GetCommitter().GetName() - commit_email := commit.Commit.GetCommitter().GetEmail() - - _, hasCommitAuthor := d.GetOk("commit_author") - _, hasCommitEmail := d.GetOk("commit_email") + if commit_author_st, hasCommitAuthor := d.GetOk("commit_author"); hasCommitAuthor { + if err = d.Set("commit_author", commit_author_st.(string)); err != nil { + return err + } + } else { + if err = d.Set("commit_author", nil); err != nil { + return err + } + } - //read from state if author+email is set explicitly, and if it was not github signing it for you previously - if commit_author != "GitHub" && commit_email != "noreply@github.com" && hasCommitAuthor && hasCommitEmail { - if err = d.Set("commit_author", commit_author); err != nil { + if commit_email_st, hasCommitEmail := d.GetOk("commit_email"); hasCommitEmail { + if err = d.Set("commit_email", commit_email_st.(string)); err != nil { return err } - if err = d.Set("commit_email", commit_email); err != nil { + } else { + if err = d.Set("commit_email", nil); err != nil { return err } } - if err = d.Set("commit_message", commit.GetCommit().GetMessage()); err != nil { - return err + + if commit_message_st, hasCommitMessage := d.GetOk("commit_message"); hasCommitMessage { + if err = d.Set("commit_message", commit_message_st.(string)); err != nil { + return err + } + } else { + if err = d.Set("commit_message", nil); err != nil { + return err + } } return nil @@ -437,20 +448,30 @@ func resourceGithubRepositoryFileUpdate(d *schema.ResourceData, meta interface{} opts.Message = &m } - create, _, err := client.Repositories.CreateFile(ctx, owner, repo, file, opts) - if err != nil { - return err + schema := resourceGithubRepositoryFile() + allSchemaKeys := make([]string, 0, len(schema.Schema)) + for k := range schema.Schema { + allSchemaKeys = append(allSchemaKeys, k) } + allSchemaKeysButCommitDetails := slices.DeleteFunc(allSchemaKeys, func(v string) bool { + return slices.Contains([]string{"commit_sha", "commit_author", "commit_email", "commit_message"}, v) + }) - if err = d.Set("commit_sha", create.GetSHA()); err != nil { - return err + if d.HasChanges(allSchemaKeysButCommitDetails...) { + create, _, err := client.Repositories.CreateFile(ctx, owner, repo, file, opts) + if err != nil { + return err + } + if err = d.Set("commit_sha", create.GetSHA()); err != nil { + return err + } + } else { + log.Printf("[DEBUG] No changes to commit, skipping commit") } - return resourceGithubRepositoryFileRead(d, meta) } func resourceGithubRepositoryFileDelete(d *schema.ResourceData, meta interface{}) error { - client := meta.(*Owner).v3client owner := meta.(*Owner).name ctx := context.Background()