Skip to content

Commit bd9f729

Browse files
feat: Add github_actions_organization_permissions data source to provider
1 parent 7024b09 commit bd9f729

6 files changed

Lines changed: 331 additions & 0 deletions

File tree

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
---
2+
page_title: "github_actions_organization_permissions (Data Source) - GitHub"
3+
description: |-
4+
Get GitHub Actions permissions for an organization
5+
---
6+
7+
# github_actions_organization_permissions (Data Source)
8+
9+
Use this data source to retrieve the GitHub Actions permissions for an organization, including which actions are allowed and which repositories are enabled.
10+
11+
## Example Usage
12+
13+
```terraform
14+
data "github_actions_organization_permissions" "example" {
15+
}
16+
```
17+
18+
## Argument Reference
19+
20+
No arguments are required. The organization is determined by the provider configuration.
21+
22+
## Attributes Reference
23+
24+
- `allowed_actions` - The permissions policy that controls the actions that are allowed to run. Can be one of: `all`, `local_only`, or `selected`.
25+
- `enabled_repositories` - The policy that controls the repositories in the organization that are allowed to run GitHub Actions. Can be one of: `all`, `none`, or `selected`.
26+
- `allowed_actions_config` - (Set when `allowed_actions` is `selected`) The actions that are allowed in the organization.
27+
- `github_owned_allowed` - Whether GitHub-owned actions are allowed in the organization.
28+
- `patterns_allowed` - Specifies a list of string-matching patterns to allow specific action(s).
29+
- `verified_allowed` - Whether actions in GitHub Marketplace from verified creators are allowed.
30+
- `enabled_repositories_config` - (Set when `enabled_repositories` is `selected`) The list of selected repositories enabled for GitHub Actions.
31+
- `repository_ids` - List of repository IDs enabled for GitHub Actions.
32+
- `sha_pinning_required` - Whether pinning to a specific SHA is required for all actions and reusable workflows in an organization.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
data "github_actions_organization_permissions" "example" {
2+
}
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
package github
2+
3+
import (
4+
"context"
5+
6+
"github.com/google/go-github/v88/github"
7+
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
8+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
9+
)
10+
11+
func dataSourceGithubActionsOrganizationPermissions() *schema.Resource {
12+
return &schema.Resource{
13+
ReadContext: dataSourceGithubActionsOrganizationPermissionsRead,
14+
15+
Schema: map[string]*schema.Schema{
16+
"allowed_actions": {
17+
Type: schema.TypeString,
18+
Computed: true,
19+
Description: "The permissions policy that controls the actions that are allowed to run. Can be one of: 'all', 'local_only', or 'selected'.",
20+
},
21+
"enabled_repositories": {
22+
Type: schema.TypeString,
23+
Computed: true,
24+
Description: "The policy that controls the repositories in the organization that are allowed to run GitHub Actions. Can be one of: 'all', 'none', or 'selected'.",
25+
},
26+
"allowed_actions_config": {
27+
Type: schema.TypeList,
28+
Computed: true,
29+
Description: "The actions that are allowed in the organization when 'allowed_actions' is 'selected'.",
30+
Elem: &schema.Resource{
31+
Schema: map[string]*schema.Schema{
32+
"github_owned_allowed": {
33+
Type: schema.TypeBool,
34+
Computed: true,
35+
Description: "Whether GitHub-owned actions are allowed in the organization.",
36+
},
37+
"patterns_allowed": {
38+
Type: schema.TypeSet,
39+
Computed: true,
40+
Description: "Specifies a list of string-matching patterns to allow specific action(s). Wildcards, tags, and SHAs are allowed.",
41+
Elem: &schema.Schema{Type: schema.TypeString},
42+
},
43+
"verified_allowed": {
44+
Type: schema.TypeBool,
45+
Computed: true,
46+
Description: "Whether actions in GitHub Marketplace from verified creators are allowed.",
47+
},
48+
},
49+
},
50+
},
51+
"enabled_repositories_config": {
52+
Type: schema.TypeList,
53+
Computed: true,
54+
Description: "The list of selected repositories that are enabled for GitHub Actions when 'enabled_repositories' is 'selected'.",
55+
Elem: &schema.Resource{
56+
Schema: map[string]*schema.Schema{
57+
"repository_ids": {
58+
Type: schema.TypeSet,
59+
Computed: true,
60+
Description: "List of repository IDs enabled for GitHub Actions.",
61+
Elem: &schema.Schema{Type: schema.TypeInt},
62+
},
63+
},
64+
},
65+
},
66+
"sha_pinning_required": {
67+
Type: schema.TypeBool,
68+
Computed: true,
69+
Description: "Whether pinning to a specific SHA is required for all actions and reusable workflows in an organization.",
70+
},
71+
},
72+
}
73+
}
74+
75+
func dataSourceGithubActionsOrganizationPermissionsRead(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics {
76+
err := checkOrganization(meta)
77+
if err != nil {
78+
return diag.FromErr(err)
79+
}
80+
81+
client := meta.(*Owner).v3client
82+
owner := meta.(*Owner).name
83+
84+
actionsPermissions, _, err := client.Actions.GetActionsPermissions(ctx, owner)
85+
if err != nil {
86+
return diag.FromErr(err)
87+
}
88+
89+
if actionsPermissions.GetAllowedActions() == "selected" {
90+
actionsAllowed, _, err := client.Actions.GetActionsAllowed(ctx, owner)
91+
if err != nil {
92+
return diag.FromErr(err)
93+
}
94+
95+
if actionsAllowed != nil {
96+
if err = d.Set("allowed_actions_config", []any{
97+
map[string]any{
98+
"github_owned_allowed": actionsAllowed.GetGithubOwnedAllowed(),
99+
"patterns_allowed": actionsAllowed.PatternsAllowed,
100+
"verified_allowed": actionsAllowed.GetVerifiedAllowed(),
101+
},
102+
}); err != nil {
103+
return diag.FromErr(err)
104+
}
105+
}
106+
}
107+
108+
if actionsPermissions.GetEnabledRepositories() == "selected" {
109+
opts := github.ListOptions{PerPage: 10, Page: 1}
110+
var repoList []int64
111+
var allRepos []*github.Repository
112+
113+
for {
114+
enabledRepos, resp, err := client.Actions.ListEnabledReposInOrg(ctx, owner, &opts)
115+
if err != nil {
116+
return diag.FromErr(err)
117+
}
118+
allRepos = append(allRepos, enabledRepos.Repositories...)
119+
opts.Page = resp.NextPage
120+
if resp.NextPage == 0 {
121+
break
122+
}
123+
}
124+
125+
for _, repo := range allRepos {
126+
repoList = append(repoList, *repo.ID)
127+
}
128+
129+
if allRepos != nil {
130+
if err = d.Set("enabled_repositories_config", []any{
131+
map[string]any{
132+
"repository_ids": repoList,
133+
},
134+
}); err != nil {
135+
return diag.FromErr(err)
136+
}
137+
}
138+
}
139+
140+
if err = d.Set("allowed_actions", actionsPermissions.GetAllowedActions()); err != nil {
141+
return diag.FromErr(err)
142+
}
143+
if err = d.Set("enabled_repositories", actionsPermissions.GetEnabledRepositories()); err != nil {
144+
return diag.FromErr(err)
145+
}
146+
if err = d.Set("sha_pinning_required", actionsPermissions.GetSHAPinningRequired()); err != nil {
147+
return diag.FromErr(err)
148+
}
149+
150+
d.SetId(owner)
151+
return nil
152+
}
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
package github
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
7+
"github.com/hashicorp/terraform-plugin-testing/helper/acctest"
8+
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
9+
"github.com/hashicorp/terraform-plugin-testing/knownvalue"
10+
"github.com/hashicorp/terraform-plugin-testing/statecheck"
11+
"github.com/hashicorp/terraform-plugin-testing/tfjsonpath"
12+
)
13+
14+
func TestAccGithubActionsOrganizationPermissionsDataSource(t *testing.T) {
15+
t.Run("reads organization permissions without error", func(t *testing.T) {
16+
config := `
17+
resource "github_actions_organization_permissions" "test" {
18+
allowed_actions = "local_only"
19+
enabled_repositories = "all"
20+
}
21+
22+
data "github_actions_organization_permissions" "test" {
23+
depends_on = [github_actions_organization_permissions.test]
24+
}
25+
`
26+
27+
resource.Test(t, resource.TestCase{
28+
PreCheck: func() { skipUnlessHasOrgs(t) },
29+
ProviderFactories: providerFactories,
30+
Steps: []resource.TestStep{
31+
{
32+
Config: config,
33+
ConfigStateChecks: []statecheck.StateCheck{
34+
statecheck.ExpectKnownValue(
35+
"data.github_actions_organization_permissions.test",
36+
tfjsonpath.New("allowed_actions"),
37+
knownvalue.StringExact("local_only"),
38+
),
39+
statecheck.ExpectKnownValue(
40+
"data.github_actions_organization_permissions.test",
41+
tfjsonpath.New("enabled_repositories"),
42+
knownvalue.StringExact("all"),
43+
),
44+
},
45+
},
46+
},
47+
})
48+
})
49+
50+
t.Run("reads selected repository and action permissions", func(t *testing.T) {
51+
randomID := acctest.RandStringFromCharSet(5, acctest.CharSetAlphaNum)
52+
repoName := fmt.Sprintf("%srepo-act-org-perm-ds-%s", testResourcePrefix, randomID)
53+
54+
config := fmt.Sprintf(`
55+
resource "github_repository" "test" {
56+
name = "%[1]s"
57+
description = "Terraform acceptance tests %[1]s"
58+
}
59+
60+
resource "github_actions_organization_permissions" "test" {
61+
allowed_actions = "selected"
62+
enabled_repositories = "selected"
63+
allowed_actions_config {
64+
github_owned_allowed = true
65+
verified_allowed = true
66+
patterns_allowed = ["actions/cache@*", "actions/checkout@*"]
67+
}
68+
enabled_repositories_config {
69+
repository_ids = [github_repository.test.repo_id]
70+
}
71+
}
72+
73+
data "github_actions_organization_permissions" "test" {
74+
depends_on = [github_actions_organization_permissions.test]
75+
}
76+
`, repoName)
77+
78+
resource.Test(t, resource.TestCase{
79+
PreCheck: func() { skipUnlessHasOrgs(t) },
80+
ProviderFactories: providerFactories,
81+
Steps: []resource.TestStep{
82+
{
83+
Config: config,
84+
ConfigStateChecks: []statecheck.StateCheck{
85+
statecheck.ExpectKnownValue(
86+
"data.github_actions_organization_permissions.test",
87+
tfjsonpath.New("allowed_actions"),
88+
knownvalue.StringExact("selected"),
89+
),
90+
statecheck.ExpectKnownValue(
91+
"data.github_actions_organization_permissions.test",
92+
tfjsonpath.New("enabled_repositories"),
93+
knownvalue.StringExact("selected"),
94+
),
95+
statecheck.ExpectKnownValue(
96+
"data.github_actions_organization_permissions.test",
97+
tfjsonpath.New("allowed_actions_config").AtSliceIndex(0).AtMapKey("github_owned_allowed"),
98+
knownvalue.Bool(true),
99+
),
100+
statecheck.ExpectKnownValue(
101+
"data.github_actions_organization_permissions.test",
102+
tfjsonpath.New("allowed_actions_config").AtSliceIndex(0).AtMapKey("verified_allowed"),
103+
knownvalue.Bool(true),
104+
),
105+
statecheck.ExpectKnownValue(
106+
"data.github_actions_organization_permissions.test",
107+
tfjsonpath.New("enabled_repositories_config").AtSliceIndex(0).AtMapKey("repository_ids"),
108+
knownvalue.SetSizeExact(1),
109+
),
110+
},
111+
},
112+
},
113+
})
114+
})
115+
}

