Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature Request] Pull Requests and git branch publishes #286

Closed
11 tasks
jcudit opened this issue Oct 18, 2019 · 5 comments
Closed
11 tasks

[Feature Request] Pull Requests and git branch publishes #286

jcudit opened this issue Oct 18, 2019 · 5 comments

Comments

@jcudit
Copy link
Contributor

jcudit commented Oct 18, 2019

Overview

👋 from GitHub's datacenter team. We are requesting guidance on functionality for this pair of features:

  • Add limited support for the Git Data API

    • Assemble a git tree from one or many templatefile outputs
    • Publish an assembled git tree (☝️)
    • Read a branch for the purposes of associating it to a PR (👇)
  • Add limited support for the Pull Requests API

  • Package features into a quality 🚢

    • Acceptance testing
    • Documentation external to the resource code itself
    • Lint for existing style and standards
    • Review for breaking changes to components that may already be in use in the wild
      • config files
      • Terraform states

cc https://github.com/terraform-providers/terraform-provider-github/issues/254 (related solution to initializing a repo with Terraform)

Suggested UX

resource "github_repository_content" "actions" {

  repository = "${local.repository_name}"

  # Optional Pull Requesst overrides of sane defaults
  pull_request {
    title = "Create standard Actions for this repo"
    target_branch    = "master"
    working_branch   = "actions-by-terraform"

    body = "${local.create_actions_body}"
    issue = "${local.create_actions_issue}"
  }

  # Declare content as a map of paths to rendered templates
  content = {
    ".github/workflows/build.yml" = templatefile("path/to/build.yml", { foo = "bar" }),
    ".github/workflows/release.yml" = templatefile("path/to/release.yml", { foo = "bar" }),
  }
}

This resource block accomplishes the following:

  • Consumes a list of files (content map)
  • Obtains a local clone of the repository specified by repository
  • Renders all content to the repository worktree with a base of target_branch
  • Commits changes (if any) and publishes a Pull Request using the working_branch

Further Discussion

This continues an existing discussion with @paultyng:

There are limitations with file handling inside terraform (length restrictions, complications in handling binary data, etc), which is one factor, but I think this may also be complex without a good SDK or supporting library to handle a lot of the standard git hash generation and so forth.

We use go-google to achieve this currently. This example is essentially what we've had running for a couple years now to automate creation of application repositories. Does Terraform need to store blobs that are uploaded to a branch?

It may be simpler to integrate via a more generic git client or creating a git provider to use together with a github provider perhaps. I have a personal project for a git provider that gives you info on a local repository as an example, but we could create one to operate on a remote repository and sync file state or something.

While tempting to leverage git directly, I want to give the GitHub Data API a shot to avoid creating a new provider. This remains an option if adding resources to the GitHub provider becomes untenable.


Here are some additional questions:

  • A Pull Request typically has a short lifetime where it is active, then merges, and then is idle in this state indefinitely. Does this lifecycle conflict with how Terraform treats resources?
  • What are some typical ways that existing Terraform state or configuration files could break when adding a feature like this? Do existing test patterns to help with this?
  • The initial use case for this is populating a repository with content immediately after creation. Is this effort more suited to a provisioner rather than a provider?
@jcudit
Copy link
Contributor Author

jcudit commented Oct 26, 2019

@paultyng - thanks for discussing this yesterday. Key takeaways I've captured are below.


declaratively, a repository should have a file in a location with content from a local file path

☝️ has been implemented over in https://github.com/edahlseng/terraform-provider-repository-template (❤️@edahlseng) and can be leveraged as a base. Doing so allows us to move the design away from the procedural github_pull_request concept and towards a declarative github_repository_content concept instead.


Does Terraform need to store blobs that are uploaded to a branch?

The initial release of this feature will support simple text files. Documentation should reflect this and deter content that is not a unicode string.


I've updated the suggested UX in the first comment to reflect the new design. The first iteration is archived here:

# // NewPullRequest represents a new pull request to be created.
# // https://github.com/google/go-github/blob/v28.0.1/github/pulls.go#L242-L251
# type NewPullRequest struct {
# 	Title               *string `json:"title,omitempty"`
# 	Head                *string `json:"head,omitempty"`
# 	Base                *string `json:"base,omitempty"`
# 	Body                *string `json:"body,omitempty"`
# 	Issue               *int    `json:"issue,omitempty"`
# 	MaintainerCanModify *bool   `json:"maintainer_can_modify,omitempty"`
# 	Draft               *bool   `json:"draft,omitempty"`
# }
resource "github_pull_request" "create_actions" {
  title = "Create standard Actions for this repo"
  base  = "master"

  # Branch to be created, populated and associated to this PR
  head  = "${format("create_actions_%s", random_id.create_actions_id.hex}"
  body = "${local.create_actions_body}"
  issue = "${local.create_actions_issue}"

  # Abstraction for Git Tree and Tree Entries as a map of paths to rendered templates
  content = {
    ".github/workflows/build.yml" = templatefile("path/to/build.yml", { foo = "bar" }),
    ".github/workflows/release.yml" = templatefile("path/to/release.yml", { foo = "bar" }),
  }
}

@edahlseng
Copy link

Woot, super excited to see interest in features like this in an upstream provider! Let me know if there's anything I can do to help. Always happy to accept pull requests on my provider in the meantime, too!

@jcudit
Copy link
Contributor Author

jcudit commented Feb 13, 2020

This was partially addressed by https://github.com/terraform-providers/terraform-provider-github/pull/318. There is follow up work needed to got Pull Request support added in now that a base layer capable of modifying files has landed.

@jcudit
Copy link
Contributor Author

jcudit commented Dec 8, 2020

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants