terraform-provider-github icon indicating copy to clipboard operation
terraform-provider-github copied to clipboard

Fix `github_repository_file`: Disable default compute of author and email

Open pawnu opened this issue 2 years ago • 18 comments

When creating a file without author and email information, github will add the following default author and email values.

      "commit_author": "GitHub",
      "commit_email": "[email protected]",

When the same file is edited, with Computed set to false and no author and email information provided, it will correctly exclude the author and email information during PUT request, i.e. set to null.

      - commit_author       = "GitHub" -> null
      - commit_email        = "[email protected]" -> null

This will allow github to sign your commit with your bot/user's access token. Otherwise, github will expect you to create a signed commit as above default user.

Fixes https://github.com/integrations/terraform-provider-github/issues/1152

pawnu avatar Jun 06 '22 21:06 pawnu

I believe this will need more work as the state will save commit_author, and commit_email as null, and when comparing against the previous commit of the file in question, it will try to change the upstream default author and email information to the local state null even when there has been no change to the file. This means there will be a change every time you run terraform plan to remove the author/email information.

Also, destroying a file with this change still resulted in unsigned commit.

pawnu avatar Jun 27 '22 18:06 pawnu

This means there will be a change every time you run terraform plan to remove the author/email information.

I'm wondering if this is actually the desired behavior? Let's think of an unusual but possible scenario. Let's say I create a file without specifying the commit author/email using terraform with credentials from user A. Terraform will appropriately not pass this information to GitHub and the commit will get signed by user a by default. Now later, without making any changes to the resource, I rerun terraform but now using credentials from user b. What should happen? Technically the computed committer author/email has indeed changed and we should be updating the file with this new information. I don't think that info is known until Terraform actually applies using whatever credentials are supplied hence why it should always show a change every time you re-run. I agree this seems weird since we didn't specify the committer information in the first place. However maybe it is required if we want to handle the scenario when a committer is explicitly specified and changed from one value to another?

Part of me feels the committer fields should always just be computed and not able to be specified by a user. Then we could safely ignore the fields and only update the file on a SHA change. This would break anyone manually specifying that information. Perhaps there is some value to being able to set the author/email to values like "Terraform Bot" or team email of those responsible for the automation .

This leaves us trying to balance out which approach makes the most sense or if we need to put in some special logic when committer information isn't provided.

tjcorr avatar Jul 13 '22 22:07 tjcorr

Agreed the scenario you described makes sense when you have users a and b. What this PR was aiming to solve was issue with signing commits.

When you first create a file without committer information with terraform, the author information comes from the App/User token you used and it is signed. When you edit the file without committer information again, the author is set to GitHub user web-flow (https://github.com/web-flow) instead of your App/User, and the commit is not signed as you don't have web-flow's token to sign the commit. I guess this is where the logic should be put in place to resolve this unsigned commit issue.

Perhaps there is some value to being able to set the author/email to values like "Terraform Bot" or team email of those responsible for the automation .

That would be a good option to have as well with a way to sign the commits as the bot/team user.

pawnu avatar Jul 14 '22 17:07 pawnu

Another option might be to add a sign_commit flag that is mutually exclusive with author/email.

Regardless, this fix would be really helpful to us, as we can't require signed commits because of this.

rwblokzijl avatar Jul 19 '22 18:07 rwblokzijl

I like the idea of adding a sign_commit flag. If the PR is updated to include it, I'll review and merge!

kfcampbell avatar Jul 29 '22 22:07 kfcampbell

@pawnu will you be able to fix this? I would, but I don't know anything about go...

rwblokzijl avatar Aug 15 '22 11:08 rwblokzijl

I can try but I'm a beginner at Go too so it might take some time. Happy if someone takes it from here too as I want this to get fixed soon.

pawnu avatar Aug 15 '22 20:08 pawnu

I think commit_as_token makes more sense?

Also, I couldn't manage to create signed commit for deletion action even with the raw github API by omitting committer/author information so I don't think it's possible with terraform at this instance.

pawnu avatar Aug 15 '22 22:08 pawnu

Thanks for the implementation :)

I personally think sign_commit is more clear to the user while commit_as_token exposes implementation details. As a user just wanting signed commits its unclear this flag would do that.

Regarding the deletion event not being signed: I think this is a bug at the github API. Personally i don't think it should stop us from implementing this flag. I submitted the following bug report feel free to comment on it with further details or copy paste it into a new issue if you want ;)

