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
4 changes: 4 additions & 0 deletions cmd/vendor/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"github.com/cloudposse/atmos/pkg/ci"
cfg "github.com/cloudposse/atmos/pkg/config"
"github.com/cloudposse/atmos/pkg/flags"
_ "github.com/cloudposse/atmos/pkg/git/providers/azuredevops"
_ "github.com/cloudposse/atmos/pkg/git/providers/cli"
_ "github.com/cloudposse/atmos/pkg/git/providers/github"
"github.com/cloudposse/atmos/pkg/perf"
Expand Down Expand Up @@ -295,6 +296,9 @@ func vendorPullRequestConfig(v *viper.Viper) schema.VendorPullRequestConfig {
Draft: v.GetBool("vendor.ci.pull_request.draft"),
Reviewers: v.GetStringSlice("vendor.ci.pull_request.reviewers"),
Assignees: v.GetStringSlice("vendor.ci.pull_request.assignees"),
Organization: v.GetString("vendor.ci.pull_request.organization"),
Project: v.GetString("vendor.ci.pull_request.project"),
Repository: v.GetString("vendor.ci.pull_request.repository"),
}
}

Expand Down
39 changes: 39 additions & 0 deletions cmd/vendor/update_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/stretchr/testify/require"

errUtils "github.com/cloudposse/atmos/errors"
"github.com/cloudposse/atmos/pkg/schema"
"github.com/cloudposse/atmos/pkg/vendoring/updater"
"github.com/cloudposse/atmos/pkg/vendoring/version"
)
Expand Down Expand Up @@ -89,6 +90,44 @@ func TestVendorUpdateCommand_StackSelectorDescribeStacksErrorPropagates(t *testi
require.Error(t, err)
}

// TestVendorPullRequestConfig proves vendorPullRequestConfig maps every vendor.ci.pull_request.*
// viper key onto the matching schema.VendorPullRequestConfig field -- including Organization,
// Project, and Repository, which only the azuredevops provider consumes (see
// pkg/vendoring/updater.resolveRepositoryAddress) -- so a key/field typo or spelling drift is
// caught by a failing assertion rather than silently reading as an empty string at runtime.
func TestVendorPullRequestConfig(t *testing.T) {
Comment thread
jorrite marked this conversation as resolved.
v := viper.New()
v.Set("vendor.ci.pull_request.provider", "azuredevops")
v.Set("vendor.ci.pull_request.base_branch", "main")
v.Set("vendor.ci.pull_request.branch_prefix", "atmos-update/")
v.Set("vendor.ci.pull_request.title", "chore: update components")
v.Set("vendor.ci.pull_request.body", "automated component update")
v.Set("vendor.ci.pull_request.labels", []string{"component-update", "automated"})
v.Set("vendor.ci.pull_request.draft", true)
v.Set("vendor.ci.pull_request.reviewers", []string{"reviewer-guid"})
v.Set("vendor.ci.pull_request.assignees", []string{"assignee-guid"})
v.Set("vendor.ci.pull_request.organization", "acme-org")
v.Set("vendor.ci.pull_request.project", "platform")
v.Set("vendor.ci.pull_request.repository", "infra")

got := vendorPullRequestConfig(v)

assert.Equal(t, schema.VendorPullRequestConfig{
Provider: "azuredevops",
BaseBranch: "main",
BranchPrefix: "atmos-update/",
Title: "chore: update components",
Body: "automated component update",
Labels: []string{"component-update", "automated"},
Draft: true,
Reviewers: []string{"reviewer-guid"},
Assignees: []string{"assignee-guid"},
Organization: "acme-org",
Project: "platform",
Repository: "infra",
}, got)
}

// TestVendorUpdateCommand_LabelsSelector proves --labels alone (no --stack) resolves through
// RunE's stack-resolution branch and scopes the update to just the matching component, leaving a
// differently-labeled sibling untouched -- mirrors clean_test.go's
Expand Down
15 changes: 15 additions & 0 deletions errors/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -1673,6 +1673,21 @@ var (
ErrGitHubAuthorization = errors.New("GitHub authorization failed")
// ErrPullRequestReconciliation indicates Atmos could not reconcile an existing or new PR.
ErrPullRequestReconciliation = errors.New("pull request reconciliation failed")
// ErrAzureDevOpsTokenNotFound indicates AZURE_DEVOPS_EXT_PAT is not set.
ErrAzureDevOpsTokenNotFound = errors.New("Azure DevOps personal access token not found")
// ErrAzureDevOpsAuthorization indicates an authentication or permission failure from the Azure DevOps API.
ErrAzureDevOpsAuthorization = errors.New("Azure DevOps authorization failed")
// ErrAzureDevOpsAssigneesUnsupported indicates Azure DevOps pull requests do not support assignees.
ErrAzureDevOpsAssigneesUnsupported = errors.New("Azure DevOps pull requests do not support assignees")
// ErrAzureDevOpsNamespaceInvalid indicates PullRequestOptions.Namespace was not exactly the
// single project segment Azure DevOps' organization/project/repository addressing requires.
ErrAzureDevOpsNamespaceInvalid = errors.New("Azure DevOps pull request namespace must be exactly one project segment")
// ErrAzureDevOpsReviewerNotFound indicates a configured reviewer's display name, account name,
// or email matched no Azure DevOps identity.
ErrAzureDevOpsReviewerNotFound = errors.New("Azure DevOps reviewer identity not found")
// ErrAzureDevOpsReviewerAmbiguous indicates a configured reviewer's display name, account name,
// or email matched more than one Azure DevOps identity.
ErrAzureDevOpsReviewerAmbiguous = errors.New("Azure DevOps reviewer identity is ambiguous")
// ErrGitFetchFailed indicates `git fetch` of a base or feature branch failed.
ErrGitFetchFailed = errors.New("git fetch failed")
// ErrGitCheckoutFailed indicates `git checkout` of a feature branch failed.
Expand Down
9 changes: 9 additions & 0 deletions pkg/config/load.go
Original file line number Diff line number Diff line change
Expand Up @@ -734,6 +734,15 @@ func bridgeVendorUpdaterConfig(atmosConfig *schema.AtmosConfiguration) {
if len(pr.Assignees) > 0 {
v.Set("vendor.ci.pull_request.assignees", pr.Assignees)
}
if pr.Organization != "" {
v.Set("vendor.ci.pull_request.organization", pr.Organization)
}
if pr.Project != "" {
v.Set("vendor.ci.pull_request.project", pr.Project)
}
if pr.Repository != "" {
v.Set("vendor.ci.pull_request.repository", pr.Repository)
}

if atmosConfig.Vendor.CI.Summary.Enabled != nil {
v.Set("vendor.ci.summary.enabled", *atmosConfig.Vendor.CI.Summary.Enabled)
Expand Down
33 changes: 33 additions & 0 deletions pkg/datafetcher/schema/atmos/config/1.0.json
Original file line number Diff line number Diff line change
Expand Up @@ -13271,6 +13271,39 @@
"type": "string"
}
]
},
"organization": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"description": "Organization is the Azure DevOps organization name (azuredevops provider only). Together\nwith Project and Repository it addresses a repository the way GitHub's owner/repository\npair does, since Azure DevOps requires three segments: organization/project/repository."
},
"project": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"description": "Project is the Azure DevOps project name (azuredevops provider only). See Organization."
},
"repository": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"description": "Repository is the repository name (azuredevops provider only). GitHub instead derives its\nowner/repository pair from the local Git remote, so this field is a no-op for that provider."
}
},
"type": "object",
Expand Down
Loading
Loading