github/provider.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,7 @@ func NewProvider() func() *schema.Provider {
224224
"github_actions_environment_secrets": dataSourceGithubActionsEnvironmentSecrets(),
225225
"github_actions_environment_variables": dataSourceGithubActionsEnvironmentVariables(),
226226
"github_actions_organization_oidc_subject_claim_customization_template": dataSourceGithubActionsOrganizationOIDCSubjectClaimCustomizationTemplate(),
227+
"github_actions_organization_permissions": dataSourceGithubActionsOrganizationPermissions(),
227228
"github_actions_organization_public_key": dataSourceGithubActionsOrganizationPublicKey(),
228229
"github_actions_organization_registration_token": dataSourceGithubActionsOrganizationRegistrationToken(),
229230
"github_actions_organization_secrets": dataSourceGithubActionsOrganizationSecrets(),
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
---
2+
page_title: "{{.Name}} ({{.Type}}) - {{.RenderedProviderName}}"
3+
description: |-
4+
Get GitHub Actions permissions for an organization
5+
---
6+
7+
# {{.Name}} ({{.Type}})
8+
9+
Use this data source to retrieve the GitHub Actions permissions for an organization, including which actions are allowed and which repositories are enabled.
10+
11+
## Example Usage
12+
13+
{{ tffile "examples/data-sources/actions_organization_permissions/data-source.tf" }}
14+
15+
## Argument Reference
16+
17+
No arguments are required. The organization is determined by the provider configuration.
18+
19+
## Attributes Reference
20+
21+
- `allowed_actions` - The permissions policy that controls the actions that are allowed to run. Can be one of: `all`, `local_only`, or `selected`.
22+
- `enabled_repositories` - The policy that controls the repositories in the organization that are allowed to run GitHub Actions. Can be one of: `all`, `none`, or `selected`.
23+
- `allowed_actions_config` - (Set when `allowed_actions` is `selected`) The actions that are allowed in the organization.
24+
- `github_owned_allowed` - Whether GitHub-owned actions are allowed in the organization.
25+
- `patterns_allowed` - Specifies a list of string-matching patterns to allow specific action(s).
26+
- `verified_allowed` - Whether actions in GitHub Marketplace from verified creators are allowed.
27+
- `enabled_repositories_config` - (Set when `enabled_repositories` is `selected`) The list of selected repositories enabled for GitHub Actions.
28+
- `repository_ids` - List of repository IDs enabled for GitHub Actions.
29+
- `sha_pinning_required` - Whether pinning to a specific SHA is required for all actions and reusable workflows in an organization.

0 commit comments

Comments
 (0)