Skip to content

Commit

Permalink
SUP-1068 Migrate pipeline resource to framework (#345)
Browse files Browse the repository at this point in the history
* Add empty pipeline resource using framework

* Implement config, import and schema for pipeline

* Start implementing pipeline read

* Start using pipeline through interface

* Finish pipeline read

* Implement delete pipeline

* Implement remaining pipeline crud

* Some changes after running tests

* Add pipeline resource to provider

* Fix bug with tags

* Refactor pipeline REST requests

* WIP remove test

* Leave tags null if empty

* Fix some tests

* Some refactoring to pass tests

* Fix formatting

* Change test for pipeline disappearance

* Fix teams on update

* Fix case where pipeline is deleted outside terraform

* Deprecate deletion_protection

* Add changelog entry

* Add test against old provider version

* Formatting

* Test against cluster_id removal

* Add test condition for provider_settings

* Update tests to assert changed behaviour can be migrated

* Update test check

* Rename provider source

* Improvements from code review

* Try different source url

* Remove last test step

* Add plan modifications and validation

* Remove plan modifier for slug

* Save organization ID on test init

* Add tests for team functionality

* Remove extra test check

* Add custom logic for handling pipeline teams

* Revert "Add custom logic for handling pipeline teams"

This reverts commit 4d33867.

* Change maximum timeout in minutes to pointer
  • Loading branch information
jradtilbrook committed Aug 14, 2023
1 parent caa5fb7 commit cae1f3f
Show file tree
Hide file tree
Showing 11 changed files with 1,406 additions and 998 deletions.
10 changes: 6 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,9 @@
All notable changes to this project will be documented in this file.

## Unreleased
- refactor 🧹: Refactor templates to use Conventional Commits[[PR #348](https://github.com/buildkite/terraform-provider-buildkite/pull/348)] @mcncl

### Forthcoming Changes
`deletion_protection` is being deprecated and will be removed in a future release (`v1`). This feature offers similar
functionality to [lifecycles](https://developer.hashicorp.com/terraform/language/meta-arguments/lifecycle) which are supported by Terraform.
- SUP-1068 Migrate pipeline resource to framework [[PR #345](https://github.com/buildkite/terraform-provider-buildkite/pull/345)] @jradtilbrook
- refactor 🧹: Refactor templates to use Conventional Commits[[PR #348](https://github.com/buildkite/terraform-provider-buildkite/pull/348)] @mcncl

## [v0.23.0](https://github.com/buildkite/terraform-provider-buildkite/compare/v0.22.0...v0.23.0)

Expand All @@ -20,6 +18,10 @@ functionality to [lifecycles](https://developer.hashicorp.com/terraform/language

- Fixed a bug in `buildkite_test_suite` resources where `team_owner_id` could be set to the `access_level` instead @james2791 @jradtilbrook

### Forthcoming Changes
`deletion_protection` is being deprecated and will be removed in a future release (`v1`). This feature offers similar
functionality to [lifecycles](https://developer.hashicorp.com/terraform/language/meta-arguments/lifecycle) which are supported by Terraform.

## [v0.22.0](https://github.com/buildkite/terraform-provider-buildkite/compare/v0.21.2...v0.22.0)

### Added
Expand Down
702 changes: 425 additions & 277 deletions buildkite/generated.go

Large diffs are not rendered by default.

79 changes: 32 additions & 47 deletions buildkite/graphql/pipeline.graphql
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
fragment PipelineValues on Pipeline {
id
allowRebuilds
# @genqlient(pointer: true)
branchConfiguration
cancelIntermediateBuilds
cancelIntermediateBuildsBranchFilter
cluster {
# @genqlient(pointer: true)
id
}
defaultBranch
# @genqlient(pointer: true)
defaultTimeoutInMinutes
# @genqlient(pointer: true)
maximumTimeoutInMinutes
description
name
Expand Down Expand Up @@ -52,60 +56,18 @@ query getPipeline($slug: ID!) {
}
}

# @genqlient(for: "PipelineCreateInput.branchConfiguration", pointer: true)
# @genqlient(for: "PipelineCreateInput.clusterId", pointer: true)
# @genqlient(for: "PipelineCreateInput.visibility", omitempty: true)
# @genqlient(for: "PipelineCreateInput.pipelineTemplateId", omitempty: true)
# @genqlient(for: "PipelineCreateInput.nextBuildNumber", omitempty: true)
# @genqlient(for: "PipelineCreateInput.pipelineTemplateId", omitempty: true)
# @genqlient(for: "PipelineCreateInput.visibility", omitempty: true)
# @genqlient(for: "PipelineCreateInput.defaultTimeoutInMinutes", pointer: true)
mutation createPipeline(
$input: PipelineCreateInput!
) {
pipelineCreate(input: $input) {
pipeline {
id
allowRebuilds
branchConfiguration
cancelIntermediateBuilds
cancelIntermediateBuildsBranchFilter
cluster {
id
}
defaultBranch
defaultTimeoutInMinutes
maximumTimeoutInMinutes
description
name
repository {
url
}
skipIntermediateBuilds
skipIntermediateBuildsBranchFilter
slug
steps {
yaml
}
tags {
label
}
teams (first: 50) {
edges {
node {
accessLevel
id
team {
description
id
isDefaultTeam
defaultMemberRole
name
membersCanCreatePipelines
privacy
slug
uuid
}
}
}
}
webhookURL
...PipelineValues
}
}
}
Expand All @@ -116,6 +78,7 @@ mutation createPipeline(
# @genqlient(for: "PipelineUpdateInput.pipelineTemplateId", omitempty: true)
# @genqlient(for: "PipelineUpdateInput.archived", omitempty: true)
# @genqlient(for: "PipelineUpdateInput.nextBuildNumber", omitempty: true)
# @genqlient(for: "PipelineUpdateInput.defaultTimeoutInMinutes", pointer: true)
mutation updatePipeline(
$input: PipelineUpdateInput!
) {
Expand All @@ -126,6 +89,28 @@ mutation updatePipeline(
}
}

mutation teamPipelineCreate($teamId: ID!, $pipelineId: ID!, $accessLevel: PipelineAccessLevels) {
teamPipelineCreate(input: {teamID: $teamId, pipelineID: $pipelineId, accessLevel: $accessLevel}) {
teamPipeline {
id
}
}
}

mutation teamPipelineDelete($id: ID!) {
teamPipelineDelete(input: {id: $id}) {
deletedTeamPipelineID
}
}

mutation teamPipelineUpdate($id: ID!, $accessLevel: PipelineAccessLevels!) {
teamPipelineUpdate(input: {id: $id, accessLevel: $accessLevel}) {
teamPipeline {
id
}
}
}

mutation deletePipeline ($id: ID!) {
pipelineDelete(input: {
id: $id
Expand Down
2 changes: 1 addition & 1 deletion buildkite/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ func (*terraformProvider) Resources(context.Context) []func() resource.Resource
newClusterAgentTokenResource,
newClusterResource,
newOrganizationResource,
newPipelineResource,
newTeamMemberResource,
newTeamResource,
newTestSuiteResource,
Expand Down Expand Up @@ -144,7 +145,6 @@ func New(version string) provider.Provider {
func Provider(version string) *schema.Provider {
provider := &schema.Provider{
ResourcesMap: map[string]*schema.Resource{
"buildkite_pipeline": resourcePipeline(),
"buildkite_organization_settings": resourceOrganizationSettings(),
},
Schema: map[string]*schema.Schema{
Expand Down
40 changes: 2 additions & 38 deletions buildkite/provider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package buildkite

import (
"context"
"fmt"
"net/http"
"os"
"testing"
Expand All @@ -12,15 +11,13 @@ import (
"github.com/hashicorp/terraform-plugin-go/tfprotov6"
"github.com/hashicorp/terraform-plugin-mux/tf5to6server"
"github.com/hashicorp/terraform-plugin-mux/tf6muxserver"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
"github.com/shurcooL/graphql"
)

var graphqlClient *graphql.Client
var genqlientGraphql genqlient.Client
var organizationID string

func init() {
rt := http.DefaultTransport
Expand All @@ -35,6 +32,7 @@ func init() {

graphqlClient = graphql.NewClient(defaultGraphqlEndpoint, httpClient)
genqlientGraphql = genqlient.NewClient(defaultGraphqlEndpoint, httpClient)
organizationID, _ = GetOrganizationID(getenv("BUILDKITE_ORGANIZATION_SLUG"), graphqlClient)
}

func protoV6ProviderFactories() map[string]func() (tfprotov6.ProviderServer, error) {
Expand Down Expand Up @@ -81,37 +79,3 @@ func testAccPreCheck(t *testing.T) {
t.Fatal("BUILDKITE_API_TOKEN must be set for acceptance tests")
}
}

// testAccCheckResourceDisappears verifies the Provider has had the resource removed from state
func testAccCheckResourceDisappears(provider *schema.Provider, resource *schema.Resource, resourceName string) resource.TestCheckFunc {
return func(s *terraform.State) error {
resourceState, ok := s.RootModule().Resources[resourceName]

if !ok {
return fmt.Errorf("resource not found: %s", resourceName)
}

if resourceState.Primary.ID == "" {
return fmt.Errorf("resource ID missing: %s", resourceName)
}

if resource.DeleteContext != nil {
client := Client{
graphql: graphqlClient,
genqlient: genqlientGraphql,
organization: getenv("BUILDKITE_ORGANIZATION_SLUG"),
}
diags := resource.DeleteContext(context.Background(), resource.Data(resourceState.Primary), &client)

for i := range diags {
if diags[i].Severity == diag.Error {
return fmt.Errorf("error deleting resource: %s", diags[i].Summary)
}
}

return nil
}

return resource.Delete(resource.Data(resourceState.Primary), provider.Meta())
}
}
18 changes: 0 additions & 18 deletions buildkite/resource_organization_settings_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,24 +86,6 @@ func TestAccOrganizationSettings_import(t *testing.T) {
})
}

func TestAccOrganizationSettings_disappears(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProtoV6ProviderFactories: protoV6ProviderFactories(),
CheckDestroy: testCheckOrganizationSettingsResourceRemoved,
Steps: []resource.TestStep{
{
Config: testAccOrganizationSettingsConfigBasic([]string{"0.0.0.0/0", "1.1.1.1/32", "1.0.0.1/32"}),
Check: resource.ComposeAggregateTestCheckFunc(
// Confirm that the allowed IP addresses are set correctly in Buildkite's system
testAccCheckResourceDisappears(Provider("testing"), resourceOrganizationSettings(), "buildkite_organization_settings.let_them_in"),
),
ExpectNonEmptyPlan: true,
},
},
})
}

func testAccOrganizationSettingsConfigBasic(ip_addresses []string) string {
config := `
resource "buildkite_organization_settings" "let_them_in" {
Expand Down

0 comments on commit cae1f3f

Please sign in to comment.