rwblokzijl avatar Aug 16 '22 10:08 rwblokzijl

I'd say this is still a workaround and we're not intentionally signing commits so I'm not sure. I'd expect a flag like sign_commit to take in your signature key to create sign commits as your specified commit author. Seems like this functionality does exist in go-github https://github.com/google/go-github/blob/master/github/git_commits.go#L91

pawnu avatar Aug 16 '22 19:08 pawnu

I really think this is an intended feature we're using.

Github always "verifies" your commits when doing things through their own verified services (clicking "update branch" on a PR, editing inside the browser, etc). If a commit if verified like this github add the following popup when clicking the vefified tag: 2022-08-16-232636_264x98_scrot However, if the commit is made by a user and signed by a known GPG key it looks as follows: 2022-08-16-232732_255x92_scrot Github marks a commit as verified iff it can verify without a doubt that the github user associated with the commit is actually the one that created it. This is either by them adding a GPG key to their personal account and using that to sign the commit. Or by editing a file while authenticated to github.

In our case we are authenticated to github (by API token). Thus github should verify the commit (unless the username/email doesn't match).

rwblokzijl avatar Aug 16 '22 21:08 rwblokzijl

Actually, given @pawnu and my previous comments I am now in favour of the original implementation. Just signing it by default if the author/email are omitted as this mirrors the github features. @kfcampbell would you be willing to merge given this argument or do you still thing a flag is needed?

rwblokzijl avatar Aug 16 '22 21:08 rwblokzijl

Actually, given @pawnu and my previous comments I am now in favour of the original implementation. Just signing it by default if the author/email are omitted as this mirrors the github features.

I believe that the current state of the PR reflects a flag being added, not the original implementation. @rwblokzijl to clarify: you're in favor of not merging this PR at all, and relying on the existing state of the code?

kfcampbell avatar Aug 29 '22 23:08 kfcampbell

No, i am in favor of the original state of the PR: If author and email are ommited, allow github to verify the commit. This was achieved by making author and email non-computed.

rwblokzijl avatar Sep 06 '22 11:09 rwblokzijl

I believe this will need more work as the state will save commit_author, and commit_email as null, and when comparing against the previous commit of the file in question, it will try to change the upstream default author and email information to the local state null even when there has been no change to the file. This means there will be a change every time you run terraform plan to remove the author/email information.

So, I guess this resourceGithubRepositoryFileRead is used to read and set the state? It seems to resolve the above issue now.

pawnu avatar Sep 06 '22 21:09 pawnu

I'm not sure I'm seeing the correct behavior when testing this locally.

My Terraform file looks like this:

provider "github" {
}

terraform {
  required_providers {
    github = {
      source = "integrations/github"
    }
  }
}


resource "github_repository" "test" {
  name      = "repo-file-test-repo-1"
  auto_init = true
}

resource "github_repository_file" "test" {
  repository     = github_repository.test.name
  branch         = "main"
  file           = "test"
  content        = "baz"
  commit_message = "Managed by Terraform2"
  commit_author  = "Terraform User" # comment to test omission of commit_author
  commit_email   = "[email protected]" # comment to test omission of commit_email
}

On both the main branch and this feature branch, I created a repo with auto-init on, then created a file without the included commit_author and commit_email, then edited that file afterward with a slightly different file content with the commit_author and commit_email present.

In both cases, the result was that omitting the commit author and email did not cause GitHub to use itself for the committer. Instead, it used my local git credentials (same token as I provided in the GITHUB_TOKEN environment var), but picked up my commit_author and email from there. In neither case was the subsequent commit verified:

image

This change doesn't seem like it creates the desired functionality. What am I missing here?

kfcampbell avatar Sep 09 '22 22:09 kfcampbell

@kfcampbell I tested this with github app so I was assuming it would be the same with PAT. I guess there is no way to sign a commit as a user with terraform github at present?

I replicated your tests with my github app and 2 files, and they seem to be working as expected.

File1 file1

File2 file2

pawnu avatar Sep 10 '22 20:09 pawnu

:+1: it definitely seems to be an app-only feature. I think we could still merge this functionality if the docs and/or naming were updated to make that clear.

kfcampbell avatar Sep 19 '22 20:09 kfcampbell

@kfcampbell Done, I have updated the docs but feel free to edit or clarify further. Thanks

pawnu avatar Oct 09 '22 21:10 pawnu