Skip to content

GCSS-1135: Add support for GitHub repository environments - #62

Merged
dev-milos merged 22 commits into
mainfrom
gcss-1135--add-environment-with-deployment-policy
Jul 14, 2026
Merged

GCSS-1135: Add support for GitHub repository environments#62
dev-milos merged 22 commits into
mainfrom
gcss-1135--add-environment-with-deployment-policy

Conversation

@dev-milos

@dev-milos dev-milos commented Jul 9, 2026

Copy link
Copy Markdown
Collaborator

Summary

Adds support for managing GitHub repository environments (deployment protection rules, required reviewers, and deployment branch/tag policies) across the importer, the Terraform provisioning layer, the JSON schema, and the docs.

Continues the work from #28 (whose head lives on a fork we can't push to), rebased on top of current main with all conflicts resolved.

  • Closes G-Research/gr-oss#1135
  • Closes G-Research/gr-oss#1137

What changed

Importer (feature/github-repo-importer/)

  • Imports existing GitHub environments (protection rules, reviewers, deployment policies) into the generated YAML.
  • Gated behind an opt-in feature flag (default: disabled, backward compatible).

Terraform (feature/github-repo-provisioning/)

  • github_repository_environment, plus github_repository_environment_deployment_policy for branch and tag patterns.
  • These resources live in the vendored child module (modules/terraform-github-repository/), consistent with how every other per-repo sub-resource is already defined there (github_branch_protection, github_repository_collaborator, github_team_repository). The root module passes environments in and wires import blocks that address module.repository[...].github_repository_environment.environment[...].
  • Reviewer slugs/usernames are resolved to numeric IDs via data.github_team / data.github_user.

Feature flag

Enable environment import by setting a flat top-level key in config/import-config.yaml:

# import-config.yaml
feature_github_environment: true

(The flags are collected via a yaml:",inline" map[string]bool, so they are flat keys — not a nested features: block.)

YAML configuration structure

environments:
  - environment: production
    wait_timer: 300            # minutes (max 43200 = 30 days)
    can_admins_bypass: false
    prevent_self_review: true
    reviewers:
      users: ["octocat"]
      teams: ["platform-team"]   # team must already have repo access
    deployment_policy:
      policy_type: protected_branches   # or selected_branches_and_tags

  - environment: staging
    deployment_policy:
      policy_type: selected_branches_and_tags
      branch_patterns: ["main", "release/*"]
      tag_patterns: ["v*"]

  - environment: development
    # no deployment_policy = any branch can deploy

JSON schema

  • Environment / DeploymentPolicy structs carry jsonschema tags: environment required, wait_timer bounded 0..43200, policy_type restricted to the enum protected_branches | selected_branches_and_tags.
  • Regenerated .schemas/repository-config.schema.json so environments: is a recognized, validated property (under additionalProperties: false the block would otherwise be rejected at validation time).

Known limitations

  • Deployment policies require numeric policy IDs that can't be derived from YAML, so they are created fresh on first apply rather than imported; state converges on a second apply.
  • Max 6 combined users + teams as reviewers (GitHub API limit).
  • Reviewer teams must already have access to the repository.

References

ljuboops257 and others added 21 commits March 19, 2026 19:06
Co-authored-by: Ivan Pavlovic <ivan@gr-oss.io>
Co-authored-by: Ivan Pavlovic <ivan@gr-oss.io>
Co-authored-by: Ivan Pavlovic <ivan@gr-oss.io>
Co-authored-by: Ivan Pavlovic <ivan@gr-oss.io>
Co-authored-by: Ivan Pavlovic <ivan@gr-oss.io>
Resolve conflicts by keeping both sides:
- repositories.go: Environments + CustomProperties fields
- github.go: two-arg ImportRepo(name, cfg) signature + nilIfEmpty helper
- import.go: config-driven feature flags
- docs/workflows.md: kept main's version (PR deletion reverted)
- DEVELOPERS_GUIDE.md: kept custom_properties/high_integrity bullets
- Add jsonschema tags to Environment/DeploymentPolicy structs: environment
  required, wait_timer bounded 0-43200, policy_type enum
- Regenerate repository-config.schema.json so the environments block is a
  validated property (previously rejected under additionalProperties:false)
- Correct wait_timer unit from seconds to minutes in docs and TF examples
The graformer plan summarizer had no case for
github_repository_environment_deployment_policy, so those resources
rendered as 'unknown type'. Add a branch that shows repo/environment
and the branch or tag pattern.
- Move environment resources from the vendored module into the root module;
  revert modules/terraform-github-repository to upstream (vendored, untouched)
- Replace the inline feature-flag map with an explicit feature_github_environments
  bool in import-config (strict, explicitly (de)serialized)
- Fail the import when fetching environments errors (no partial imports);
  resolveEnvironments and fetchDeploymentPolicies now propagate errors, and
  unknown reviewer/policy types are rejected
- Drop dead code (top-level reviewer resolution + org lookup, map-cast fallback,
  unused module outputs, IsFeatureEnabled) and remove comments
- Scope cleanup: revert tf-apply and Justfile churn, delete ADDING_FEATURES.md
  and FEATURE_GITHUB_ENVIRONMENT.md, restore the DEVELOPERS_GUIDE High Integrity
  section, keep DEVELOPERS_GUIDE at repo root
GitHub caps required reviewers at 6 total across users and teams; fail the
import instead of producing config Terraform would later reject.
…view comments

Replace the hand-rolled deployment-branch-policies request (raw NewRequest/Do,
inline structs, and non-functional pagination that never advanced the page)
with the typed client.Repositories.ListDeploymentBranchPolicies. Restore the
two explanatory comments the reviewer asked to keep.
@dev-milos
dev-milos requested a review from pavlovic-ivan July 10, 2026 09:39
@dev-milos
dev-milos marked this pull request as ready for review July 10, 2026 09:39
- Deployment-policy import: importer now stores numeric policy IDs in hidden
  branch_policy_ids/tag_policy_ids maps (jsonschema:-), root module adds import
  blocks for branch_policy/tag_policy, promote yq strips the maps, and compare
  normalisation ignores them (mirrors the ruleset id lifecycle)
- fetchDeploymentPolicies: real pagination (per_page=100 + page advance),
  reusing the typed DeploymentBranchPolicyResponse
- Revert WriteRepositoryToYaml to yaml.Marshal (drop unrelated SetIndent(2))
- Reviewer teams stored by slug only (GetSlug), matching the rest of the code
- resolveEnvironments: switch on ProtectionRule type (wait_timer vs
  required_reviewers) to reflect GitHub's mutually-exclusive rule model

@pavlovic-ivan pavlovic-ivan 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.

LGTM

@dev-milos
dev-milos merged commit b8f6737 into main Jul 14, 2026
1 check passed
@dev-milos
dev-milos deleted the gcss-1135--add-environment-with-deployment-policy branch July 14, 2026 20:03
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

Successfully merging this pull request may close these issues.

4 participants