Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
5 changes: 3 additions & 2 deletions github/data_source_github_repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -241,8 +241,9 @@ func dataSourceGithubRepository() *schema.Resource {
},
},
"pages": {
Type: schema.TypeList,
Computed: true,
Type: schema.TypeList,
Computed: true,
Deprecated: "Use the github_repository_pages data source instead. This field will be removed in a future version.",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"source": {
Expand Down
156 changes: 156 additions & 0 deletions github/data_source_github_repository_pages.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
package github

import (
"context"
"net/http"
"strconv"

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

func dataSourceGithubRepositoryPages() *schema.Resource {
return &schema.Resource{
Description: "Use this data source to retrieve GitHub Pages configuration for a repository.",
ReadContext: dataSourceGithubRepositoryPagesRead,

Schema: map[string]*schema.Schema{
"repository": {
Type: schema.TypeString,
Required: true,
Description: "The repository name to get GitHub Pages information for.",
},
// TODO: Uncomment this when we are ready to support owner fields properly. https://github.com/integrations/terraform-provider-github/pull/3166#discussion_r2816053082
// "owner": {
// Type: schema.TypeString,
// Required: true,
// Description: "The owner of the repository.",
// },
"source": {
Type: schema.TypeList,
Computed: true,
Description: "The source branch and directory for the rendered Pages site.",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"branch": {
Type: schema.TypeString,
Computed: true,
Description: "The repository branch used to publish the site's source files.",
},
"path": {
Type: schema.TypeString,
Computed: true,
Description: "The repository directory from which the site publishes.",
},
},
},
},
"build_type": {
Type: schema.TypeString,
Computed: true,
Description: "The type of GitHub Pages site. Can be 'legacy' or 'workflow'.",
},
"cname": {
Type: schema.TypeString,
Computed: true,
Description: "The custom domain for the repository.",
},
"custom_404": {
Type: schema.TypeBool,
Computed: true,
Description: "Whether the rendered GitHub Pages site has a custom 404 page.",
},
"html_url": {
Type: schema.TypeString,
Computed: true,
Description: "The absolute URL (with scheme) to the rendered GitHub Pages site.",
},
"build_status": {
Type: schema.TypeString,
Computed: true,
Description: "The GitHub Pages site's build status e.g. 'building' or 'built'.",
},
"api_url": {
Type: schema.TypeString,
Computed: true,
Description: "The API URL of the GitHub Pages resource.",
},
"public": {
Type: schema.TypeBool,
Computed: true,
Description: "Whether the GitHub Pages site is publicly visible. If set to `true`, the site is accessible to anyone on the internet. If set to `false`, the site will only be accessible to users who have at least `read` access to the repository that published the site.",
},
"https_enforced": {
Type: schema.TypeBool,
Computed: true,
Description: "Whether the rendered GitHub Pages site will only be served over HTTPS.",
},
},
}
}

func dataSourceGithubRepositoryPagesRead(ctx context.Context, d *schema.ResourceData, m any) diag.Diagnostics {
meta := m.(*Owner)
client := meta.v3client

owner := meta.name // TODO: Add owner support // d.Get("owner").(string)
repoName := d.Get("repository").(string)

pages, resp, err := client.Repositories.GetPagesInfo(ctx, owner, repoName)
if err != nil {
if resp != nil && resp.StatusCode == http.StatusNotFound {
return diag.Errorf("GitHub Pages not found for repository %s/%s", owner, repoName)
}
return diag.Errorf("error reading repository pages: %s", err.Error())
}

repo, _, err := client.Repositories.Get(ctx, owner, repoName)
if err != nil {
return diag.FromErr(err)
}

d.SetId(strconv.Itoa(int(repo.GetID())))

if err := d.Set("build_type", pages.GetBuildType()); err != nil {
return diag.FromErr(err)
}
if err := d.Set("cname", pages.GetCNAME()); err != nil {
return diag.FromErr(err)
}
if err := d.Set("custom_404", pages.GetCustom404()); err != nil {
return diag.FromErr(err)
}
if err := d.Set("html_url", pages.GetHTMLURL()); err != nil {
return diag.FromErr(err)
}
if err := d.Set("build_status", pages.GetStatus()); err != nil {
return diag.FromErr(err)
}
if err := d.Set("api_url", pages.GetURL()); err != nil {
return diag.FromErr(err)
}
if err := d.Set("public", pages.GetPublic()); err != nil {
return diag.FromErr(err)
}
if err := d.Set("https_enforced", pages.GetHTTPSEnforced()); err != nil {
return diag.FromErr(err)
}
// Set source only for legacy build type
if pages.GetBuildType() == "legacy" && pages.GetSource() != nil {
source := []map[string]any{
{
"branch": pages.GetSource().GetBranch(),
"path": pages.GetSource().GetPath(),
},
}
if err := d.Set("source", source); err != nil {
return diag.FromErr(err)
}
} else {
if err := d.Set("source", []map[string]any{}); err != nil {
return diag.FromErr(err)
}
}

return nil
}
122 changes: 122 additions & 0 deletions github/data_source_github_repository_pages_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
package github

import (
"fmt"
"testing"

"github.com/hashicorp/terraform-plugin-testing/compare"
"github.com/hashicorp/terraform-plugin-testing/helper/acctest"
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
"github.com/hashicorp/terraform-plugin-testing/knownvalue"
"github.com/hashicorp/terraform-plugin-testing/statecheck"
"github.com/hashicorp/terraform-plugin-testing/tfjsonpath"
)

func TestAccGithubRepositoryPagesDataSource(t *testing.T) {
baseRepoVisibility := "public"
if testAccConf.authMode == enterprise {
baseRepoVisibility = "private"
}

t.Run("reads_pages_configuration", func(t *testing.T) {
randomID := acctest.RandString(5)
repoName := fmt.Sprintf("%spages-ds-%s", testResourcePrefix, randomID)

config := fmt.Sprintf(`
resource "github_repository" "test" {
name = "%s"
visibility = "%s"
auto_init = true
}

resource "github_repository_pages" "test" {
repository = github_repository.test.name
build_type = "legacy"
source {
branch = "main"
path = "/"
}
}

data "github_repository_pages" "test" {
repository = github_repository.test.name

depends_on = [github_repository_pages.test]
}
`, repoName, baseRepoVisibility)

resource.Test(t, resource.TestCase{
PreCheck: func() {
skipUnauthenticated(t)
},
ProviderFactories: providerFactories,
Steps: []resource.TestStep{
{
Config: config,
ConfigStateChecks: []statecheck.StateCheck{
statecheck.CompareValuePairs("data.github_repository_pages.test", tfjsonpath.New("build_type"), "github_repository_pages.test", tfjsonpath.New("build_type"), compare.ValuesSame()),
statecheck.CompareValuePairs("data.github_repository_pages.test", tfjsonpath.New("source").AtSliceIndex(0).AtMapKey("branch"), "github_repository_pages.test", tfjsonpath.New("source").AtSliceIndex(0).AtMapKey("branch"), compare.ValuesSame()),
statecheck.CompareValuePairs("data.github_repository_pages.test", tfjsonpath.New("source").AtSliceIndex(0).AtMapKey("path"), "github_repository_pages.test", tfjsonpath.New("source").AtSliceIndex(0).AtMapKey("path"), compare.ValuesSame()),
statecheck.CompareValuePairs("data.github_repository_pages.test", tfjsonpath.New("cname"), "github_repository_pages.test", tfjsonpath.New("cname"), compare.ValuesSame()),
statecheck.CompareValuePairs("data.github_repository_pages.test", tfjsonpath.New("custom_404"), "github_repository_pages.test", tfjsonpath.New("custom_404"), compare.ValuesSame()),
statecheck.CompareValuePairs("data.github_repository_pages.test", tfjsonpath.New("html_url"), "github_repository_pages.test", tfjsonpath.New("html_url"), compare.ValuesSame()),
statecheck.ExpectKnownValue("data.github_repository_pages.test", tfjsonpath.New("build_status"), knownvalue.NotNull()),
statecheck.CompareValuePairs("data.github_repository_pages.test", tfjsonpath.New("api_url"), "github_repository_pages.test", tfjsonpath.New("api_url"), compare.ValuesSame()),
statecheck.ExpectKnownValue("data.github_repository_pages.test", tfjsonpath.New("public"), knownvalue.Bool(testAccConf.authMode != enterprise)),
statecheck.CompareValuePairs("data.github_repository_pages.test", tfjsonpath.New("https_enforced"), "github_repository_pages.test", tfjsonpath.New("https_enforced"), compare.ValuesSame()),
},
},
},
})
})
t.Run("reads_pages_enterprise_configuration", func(t *testing.T) {
randomID := acctest.RandString(5)
repoName := fmt.Sprintf("%spages-ds-%s", testResourcePrefix, randomID)

config := fmt.Sprintf(`
resource "github_repository" "test" {
name = "%s"
visibility = "%s"
auto_init = true
}

resource "github_repository_pages" "test" {
repository = github_repository.test.name
build_type = "legacy"
source {
branch = "main"
path = "/"
}
public = false
}

data "github_repository_pages" "test" {
repository = github_repository.test.name

depends_on = [github_repository_pages.test]
}
`, repoName, baseRepoVisibility)

resource.Test(t, resource.TestCase{
PreCheck: func() { skipUnlessEnterprise(t) },
ProviderFactories: providerFactories,
Steps: []resource.TestStep{
{
Config: config,
ConfigStateChecks: []statecheck.StateCheck{
statecheck.CompareValuePairs("data.github_repository_pages.test", tfjsonpath.New("build_type"), "github_repository_pages.test", tfjsonpath.New("build_type"), compare.ValuesSame()),
statecheck.CompareValuePairs("data.github_repository_pages.test", tfjsonpath.New("source").AtSliceIndex(0).AtMapKey("branch"), "github_repository_pages.test", tfjsonpath.New("source").AtSliceIndex(0).AtMapKey("branch"), compare.ValuesSame()),
statecheck.CompareValuePairs("data.github_repository_pages.test", tfjsonpath.New("source").AtSliceIndex(0).AtMapKey("path"), "github_repository_pages.test", tfjsonpath.New("source").AtSliceIndex(0).AtMapKey("path"), compare.ValuesSame()),
statecheck.CompareValuePairs("data.github_repository_pages.test", tfjsonpath.New("cname"), "github_repository_pages.test", tfjsonpath.New("cname"), compare.ValuesSame()),
statecheck.CompareValuePairs("data.github_repository_pages.test", tfjsonpath.New("custom_404"), "github_repository_pages.test", tfjsonpath.New("custom_404"), compare.ValuesSame()),
statecheck.CompareValuePairs("data.github_repository_pages.test", tfjsonpath.New("html_url"), "github_repository_pages.test", tfjsonpath.New("html_url"), compare.ValuesSame()),
statecheck.ExpectKnownValue("data.github_repository_pages.test", tfjsonpath.New("build_status"), knownvalue.NotNull()),
statecheck.CompareValuePairs("data.github_repository_pages.test", tfjsonpath.New("api_url"), "github_repository_pages.test", tfjsonpath.New("api_url"), compare.ValuesSame()),
statecheck.CompareValuePairs("data.github_repository_pages.test", tfjsonpath.New("public"), "github_repository_pages.test", tfjsonpath.New("public"), compare.ValuesSame()),
statecheck.CompareValuePairs("data.github_repository_pages.test", tfjsonpath.New("https_enforced"), "github_repository_pages.test", tfjsonpath.New("https_enforced"), compare.ValuesSame()),
},
},
},
})
})
}
2 changes: 2 additions & 0 deletions github/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ func Provider() *schema.Provider {
"github_repository_environment_deployment_policy": resourceGithubRepositoryEnvironmentDeploymentPolicy(),
"github_repository_file": resourceGithubRepositoryFile(),
"github_repository_milestone": resourceGithubRepositoryMilestone(),
"github_repository_pages": resourceGithubRepositoryPages(),
"github_repository_project": resourceGithubRepositoryProject(),
"github_repository_pull_request": resourceGithubRepositoryPullRequest(),
"github_repository_ruleset": resourceGithubRepositoryRuleset(),
Expand Down Expand Up @@ -282,6 +283,7 @@ func Provider() *schema.Provider {
"github_repository_deployment_branch_policies": dataSourceGithubRepositoryDeploymentBranchPolicies(),
"github_repository_file": dataSourceGithubRepositoryFile(),
"github_repository_milestone": dataSourceGithubRepositoryMilestone(),
"github_repository_pages": dataSourceGithubRepositoryPages(),
"github_repository_pull_request": dataSourceGithubRepositoryPullRequest(),
"github_repository_pull_requests": dataSourceGithubRepositoryPullRequests(),
"github_repository_teams": dataSourceGithubRepositoryTeams(),
Expand Down
4 changes: 3 additions & 1 deletion github/resource_github_repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,7 @@ func resourceGithubRepository() *schema.Resource {
MaxItems: 1,
Optional: true,
Description: "The repository's GitHub Pages configuration",
Deprecated: "Use the github_repository_pages resource instead. This field will be removed in a future version.",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"source": {
Expand Down Expand Up @@ -859,7 +860,8 @@ func resourceGithubRepositoryRead(ctx context.Context, d *schema.ResourceData, m
_ = d.Set("squash_merge_commit_title", repo.GetSquashMergeCommitTitle())
}

if repo.GetHasPages() {
_, isPagesConfigured := d.GetOk("pages")
if repo.GetHasPages() && isPagesConfigured {
pages, _, err := client.Repositories.GetPagesInfo(ctx, owner, repoName)
if err != nil {
return diag.FromErr(err)
Expand Down
Loading