diff --git a/runatlantis.io/docs/server-configuration.md b/runatlantis.io/docs/server-configuration.md index 7c74d9a6a..142bb1df6 100644 --- a/runatlantis.io/docs/server-configuration.md +++ b/runatlantis.io/docs/server-configuration.md @@ -241,6 +241,20 @@ and set `--autoplan-modules` to `false`. Azure DevOps hostname to support cloud and self hosted instances. Defaults to `dev.azure.com`. +::: warning COMPATIBILITY WARNING +If you are affected by this change [docs](https://learn.microsoft.com/en-us/azure/devops/release-notes/2018/sep-10-azure-devops-launch#administration) +or this [issue](https://github.com/runatlantis/atlantis/issues/5595) +both Service Hooks (v1 & v2) will convert the AD Organization name to lowercase: +Examples: +`https://dev.azure.com/MYCompany/` & `https://mycompany.visualstudio.com/` will be converted to `mycompany` +`https://dev.azure.com/MYCOMPANY/` & `https://myCOMPANY.visualstudio.com/` will be converted to `mycompany` + +This [change](https://github.com/runatlantis/atlantis/pull/5596) will be applied from version v0.35.0 + +What to do if you have pending plans that were generated with a previous version? +Running an atlantis unlock from v0.35.0 on your current PRs will ignore the files on the `MYCompany` folder. On the next atlantis plan will use the `mycompany` folder and generate everything in the new folder name +::: + ### `--azuredevops-token` ```bash diff --git a/server/events/event_parser.go b/server/events/event_parser.go index 6333f25dd..911b92d4d 100644 --- a/server/events/event_parser.go +++ b/server/events/event_parser.go @@ -1029,6 +1029,12 @@ func (e *EventParser) ParseAzureDevopsRepo(adRepo *azuredevops.GitRepository) (m } else { owner = strings.Split(uri.Path, "/")[1] } + owner = strings.ToLower(owner) + // Important Issue + // Details in here: https://github.com/runatlantis/atlantis/issues/5595 + // Original issue from 2018: https://github.com/runatlantis/atlantis/issues/1858 + // Related Microsoft article: https://learn.microsoft.com/en-us/azure/devops/release-notes/2018/sep-10-azure-devops-launch#administration + // If Azure DevOps forces the usage of new url, we need to remove all the changes added on this pull request (1 line and 1 test) } // Construct our own clone URL so we always get the new dev.azure.com diff --git a/server/events/event_parser_test.go b/server/events/event_parser_test.go index acdca3e06..7c2081520 100644 --- a/server/events/event_parser_test.go +++ b/server/events/event_parser_test.go @@ -1331,6 +1331,36 @@ func TestParseAzureDevopsRepo(t *testing.T) { }, r) } +func TestParseAzureDevopsRepo_LowercasesOwner(t *testing.T) { + parser := events.EventParser{ + AzureDevopsUser: "azuredevops-user", + AzureDevopsToken: "azuredevops-token", + } + + tests := []struct { + url string + expected string + }{ + {"https://dev.azure.com/MyCompany/project/_git/repo", "mycompany"}, + {"https://MYCOMPANY.visualstudio.com/project/_git/repo", "mycompany"}, + {"https://AnotherOrg.visualstudio.com/project/_git/repo", "anotherorg"}, + } + + for _, tt := range tests { + repo := azuredevops.GitRepository{} + repo.WebURL = azuredevops.String(tt.url) + repo.ParentRepository = nil + repo.Project = &azuredevops.TeamProjectReference{Name: azuredevops.String("project")} + repo.Name = azuredevops.String("repo") + + r, err := parser.ParseAzureDevopsRepo(&repo) + Ok(t, err) + // Only check the owner part + parts := strings.Split(r.FullName, "/") + owner := parts[0] + Equals(t, tt.expected, owner) + } +} func TestParseAzureDevopsPullEvent(t *testing.T) { _, _, _, _, _, err := parser.ParseAzureDevopsPullEvent(ADPullEvent) Ok(t, err)