Skip to content
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 71 additions & 11 deletions github/resource_github_repository_file.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,28 @@ func resourceGithubRepositoryFile() *schema.Resource {
StateContext: resourceGithubRepositoryFileImport,
},

SchemaVersion: 1,
StateUpgraders: []schema.StateUpgrader{
{
Type: resourceGithubRepositoryFileV0().CoreConfigSchema().ImpliedType(),
Upgrade: resourceGithubRepositoryFileStateUpgradeV0,
Version: 0,
},
},

Description: "This resource allows you to create and manage files within a GitHub repository.",

Schema: map[string]*schema.Schema{
"repository": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
Description: "The repository name",
},
"repository_id": {
Type: schema.TypeInt,
Computed: true,
Description: "The repository ID",
},
"file": {
Type: schema.TypeString,
Required: true,
Expand All @@ -47,6 +60,7 @@ func resourceGithubRepositoryFile() *schema.Resource {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Computed: true,
Description: "The branch name, defaults to the repository's default branch",
},
"ref": {
Expand Down Expand Up @@ -115,6 +129,7 @@ func resourceGithubRepositoryFile() *schema.Resource {
DiffSuppressFunc: autoBranchDiffSuppressFunc,
},
},
CustomizeDiff: diffRepository,
}
}

Expand Down Expand Up @@ -161,6 +176,8 @@ func resourceGithubRepositoryFileCreate(ctx context.Context, d *schema.ResourceD

checkOpt := github.RepositoryContentGetOptions{}

repoInfo, _, err := client.Repositories.Get(ctx, owner, repo)
Comment thread
deiga marked this conversation as resolved.

if branch, ok := d.GetOk("branch"); ok {
tflog.Debug(ctx, "Using explicitly set branch", map[string]any{
"branch": branch.(string),
Expand All @@ -175,6 +192,17 @@ func resourceGithubRepositoryFileCreate(ctx context.Context, d *schema.ResourceD
}
}
checkOpt.Ref = branch.(string)
} else {
if err != nil {
return diag.FromErr(err)
}
Comment thread
deiga marked this conversation as resolved.
Outdated
if err := d.Set("branch", repoInfo.GetDefaultBranch()); err != nil {
return diag.FromErr(err)
}
Comment thread
deiga marked this conversation as resolved.
Outdated
}

if err := d.Set("repository_id", int(repoInfo.GetID())); err != nil {
return diag.FromErr(err)
}
Comment thread
deiga marked this conversation as resolved.
Outdated

opts := resourceGithubRepositoryFileOptions(d)
Expand Down Expand Up @@ -215,7 +243,13 @@ func resourceGithubRepositoryFileCreate(ctx context.Context, d *schema.ResourceD
return diag.FromErr(err)
}

d.SetId(fmt.Sprintf("%s/%s", repo, file))
branch := d.Get("branch").(string)
Comment thread
deiga marked this conversation as resolved.
Outdated

newResourceID, err := buildID(repo, file, branch)
if err != nil {
return diag.FromErr(err)
}
d.SetId(newResourceID)
if err = d.Set("commit_sha", create.GetSHA()); err != nil {
return diag.FromErr(err)
}
Expand All @@ -227,7 +261,11 @@ func resourceGithubRepositoryFileRead(ctx context.Context, d *schema.ResourceDat
client := meta.(*Owner).v3client
owner := meta.(*Owner).name

repo, file := splitRepoFilePath(d.Id())
repo, file, _, err := parseID3(d.Id())
if err != nil {
return diag.FromErr(err)
}
Comment thread
deiga marked this conversation as resolved.
Outdated

ctx = tflog.SetField(ctx, "repository", repo)
ctx = tflog.SetField(ctx, "file", file)
ctx = tflog.SetField(ctx, "owner", owner)
Expand Down Expand Up @@ -427,28 +465,50 @@ func autoBranchDiffSuppressFunc(k, _, _ string, d *schema.ResourceData) bool {
}

func resourceGithubRepositoryFileImport(ctx context.Context, d *schema.ResourceData, meta any) ([]*schema.ResourceData, error) {
repoFilePath, branch, err := parseID2(d.Id())
repo, filePath, branch, err := parseID3(d.Id())
if err != nil {
return nil, fmt.Errorf("invalid ID specified. Supplied ID must be written as <repository>/<file path>:<branch>. %w", err)
return nil, fmt.Errorf("invalid ID specified. Supplied ID must be written as <repository>:<file path>: (when branch is default) or <repository>:<file path>:<branch>. %w", err)
}

client := meta.(*Owner).v3client
owner := meta.(*Owner).name
repo, file := splitRepoFilePath(repoFilePath)

opts := &github.RepositoryContentGetOptions{Ref: branch}
if err := d.Set("branch", branch); err != nil {
opts := &github.RepositoryContentGetOptions{}

repoInfo, _, err := client.Repositories.Get(ctx, owner, repo)
Comment thread
deiga marked this conversation as resolved.
if branch != "" {
opts.Ref = branch
if err := d.Set("branch", branch); err != nil {
return nil, err
}
} else {

if err != nil {
return nil, err
}
defaultBranch := repoInfo.GetDefaultBranch()
branch = defaultBranch
if err := d.Set("branch", branch); err != nil {
return nil, err
}
}
if err := d.Set("repository_id", int(repoInfo.GetID())); err != nil {
return nil, err
}
fc, _, _, err := client.Repositories.GetContents(ctx, owner, repo, file, opts)

fc, _, _, err := client.Repositories.GetContents(ctx, owner, repo, filePath, opts)
if err != nil {
return nil, err
}
if fc == nil {
return nil, fmt.Errorf("file %s is not a file in repository %s/%s or repository is not readable", file, owner, repo)
return nil, fmt.Errorf("filePath %s is not a file in repository %s/%s or repository is not readable", filePath, owner, repo)
}

d.SetId(fmt.Sprintf("%s/%s", repo, file))
newResourceID, err := buildID(repo, filePath, branch)
if err != nil {
return nil, err
}
d.SetId(newResourceID)
if err = d.Set("overwrite_on_create", false); err != nil {
return nil, err
}
Expand Down
123 changes: 123 additions & 0 deletions github/resource_github_repository_file_migration.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
package github

import (
"context"
"fmt"

"github.com/hashicorp/terraform-plugin-log/tflog"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

func resourceGithubRepositoryFileV0() *schema.Resource {
return &schema.Resource{
Schema: map[string]*schema.Schema{
"repository": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"file": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"content": {
Type: schema.TypeString,
Required: true,
},
"branch": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
},
"ref": {
Type: schema.TypeString,
Computed: true,
ForceNew: true,
},
"commit_sha": {
Type: schema.TypeString,
Computed: true,
},
"commit_message": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"commit_author": {
Type: schema.TypeString,
Optional: true,
RequiredWith: []string{"commit_email"},
},
"commit_email": {
Type: schema.TypeString,
Optional: true,
RequiredWith: []string{"commit_author"},
},
"sha": {
Type: schema.TypeString,
Computed: true,
},
"overwrite_on_create": {
Type: schema.TypeBool,
Optional: true,
Default: false,
},
"autocreate_branch": {
Type: schema.TypeBool,
Optional: true,
Default: false,
},
"autocreate_branch_source_branch": {
Type: schema.TypeString,
Default: "main",
Optional: true,
RequiredWith: []string{"autocreate_branch"},
},
"autocreate_branch_source_sha": {
Type: schema.TypeString,
Optional: true,
Computed: true,
RequiredWith: []string{"autocreate_branch"},
},
},
}
}

func resourceGithubRepositoryFileStateUpgradeV0(ctx context.Context, rawState map[string]any, m any) (map[string]any, error) {
tflog.Debug(ctx, "GitHub Repository File State before migration", map[string]any{
"rawState": rawState,
})

meta := m.(*Owner)
client := meta.v3client
owner := meta.name

repoName, ok := rawState["repository"].(string)
if !ok {
return nil, fmt.Errorf("repository not found or is not a string")
}

repo, _, err := client.Repositories.Get(ctx, owner, repoName)
if err != nil {
return nil, fmt.Errorf("failed to retrieve repository '%s': %w", repoName, err)
}

rawState["repository_id"] = int(repo.GetID())

// If branch is missing or empty, fetch the default branch from the repository
if branch, ok := rawState["branch"].(string); !ok || branch == "" {
rawState["branch"] = repo.GetDefaultBranch()
}

newResourceID, err := buildID(rawState["repository"].(string), rawState["file"].(string), rawState["branch"].(string))
if err != nil {
return nil, fmt.Errorf("failed to build ID: %w", err)
}
rawState["id"] = newResourceID

tflog.Debug(ctx, "GitHub Repository File State after migration", map[string]any{
"rawState": rawState,
})
return rawState, nil
}
Loading
Loading