Skip to content

feat(core): add fork functionality #2674

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

Closed
wants to merge 15 commits into from
Closed

Conversation

hminaee-tc
Copy link

@hminaee-tc hminaee-tc commented May 30, 2025

Resolves

#2632


Before the change?

  • Forking repos using terraform is not possible

After the change?

I've added support for forking GitHub repositories to the GitHub Terraform Provider. This feature allows users to fork existing repositories using Terraform, supporting both user and organization accounts.

Key Implementations:

  1. Fork Parameters: Added schema attributes for repository forking:

    • fork: Boolean flag to enable forking
    • source_owner: Owner of the repository to fork from
    • source_repo: Name of the repository to fork from
  2. Fork Creation Logic: Implemented forking in the resourceGithubRepositoryCreate function:

  • Added a new branch to the existing conditional structure to handle forks
  • Supports custom repository naming via the name attribute
  • Properly handles organization-owned forks by setting the organization parameter
  1. Asynchronous Fork Handling: Added support for GitHub's asynchronous fork creation:
  • Properly handles the 202 Accepted response
  • Includes error logging and validation of returned data
  1. State Management: Set repository attributes in Terraform state:
  • Repository name, full name, and various URL formats
  • All critical attributes needed for Terraform to track the resource
  1. Fork Information Reading: Enhanced resourceGithubRepositoryRead to read fork status:
  • Detects when a repository is a fork
  • Sets the source repository information in state
  • Properly clears fork information for non-forked repositories

Here are few tests/show case for different aspect of the above changes

  • Forking the repos successfully works
    creating fork and also fork from fork:
terraform {
  required_providers {
    github = {
      source  = "integrations/github"
    }
  }
}

provider "github" {
  owner = "TucowsTCX"  # Your organization
  token = "ghp_xxxxx"
}

# Test forking a repository
resource "github_repository" "forked_repo" {
  name         = "test-fork-terraform"
  description  = "Test fork functionality with custom provider"
  fork         = true
  source_owner = "TucowsTCX" 
  source_repo  = "test-deleted"
}

# Second fork (forking from the first fork using a reference)
resource "github_repository" "second_fork" {
  name         = "test-fork-terraform-second"
  description  = "Second fork created from the first fork"
  fork         = true
  source_owner = "TucowsTCX" 
  # Reference the name attribute of the first fork
  source_repo  = github_repository.forked_repo.name
  
  depends_on = [github_repository.forked_repo]
}

Note you can also use : export GITHUB_TOKEN="gh_xxx"

terraform init

terraform init    

Initializing the backend...

Initializing provider plugins...
- Reusing previous version of integrations/github from the dependency lock file
- Using previously-installed integrations/github v6.6.0

╷
│ Warning: Provider development overrides are in effect
│ 
│ The following provider development overrides are set in the CLI configuration:
│  - integrations/github in /Users/hamed/Desktop/tucows-code/terra-providor-extended/terraform-provider-github
│ 
│ Skip terraform init when using provider development overrides. It is not necessary
│ and may error unexpectedly.
╵

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.

terraform plan

here is the plan result:

opencpk#1 (comment)

terraform apply

here is the apply result:

opencpk#1 (comment)

Also importing existing resources :

Now lets say we forked a repo manually and now we need to import it in terraform so it is being tracked

first fork a repo called manual-test

import {
  # The provider-specific resource address
  to = github_repository.test_import
  
  # The existing resource identifier 
  id = "hamed-test"
}

# Resource to import an existing forked repository
resource "github_repository" "test_import" {
  name = "hamed-test"
  # Minimal configuration only - import will fill in the rest
}

And the result shows
opencpk#1 (comment)

verify the import:

opencpk#1 (comment)

Now time to destroy it which means it should also be able to destroy manually created fork


terraform destroy
╷
│ Warning: Provider development overrides are in effect
│ 
│ The following provider development overrides are set in the CLI configuration:
│  - integrations/github in /Users/hamed/Desktop/tucows-code/terra-providor-extended/terraform-provider-github
│ 
│ The behavior may therefore not match any released version of the provider and
│ applying changes may cause the state to become incompatible with published
│ releases.
╵
github_repository.forked_repo: Refreshing state... [id=test-fork-terraform]
github_repository.second_fork: Refreshing state... [id=test-fork-terraform-second]

Terraform used the selected providers to generate the following execution plan.
Resource actions are indicated with the following symbols:
  - destroy

