diff --git a/docs/resources/repository_cron.md b/docs/resources/repository_cron.md new file mode 100644 index 0000000..b7970d1 --- /dev/null +++ b/docs/resources/repository_cron.md @@ -0,0 +1,54 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "woodpecker_repository_cron Resource - terraform-provider-woodpecker" +subcategory: "" +description: |- + This resource allows you to add/remove cron jobs. When applied, a new cron job will be created. When destroyed, that cron job will be removed. For more information see the Woodpecker docs https://woodpecker-ci.org/docs/usage/cron. +--- + +# woodpecker_repository_cron (Resource) + +This resource allows you to add/remove cron jobs. When applied, a new cron job will be created. When destroyed, that cron job will be removed. For more information see [the Woodpecker docs](https://woodpecker-ci.org/docs/usage/cron). + +## Example Usage + +```terraform +resource "woodpecker_repository" "test_repo" { + full_name = "Kichiyaki/test-repo" + is_trusted = true + visibility = "public" +} + +resource "woodpecker_repository_cron" "test" { + repository_id = woodpecker_repository.test_repo.id + name = "test" + schedule = "@daily" +} +``` + + +## Schema + +### Required + +- `name` (String) the name of the cron job +- `repository_id` (Number) the ID of the repository +- `schedule` (String) [cron expression](https://pkg.go.dev/github.com/robfig/cron#hdr-CRON_Expression_Format) + +### Optional + +- `branch` (String) the name of the branch (uses default branch if empty) + +### Read-Only + +- `created_at` (Number) date the cron job was created +- `creator_id` (Number) id of user who created the cron job +- `id` (Number) the id of the cron job + +## Import + +Import is supported using the following syntax: + +```shell +terraform import woodpecker_repository_cron.test "/" +``` diff --git a/examples/resources/woodpecker_repository_cron/import.sh b/examples/resources/woodpecker_repository_cron/import.sh new file mode 100644 index 0000000..6aa8412 --- /dev/null +++ b/examples/resources/woodpecker_repository_cron/import.sh @@ -0,0 +1 @@ +terraform import woodpecker_repository_cron.test "/" diff --git a/examples/resources/woodpecker_repository_cron/resource.tf b/examples/resources/woodpecker_repository_cron/resource.tf new file mode 100644 index 0000000..044ed76 --- /dev/null +++ b/examples/resources/woodpecker_repository_cron/resource.tf @@ -0,0 +1,11 @@ +resource "woodpecker_repository" "test_repo" { + full_name = "Kichiyaki/test-repo" + is_trusted = true + visibility = "public" +} + +resource "woodpecker_repository_cron" "test" { + repository_id = woodpecker_repository.test_repo.id + name = "test" + schedule = "@daily" +} diff --git a/internal/models.go b/internal/models.go index 4535a89..c5ebdd4 100644 --- a/internal/models.go +++ b/internal/models.go @@ -217,3 +217,36 @@ func (m *repositorySecretDataSourceModel) setValues(ctx context.Context, secret return diagsRes } + +type repositoryCronModel struct { + ID types.Int64 `tfsdk:"id"` + Name types.String `tfsdk:"name"` + RepositoryID types.Int64 `tfsdk:"repository_id"` + CreatorID types.Int64 `tfsdk:"creator_id"` + Schedule types.String `tfsdk:"schedule"` + CreatedAt types.Int64 `tfsdk:"created_at"` + Branch types.String `tfsdk:"branch"` +} + +func (m *repositoryCronModel) setValues(_ context.Context, cron *woodpecker.Cron) diag.Diagnostics { + m.ID = types.Int64Value(cron.ID) + m.Name = types.StringValue(cron.Name) + m.RepositoryID = types.Int64Value(cron.RepoID) + m.CreatorID = types.Int64Value(cron.CreatorID) + m.Schedule = types.StringValue(cron.Schedule) + m.CreatedAt = types.Int64Value(cron.Created) + m.Branch = types.StringValue(cron.Branch) + return nil +} + +func (m *repositoryCronModel) toWoodpeckerModel(_ context.Context) (*woodpecker.Cron, diag.Diagnostics) { + return &woodpecker.Cron{ + ID: m.ID.ValueInt64(), + Name: m.Name.ValueString(), + RepoID: m.RepositoryID.ValueInt64(), + CreatorID: m.CreatorID.ValueInt64(), + Schedule: m.Schedule.ValueString(), + Created: m.CreatedAt.ValueInt64(), + Branch: m.Branch.ValueString(), + }, nil +} diff --git a/internal/provider.go b/internal/provider.go index 4c4b044..adaa699 100644 --- a/internal/provider.go +++ b/internal/provider.go @@ -13,6 +13,8 @@ import ( "golang.org/x/oauth2" ) +const importStateIDSeparator = "/" + type woodpeckerProvider struct { version string } @@ -67,6 +69,7 @@ func (p *woodpeckerProvider) Resources(_ context.Context) []func() resource.Reso newSecretResource, newRepositoryResource, newRepositorySecretResource, + newRepositoryCronResource, } } diff --git a/internal/resource_repository_cron.go b/internal/resource_repository_cron.go new file mode 100644 index 0000000..f73323e --- /dev/null +++ b/internal/resource_repository_cron.go @@ -0,0 +1,225 @@ +package internal + +import ( + "context" + "fmt" + "strconv" + "strings" + + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/hashicorp/terraform-plugin-framework/resource/schema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64planmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" + "github.com/woodpecker-ci/woodpecker/woodpecker-go/woodpecker" +) + +type repositoryCronResource struct { + client woodpecker.Client +} + +var _ resource.Resource = (*repositoryCronResource)(nil) +var _ resource.ResourceWithConfigure = (*repositoryCronResource)(nil) +var _ resource.ResourceWithImportState = (*repositoryCronResource)(nil) + +func newRepositoryCronResource() resource.Resource { + return &repositoryCronResource{} +} + +func (r *repositoryCronResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { + resp.TypeName = req.ProviderTypeName + "_repository_cron" +} + +func (r *repositoryCronResource) Schema(_ context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) { + resp.Schema = schema.Schema{ + MarkdownDescription: "This resource allows you to add/remove cron jobs." + + " When applied, a new cron job will be created." + + " When destroyed, that cron job will be removed." + + " For more information see [the Woodpecker docs](https://woodpecker-ci.org/docs/usage/cron).", + Attributes: map[string]schema.Attribute{ + "id": schema.Int64Attribute{ + Computed: true, + Description: "the id of the cron job", + PlanModifiers: []planmodifier.Int64{ + int64planmodifier.UseStateForUnknown(), + }, + }, + "repository_id": schema.Int64Attribute{ + Required: true, + Description: "the ID of the repository", + PlanModifiers: []planmodifier.Int64{ + int64planmodifier.RequiresReplace(), + }, + }, + "name": schema.StringAttribute{ + Required: true, + Description: "the name of the cron job", + }, + "schedule": schema.StringAttribute{ + Required: true, + MarkdownDescription: "[cron expression](https://pkg.go.dev/github.com/robfig/cron#hdr-CRON_Expression_Format)", + }, + "branch": schema.StringAttribute{ + Computed: true, + Optional: true, + Description: "the name of the branch (uses default branch if empty)", + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + }, + "creator_id": schema.Int64Attribute{ + Computed: true, + Description: "id of user who created the cron job", + PlanModifiers: []planmodifier.Int64{ + int64planmodifier.UseStateForUnknown(), + }, + }, + "created_at": schema.Int64Attribute{ + Computed: true, + Description: "date the cron job was created", + PlanModifiers: []planmodifier.Int64{ + int64planmodifier.UseStateForUnknown(), + }, + }, + }, + } +} + +func (r *repositoryCronResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { + // Prevent panic if the provider has not been configured. + if req.ProviderData == nil { + return + } + + client, ok := req.ProviderData.(woodpecker.Client) + if !ok { + resp.Diagnostics.AddError( + "Unexpected Data Source Configure Type", + fmt.Sprintf("Expected woodpecker.Client, got: %T. Please report this issue to the provider developers.", req.ProviderData), + ) + return + } + + r.client = client +} + +func (r *repositoryCronResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { + var data repositoryCronModel + + resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) + if resp.Diagnostics.HasError() { + return + } + + wData, diags := data.toWoodpeckerModel(ctx) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + cron, err := r.client.CronCreate(data.RepositoryID.ValueInt64(), wData) + if err != nil { + resp.Diagnostics.AddError("Couldn't create cron job", err.Error()) + return + } + + resp.Diagnostics.Append(data.setValues(ctx, cron)...) + if resp.Diagnostics.HasError() { + return + } + + resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) +} + +func (r *repositoryCronResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { + var data repositoryCronModel + + resp.Diagnostics.Append(req.State.Get(ctx, &data)...) + if resp.Diagnostics.HasError() { + return + } + + cron, err := r.client.CronGet(data.RepositoryID.ValueInt64(), data.ID.ValueInt64()) + if err != nil { + resp.Diagnostics.AddError("Couldn't get cron job", err.Error()) + } + + resp.Diagnostics.Append(data.setValues(ctx, cron)...) + if resp.Diagnostics.HasError() { + return + } + + resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) +} + +func (r *repositoryCronResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { + var data repositoryCronModel + + resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) + if resp.Diagnostics.HasError() { + return + } + + wData, diags := data.toWoodpeckerModel(ctx) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + cron, err := r.client.CronUpdate(data.RepositoryID.ValueInt64(), wData) + if err != nil { + resp.Diagnostics.AddError("Couldn't update cron job", err.Error()) + return + } + + resp.Diagnostics.Append(data.setValues(ctx, cron)...) + if resp.Diagnostics.HasError() { + return + } + + resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) +} + +func (r *repositoryCronResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { + var data repositoryCronModel + + resp.Diagnostics.Append(req.State.Get(ctx, &data)...) + if resp.Diagnostics.HasError() { + return + } + + if err := r.client.CronDelete(data.RepositoryID.ValueInt64(), data.ID.ValueInt64()); err != nil { + resp.Diagnostics.AddError("Couldn't delete cron job", err.Error()) + return + } + + resp.State.RemoveResource(ctx) +} + +func (r *repositoryCronResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { + idParts := strings.Split(req.ID, importStateIDSeparator) + + if len(idParts) != 2 || idParts[0] == "" || idParts[1] == "" { + resp.Diagnostics.AddError( + "Unexpected Import Identifier", + fmt.Sprintf("Expected import identifier with format: repository_id/id. Got: %q", req.ID), + ) + return + } + + repoID, err := strconv.ParseInt(idParts[0], 10, 64) + if err != nil { + resp.Diagnostics.AddError("Invalid repository id", err.Error()) + return + } + + id, err := strconv.ParseInt(idParts[1], 10, 64) + if err != nil { + resp.Diagnostics.AddError("Invalid cron id", err.Error()) + return + } + + resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("repository_id"), repoID)...) + resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("id"), id)...) +} diff --git a/internal/resource_repository_cron_test.go b/internal/resource_repository_cron_test.go new file mode 100644 index 0000000..b5b217c --- /dev/null +++ b/internal/resource_repository_cron_test.go @@ -0,0 +1,140 @@ +package internal_test + +import ( + "errors" + "fmt" + "slices" + "strconv" + "testing" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/plancheck" + "github.com/hashicorp/terraform-plugin-testing/terraform" + "github.com/woodpecker-ci/woodpecker/woodpecker-go/woodpecker" +) + +func TestRepositoryCronResource(t *testing.T) { + t.Parallel() + + giteaRepo := createRepo(t) + repo := activateRepo(t, giteaRepo) + branch := createBranch(t, giteaRepo) + newRepo := activateRepo(t, createRepo(t)) + + name := uuid.NewString() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, + CheckDestroy: checkRepositoryCronResourceDestroy(map[int64][]string{ + repo.ID: {name}, + newRepo.ID: {name}, + }), + Steps: []resource.TestStep{ + { // create cron + Config: fmt.Sprintf(` +resource "woodpecker_repository_cron" "test_cron" { + repository_id = %d + name = "%s" + schedule = "@daily" +} +`, repo.ID, name), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttrSet("woodpecker_repository_cron.test_cron", "id"), + resource.TestCheckResourceAttr("woodpecker_repository_cron.test_cron", "repository_id", strconv.FormatInt(repo.ID, 10)), + resource.TestCheckResourceAttr("woodpecker_repository_cron.test_cron", "name", name), + resource.TestCheckResourceAttr("woodpecker_repository_cron.test_cron", "schedule", "@daily"), + resource.TestCheckResourceAttr("woodpecker_repository_cron.test_cron", "branch", ""), + resource.TestCheckResourceAttrSet("woodpecker_repository_cron.test_cron", "created_at"), + resource.TestCheckResourceAttrSet("woodpecker_repository_cron.test_cron", "creator_id"), + ), + }, + { // update cron + Config: fmt.Sprintf(` +resource "woodpecker_repository_cron" "test_cron" { + repository_id = %d + name = "%s" + schedule = "@every 5m" + branch = "%s" +} +`, repo.ID, name, branch.Name), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttrSet("woodpecker_repository_cron.test_cron", "id"), + resource.TestCheckResourceAttr("woodpecker_repository_cron.test_cron", "repository_id", strconv.FormatInt(repo.ID, 10)), + resource.TestCheckResourceAttr("woodpecker_repository_cron.test_cron", "name", name), + resource.TestCheckResourceAttr("woodpecker_repository_cron.test_cron", "schedule", "@every 5m"), + resource.TestCheckResourceAttr("woodpecker_repository_cron.test_cron", "branch", branch.Name), + resource.TestCheckResourceAttrSet("woodpecker_repository_cron.test_cron", "created_at"), + resource.TestCheckResourceAttrSet("woodpecker_repository_cron.test_cron", "creator_id"), + ), + }, + { // update cron + Config: fmt.Sprintf(` +resource "woodpecker_repository_cron" "test_cron" { + repository_id = %d + name = "%s" + schedule = "@daily" +} +//`, repo.ID, name), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttrSet("woodpecker_repository_cron.test_cron", "id"), + resource.TestCheckResourceAttr("woodpecker_repository_cron.test_cron", "repository_id", strconv.FormatInt(repo.ID, 10)), + resource.TestCheckResourceAttr("woodpecker_repository_cron.test_cron", "name", name), + resource.TestCheckResourceAttr("woodpecker_repository_cron.test_cron", "schedule", "@daily"), + resource.TestCheckResourceAttr("woodpecker_repository_cron.test_cron", "branch", branch.Name), + resource.TestCheckResourceAttrSet("woodpecker_repository_cron.test_cron", "created_at"), + resource.TestCheckResourceAttrSet("woodpecker_repository_cron.test_cron", "creator_id"), + ), + }, + { // import + ResourceName: "woodpecker_repository_cron.test_cron", + ImportState: true, + ImportStateIdPrefix: strconv.FormatInt(repo.ID, 10) + "/", + ImportStateVerify: true, + }, + { // replace cron + Config: fmt.Sprintf(` +resource "woodpecker_repository_cron" "test_cron" { + repository_id = %d + name = "%s" + schedule = "@daily" +} +`, newRepo.ID, name), + ConfigPlanChecks: resource.ConfigPlanChecks{ + PreApply: []plancheck.PlanCheck{ + plancheck.ExpectResourceAction("woodpecker_repository_cron.test_cron", plancheck.ResourceActionReplace), + }, + }, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttrSet("woodpecker_repository_cron.test_cron", "id"), + resource.TestCheckResourceAttr("woodpecker_repository_cron.test_cron", "repository_id", strconv.FormatInt(newRepo.ID, 10)), + resource.TestCheckResourceAttr("woodpecker_repository_cron.test_cron", "name", name), + resource.TestCheckResourceAttr("woodpecker_repository_cron.test_cron", "schedule", "@daily"), + resource.TestCheckResourceAttr("woodpecker_repository_cron.test_cron", "branch", ""), + resource.TestCheckResourceAttrSet("woodpecker_repository_cron.test_cron", "created_at"), + resource.TestCheckResourceAttrSet("woodpecker_repository_cron.test_cron", "creator_id"), + ), + }, + }, + }) +} + +func checkRepositoryCronResourceDestroy(m map[int64][]string) func(state *terraform.State) error { + return func(state *terraform.State) error { + for repoID, names := range m { + crons, err := woodpeckerClient.CronList(repoID) + if err != nil { + return fmt.Errorf("couldn't list cron jobs: %w", err) + } + + if slices.ContainsFunc(crons, func(cron *woodpecker.Cron) bool { + return slices.Contains(names, cron.Name) + }) { + return errors.New("at least one of the created cron jobs isn't deleted") + } + } + + return nil + } +} diff --git a/internal/resource_repository_secret.go b/internal/resource_repository_secret.go index 139ca33..628e402 100644 --- a/internal/resource_repository_secret.go +++ b/internal/resource_repository_secret.go @@ -219,7 +219,7 @@ func (r *repositorySecretResource) Delete(ctx context.Context, req resource.Dele } func (r *repositorySecretResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - idParts := strings.Split(req.ID, "/") + idParts := strings.Split(req.ID, importStateIDSeparator) if len(idParts) != 2 || idParts[0] == "" || idParts[1] == "" { resp.Diagnostics.AddError( diff --git a/internal/resource_repository_secret_test.go b/internal/resource_repository_secret_test.go index ae235cd..15b2494 100644 --- a/internal/resource_repository_secret_test.go +++ b/internal/resource_repository_secret_test.go @@ -22,6 +22,7 @@ func TestRepositorySecretResource(t *testing.T) { t.Parallel() repo := activateRepo(t, createRepo(t)) + newRepo := activateRepo(t, createRepo(t)) name := uuid.NewString() newName := uuid.NewString() @@ -29,7 +30,10 @@ func TestRepositorySecretResource(t *testing.T) { resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, - CheckDestroy: checkRepositorySecretResourceDestroy(repo.ID, name, newName), + CheckDestroy: checkRepositorySecretResourceDestroy(map[int64][]string{ + repo.ID: {name, newName}, + newRepo.ID: {name, newName}, + }), Steps: []resource.TestStep{ { // create secret Config: fmt.Sprintf(` @@ -99,7 +103,7 @@ resource "woodpecker_repository_secret" "test_secret" { ImportStateVerify: true, ImportStateVerifyIgnore: []string{"value"}, }, - { // replace secret + { // replace secret (new name) Config: fmt.Sprintf(` resource "woodpecker_repository_secret" "test_secret" { repository_id = %d @@ -122,6 +126,29 @@ resource "woodpecker_repository_secret" "test_secret" { resource.TestCheckResourceAttr("woodpecker_repository_secret.test_secret", "plugins_only", "false"), ), }, + { // replace secret (new repo id) + Config: fmt.Sprintf(` +resource "woodpecker_repository_secret" "test_secret" { + repository_id = %d + name = "%s" + value = "test123New" + events = ["push"] +} +`, newRepo.ID, newName), + ConfigPlanChecks: resource.ConfigPlanChecks{ + PreApply: []plancheck.PlanCheck{ + plancheck.ExpectResourceAction("woodpecker_repository_secret.test_secret", plancheck.ResourceActionReplace), + }, + }, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttrSet("woodpecker_repository_secret.test_secret", "id"), + resource.TestCheckResourceAttr("woodpecker_repository_secret.test_secret", "repository_id", strconv.FormatInt(newRepo.ID, 10)), + resource.TestCheckResourceAttr("woodpecker_repository_secret.test_secret", "name", newName), + resource.TestCheckResourceAttr("woodpecker_repository_secret.test_secret", "value", "test123New"), + resource.TestCheckTypeSetElemAttr("woodpecker_repository_secret.test_secret", "events.*", "push"), + resource.TestCheckResourceAttr("woodpecker_repository_secret.test_secret", "plugins_only", "false"), + ), + }, }, }) }) @@ -149,17 +176,19 @@ resource "woodpecker_repository_secret" "test_secret" { }) } -func checkRepositorySecretResourceDestroy(repoID int64, names ...string) func(state *terraform.State) error { +func checkRepositorySecretResourceDestroy(m map[int64][]string) func(state *terraform.State) error { return func(state *terraform.State) error { - secrets, err := woodpeckerClient.SecretList(repoID) - if err != nil { - return fmt.Errorf("couldn't list secrets: %w", err) - } + for repoID, names := range m { + secrets, err := woodpeckerClient.SecretList(repoID) + if err != nil { + return fmt.Errorf("couldn't list secrets: %w", err) + } - if slices.ContainsFunc(secrets, func(secret *woodpecker.Secret) bool { - return slices.Contains(names, secret.Name) - }) { - return errors.New("at least one of the created secrets isn't deleted") + if slices.ContainsFunc(secrets, func(secret *woodpecker.Secret) bool { + return slices.Contains(names, secret.Name) + }) { + return errors.New("at least one of the created secrets isn't deleted") + } } return nil diff --git a/internal/resource_repository_test.go b/internal/resource_repository_test.go index 53d16ca..4e4d2c8 100644 --- a/internal/resource_repository_test.go +++ b/internal/resource_repository_test.go @@ -8,7 +8,6 @@ import ( "strconv" "testing" - "code.gitea.io/sdk/gitea" "github.com/google/uuid" "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/plancheck" @@ -213,40 +212,3 @@ func checkRepositoryResourceDestroy(names ...string) func(state *terraform.State return nil } } - -func createRepo(tb testing.TB) *gitea.Repository { - tb.Helper() - - repo, _, err := giteaClient.CreateRepo(gitea.CreateRepoOption{ - Name: uuid.NewString(), - Description: uuid.NewString(), - Private: false, - AutoInit: true, - Template: false, - License: "MIT", - Readme: "Default", - DefaultBranch: "master", - }) - if err != nil { - tb.Fatalf("got unexpected error while creating repo: %s", err) - } - tb.Cleanup(func() { - _, _ = giteaClient.DeleteRepo(repo.Owner.UserName, repo.Name) - }) - - return repo -} - -func activateRepo(tb testing.TB, giteaRepo *gitea.Repository) *woodpecker.Repo { - tb.Helper() - - repo, err := woodpeckerClient.RepoPost(giteaRepo.ID) - if err != nil { - tb.Fatalf("got unexpected error while activating repo: %s", err) - } - tb.Cleanup(func() { - _ = woodpeckerClient.RepoDel(repo.ID) - }) - - return repo -} diff --git a/internal/utils_test.go b/internal/utils_test.go new file mode 100644 index 0000000..36c2f03 --- /dev/null +++ b/internal/utils_test.go @@ -0,0 +1,59 @@ +package internal_test + +import ( + "testing" + + "code.gitea.io/sdk/gitea" + "github.com/google/uuid" + "github.com/woodpecker-ci/woodpecker/woodpecker-go/woodpecker" +) + +func createRepo(tb testing.TB) *gitea.Repository { + tb.Helper() + + repo, _, err := giteaClient.CreateRepo(gitea.CreateRepoOption{ + Name: uuid.NewString(), + Description: uuid.NewString(), + Private: false, + AutoInit: true, + Template: false, + License: "MIT", + Readme: "Default", + DefaultBranch: "master", + }) + if err != nil { + tb.Fatalf("got unexpected error while creating repo: %s", err) + } + tb.Cleanup(func() { + _, _ = giteaClient.DeleteRepo(repo.Owner.UserName, repo.Name) + }) + + return repo +} + +func createBranch(tb testing.TB, repo *gitea.Repository) *gitea.Branch { + tb.Helper() + + branch, _, err := giteaClient.CreateBranch(repo.Owner.UserName, repo.Name, gitea.CreateBranchOption{ + BranchName: uuid.NewString(), + }) + if err != nil { + tb.Fatalf("got unexpected error while creating branch: %s", err) + } + + return branch +} + +func activateRepo(tb testing.TB, giteaRepo *gitea.Repository) *woodpecker.Repo { + tb.Helper() + + repo, err := woodpeckerClient.RepoPost(giteaRepo.ID) + if err != nil { + tb.Fatalf("got unexpected error while activating repo: %s", err) + } + tb.Cleanup(func() { + _ = woodpeckerClient.RepoDel(repo.ID) + }) + + return repo +}