Terraform will perform the following actions:

  # github_repository.forked_repo will be destroyed
  - resource "github_repository" "forked_repo" {
      - allow_auto_merge            = false -> null
      - allow_merge_commit          = true -> null
      - allow_rebase_merge          = true -> null
      - allow_squash_merge          = true -> null
      - allow_update_branch         = false -> null
      - archived                    = false -> null
      - default_branch              = "main" -> null
      - delete_branch_on_merge      = false -> null
      - description                 = "UPDATED: Test fork functionality with custom provider" -> null
      - etag                        = "W/\"9ad77049741f2d57f3dcfb1f19a44cff0287228118b99de9b7e63af2cf3b6f97\"" -> null
      - fork                        = true -> null
      - full_name                   = "TucowsTCX/test-fork-terraform" -> null
      - git_clone_url               = "git://github.com/TucowsTCX/test-fork-terraform.git" -> null
      - has_discussions             = false -> null
      - has_downloads               = false -> null
      - has_issues                  = false -> null
      - has_projects                = false -> null
      - has_wiki                    = false -> null
      - homepage_url                = "https://example.com" -> null
      - html_url                    = "https://github.com/TucowsTCX/test-fork-terraform" -> null
      - http_clone_url              = "https://github.com/TucowsTCX/test-fork-terraform.git" -> null
      - id                          = "test-fork-terraform" -> null
      - is_template                 = false -> null
      - merge_commit_message        = "PR_TITLE" -> null
      - merge_commit_title          = "MERGE_MESSAGE" -> null
      - name                        = "test-fork-terraform" -> null
      - node_id                     = "R_kgDOOtfkKw" -> null
      - private                     = false -> null
      - repo_id                     = 987227179 -> null
      - source_owner                = "TucowsTCX" -> null
      - source_repo                 = "test-deleted" -> null
      - squash_merge_commit_message = "COMMIT_MESSAGES" -> null
      - squash_merge_commit_title   = "COMMIT_OR_PR_TITLE" -> null
      - ssh_clone_url               = "[email protected]:TucowsTCX/test-fork-terraform.git" -> null
      - svn_url                     = "https://github.com/TucowsTCX/test-fork-terraform" -> null
      - topics                      = [] -> null
      - visibility                  = "public" -> null
      - vulnerability_alerts        = false -> null
      - web_commit_signoff_required = false -> null

      - security_and_analysis {
          - secret_scanning {
              - status = "disabled" -> null
            }
          - secret_scanning_push_protection {
              - status = "disabled" -> null
            }
        }
    }

  # github_repository.second_fork will be destroyed
  - resource "github_repository" "second_fork" {
      - allow_auto_merge            = false -> null
      - allow_merge_commit          = true -> null
      - allow_rebase_merge          = true -> null
      - allow_squash_merge          = true -> null
      - allow_update_branch         = false -> null
      - archived                    = false -> null
      - default_branch              = "main" -> null
      - delete_branch_on_merge      = false -> null
      - description                 = "Second fork created from the first fork" -> null
      - etag                        = "W/\"7e1c2db83427f2f42371d7532deb87f1126e31e86f0d12ae4b1c8f4d0e1a3fde\"" -> null
      - fork                        = true -> null
      - full_name                   = "TucowsTCX/test-fork-terraform-second" -> null
      - git_clone_url               = "git://github.com/TucowsTCX/test-fork-terraform-second.git" -> null
      - has_discussions             = false -> null
      - has_downloads               = false -> null
      - has_issues                  = false -> null
      - has_projects                = false -> null
      - has_wiki                    = false -> null
      - html_url                    = "https://github.com/TucowsTCX/test-fork-terraform-second" -> null
      - http_clone_url              = "https://github.com/TucowsTCX/test-fork-terraform-second.git" -> null
      - id                          = "test-fork-terraform-second" -> null
      - is_template                 = false -> null
      - merge_commit_message        = "PR_TITLE" -> null
      - merge_commit_title          = "MERGE_MESSAGE" -> null
      - name                        = "test-fork-terraform-second" -> null
      - node_id                     = "R_kgDOOtfkTQ" -> null
      - private                     = false -> null
      - repo_id                     = 987227213 -> null
      - source_owner                = "TucowsTCX" -> null
      - source_repo                 = "test-fork-terraform" -> null
      - squash_merge_commit_message = "COMMIT_MESSAGES" -> null
      - squash_merge_commit_title   = "COMMIT_OR_PR_TITLE" -> null
      - ssh_clone_url               = "[email protected]:TucowsTCX/test-fork-terraform-second.git" -> null
      - svn_url                     = "https://github.com/TucowsTCX/test-fork-terraform-second" -> null
      - topics                      = [] -> null
      - visibility                  = "public" -> null
      - vulnerability_alerts        = false -> null
      - web_commit_signoff_required = false -> null

      - security_and_analysis {
          - secret_scanning {
              - status = "disabled" -> null
            }
          - secret_scanning_push_protection {
              - status = "disabled" -> null
            }
        }
    }

Plan: 0 to add, 0 to change, 2 to destroy.

Changes to Outputs:
  - fork_full_name        = "TucowsTCX/test-fork-terraform" -> null
  - fork_name             = "test-fork-terraform" -> null
  - fork_url              = "https://github.com/TucowsTCX/test-fork-terraform" -> null
  - second_fork_full_name = "TucowsTCX/test-fork-terraform-second" -> null
  - second_fork_name      = "test-fork-terraform-second" -> null
  - second_fork_url       = "https://github.com/TucowsTCX/test-fork-terraform-second" -> null

Do you really want to destroy all resources?
  Terraform will destroy all your managed infrastructure, as shown above.
  There is no undo. Only 'yes' will be accepted to confirm.

  Enter a value: yes

github_repository.second_fork: Destroying... [id=test-fork-terraform-second]
github_repository.second_fork: Destruction complete after 0s
github_repository.forked_repo: Destroying... [id=test-fork-terraform]
github_repository.forked_repo: Destruction complete after 2s

Destroy complete! Resources: 2 destroyed.

Pull request checklist

  • 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

@hminaee-tc hminaee-tc changed the title feat(adding fork functionality): Adding fork functionality feat(core): add fork functionality May 30, 2025
@aouellet-tc
Copy link

+1 this feature request addition

@nickfloyd nickfloyd moved this from 🆕 Triage to 👀 In review in 🧰 Octokit Active Jun 3, 2025
@hminaee-tc
Copy link
Author

#2678
created the above PR instead which address the issue

@hminaee-tc hminaee-tc closed this Jun 4, 2025
@github-project-automation github-project-automation bot moved this from 👀 In review to ✅ Done in 🧰 Octokit Active Jun 4, 2025
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.

2 participants