Skip to content

Commit ceff056

Browse files
Christian Bumannpascalberger
authored andcommitted
Add overload for AzureDevOpsBuildSettings.UsingAzurePipelinesOAuthToken accepting a build id
Resolves #239
1 parent 2328478 commit ceff056

File tree

4 files changed

+228
-20
lines changed

4 files changed

+228
-20
lines changed

src/Cake.AzureDevOps.Tests/Pipelines/AzureDevOpsBuildSettingsTests.cs

Lines changed: 137 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -839,6 +839,40 @@ public void Should_Throw_If_Build_Id_Env_Var_Is_Not_Set()
839839
result.IsInvalidOperationException();
840840
}
841841

842+
[Fact]
843+
public void Should_Throw_If_Build_Id_Env_Var_Is_Set_But_Ctor_Build_Id_Value_Zero()
844+
{
845+
// Given
846+
var creds = new AzureDevOpsNtlmCredentials();
847+
Environment.SetEnvironmentVariable("SYSTEM_TEAMFOUNDATIONCOLLECTIONURI", "https://example.com/collection");
848+
Environment.SetEnvironmentVariable("SYSTEM_TEAMPROJECT", "MyProject");
849+
Environment.SetEnvironmentVariable("BUILD_BUILDID", "20");
850+
Environment.SetEnvironmentVariable("SYSTEM_ACCESSTOKEN", "foo");
851+
852+
// When
853+
var result = Record.Exception(() => new AzureDevOpsBuildSettings(0, creds));
854+
855+
// Then
856+
result.IsArgumentOutOfRangeException("buildId");
857+
}
858+
859+
[Fact]
860+
public void Should_Throw_If_Build_Id_Env_Var_Is_Set_But_Ctor_Build_Id_Value_Negative()
861+
{
862+
// Given
863+
var creds = new AzureDevOpsNtlmCredentials();
864+
Environment.SetEnvironmentVariable("SYSTEM_TEAMFOUNDATIONCOLLECTIONURI", "https://example.com/collection");
865+
Environment.SetEnvironmentVariable("SYSTEM_TEAMPROJECT", "MyProject");
866+
Environment.SetEnvironmentVariable("BUILD_BUILDID", "20");
867+
Environment.SetEnvironmentVariable("SYSTEM_ACCESSTOKEN", "foo");
868+
869+
// When
870+
var result = Record.Exception(() => new AzureDevOpsBuildSettings(-1, creds));
871+
872+
// Then
873+
result.IsArgumentOutOfRangeException("buildId");
874+
}
875+
842876
[Fact]
843877
public void Should_Throw_If_Build_Id_Env_Var_Is_Not_Integer()
844878
{
@@ -874,7 +908,7 @@ public void Should_Throw_If_Build_Id_Is_Zero()
874908
}
875909

876910
[Fact]
877-
public void Should_Throw_If_System_Access_Token_Env_Var_Is_Not_Set()
911+
public void Should_Throw_If_System_Access_Token_Env_Var_Is_Not_Set_With_OAuthToken()
878912
{
879913
// Given
880914
Environment.SetEnvironmentVariable("SYSTEM_TEAMFOUNDATIONCOLLECTIONURI", "https://example.com/collection");
@@ -890,7 +924,7 @@ public void Should_Throw_If_System_Access_Token_Env_Var_Is_Not_Set()
890924
}
891925

892926
[Fact]
893-
public void Should_Throw_If_System_Access_Token_Env_Var_Is_Empty()
927+
public void Should_Throw_If_System_Access_Token_Env_Var_Is_Empty_With_OAuthToken()
894928
{
895929
// Given
896930
Environment.SetEnvironmentVariable("SYSTEM_TEAMFOUNDATIONCOLLECTIONURI", "https://example.com/collection");
@@ -906,7 +940,7 @@ public void Should_Throw_If_System_Access_Token_Env_Var_Is_Empty()
906940
}
907941

908942
[Fact]
909-
public void Should_Throw_If_System_Access_Token_Env_Var_Is_WhiteSpace()
943+
public void Should_Throw_If_System_Access_Token_Env_Var_Is_WhiteSpace_With_OAuthToken()
910944
{
911945
// Given
912946
Environment.SetEnvironmentVariable("SYSTEM_TEAMFOUNDATIONCOLLECTIONURI", "https://example.com/collection");
@@ -921,6 +955,88 @@ public void Should_Throw_If_System_Access_Token_Env_Var_Is_WhiteSpace()
921955
result.IsInvalidOperationException();
922956
}
923957

958+
[Fact]
959+
public void Should_Throw_If_System_Access_Token_Env_Var_Is_Not_Set_And_Correct_Build_Id()
960+
{
961+
// Given
962+
Environment.SetEnvironmentVariable("SYSTEM_TEAMFOUNDATIONCOLLECTIONURI", "https://example.com/collection");
963+
Environment.SetEnvironmentVariable("SYSTEM_TEAMPROJECT", "MyProject");
964+
Environment.SetEnvironmentVariable("BUILD_BUILDID", "42");
965+
Environment.SetEnvironmentVariable("SYSTEM_ACCESSTOKEN", null);
966+
967+
// When
968+
var result = Record.Exception(() => AzureDevOpsBuildSettings.UsingAzurePipelinesOAuthToken(42));
969+
970+
// Then
971+
result.IsInvalidOperationException();
972+
}
973+
974+
[Fact]
975+
public void Should_Throw_If_System_Access_Token_Env_Var_Is_Empty_And_Correct_Build_Id_With_OAuthToken()
976+
{
977+
// Given
978+
Environment.SetEnvironmentVariable("SYSTEM_TEAMFOUNDATIONCOLLECTIONURI", "https://example.com/collection");
979+
Environment.SetEnvironmentVariable("SYSTEM_TEAMPROJECT", "MyProject");
980+
Environment.SetEnvironmentVariable("BUILD_BUILDID", "42");
981+
Environment.SetEnvironmentVariable("SYSTEM_ACCESSTOKEN", string.Empty);
982+
983+
// When
984+
var result = Record.Exception(() => AzureDevOpsBuildSettings.UsingAzurePipelinesOAuthToken(42));
985+
986+
// Then
987+
result.IsInvalidOperationException();
988+
}
989+
990+
[Fact]
991+
public void Should_Throw_If_Build_Id_Env_Var_Is_Set_But_Ctor_Build_Id_Value_Zero_With_OAuthToken()
992+
{
993+
// Given
994+
var creds = new AzureDevOpsNtlmCredentials();
995+
Environment.SetEnvironmentVariable("SYSTEM_TEAMFOUNDATIONCOLLECTIONURI", "https://example.com/collection");
996+
Environment.SetEnvironmentVariable("SYSTEM_TEAMPROJECT", "MyProject");
997+
Environment.SetEnvironmentVariable("BUILD_BUILDID", "20");
998+
Environment.SetEnvironmentVariable("SYSTEM_ACCESSTOKEN", "foo");
999+
1000+
// When
1001+
var result = Record.Exception(() => AzureDevOpsBuildSettings.UsingAzurePipelinesOAuthToken(0));
1002+
1003+
// Then
1004+
result.IsArgumentOutOfRangeException("buildId");
1005+
}
1006+
1007+
[Fact]
1008+
public void Should_Throw_If_Build_Id_Env_Var_Is_Set_But_Ctor_Build_Id_Value_Negative_With_OAuthToken()
1009+
{
1010+
// Given
1011+
var creds = new AzureDevOpsNtlmCredentials();
1012+
Environment.SetEnvironmentVariable("SYSTEM_TEAMFOUNDATIONCOLLECTIONURI", "https://example.com/collection");
1013+
Environment.SetEnvironmentVariable("SYSTEM_TEAMPROJECT", "MyProject");
1014+
Environment.SetEnvironmentVariable("BUILD_BUILDID", "20");
1015+
Environment.SetEnvironmentVariable("SYSTEM_ACCESSTOKEN", "foo");
1016+
1017+
// When
1018+
var result = Record.Exception(() => AzureDevOpsBuildSettings.UsingAzurePipelinesOAuthToken(-1));
1019+
1020+
// Then
1021+
result.IsArgumentOutOfRangeException("buildId");
1022+
}
1023+
1024+
[Fact]
1025+
public void Should_Throw_If_System_Access_Token_Env_Var_Is_WhiteSpace_And_Correct_Build_Id_With_OAuthToken()
1026+
{
1027+
// Given
1028+
Environment.SetEnvironmentVariable("SYSTEM_TEAMFOUNDATIONCOLLECTIONURI", "https://example.com/collection");
1029+
Environment.SetEnvironmentVariable("SYSTEM_TEAMPROJECT", "MyProject");
1030+
Environment.SetEnvironmentVariable("BUILD_BUILDID", "42");
1031+
Environment.SetEnvironmentVariable("SYSTEM_ACCESSTOKEN", " ");
1032+
1033+
// When
1034+
var result = Record.Exception(() => AzureDevOpsBuildSettings.UsingAzurePipelinesOAuthToken(42));
1035+
1036+
// Then
1037+
result.IsInvalidOperationException();
1038+
}
1039+
9241040
[Fact]
9251041
public void Should_Set_Collection_Url()
9261042
{
@@ -974,6 +1090,24 @@ public void Should_Set_Build_Id()
9741090
settings.BuildId.ShouldBe(buildId);
9751091
}
9761092

1093+
[Fact]
1094+
public void Should_Set_Build_Id_With_Ctor()
1095+
{
1096+
// Given
1097+
var buildId = 42;
1098+
var creds = new AzureDevOpsNtlmCredentials();
1099+
Environment.SetEnvironmentVariable("SYSTEM_TEAMFOUNDATIONCOLLECTIONURI", "https://example.com/collection");
1100+
Environment.SetEnvironmentVariable("SYSTEM_TEAMPROJECT", "MyProject");
1101+
Environment.SetEnvironmentVariable("BUILD_BUILDID", "20");
1102+
Environment.SetEnvironmentVariable("SYSTEM_ACCESSTOKEN", "foo");
1103+
1104+
// When
1105+
var settings = new AzureDevOpsBuildSettings(buildId, creds);
1106+
1107+
// Then
1108+
settings.BuildId.ShouldBe(buildId);
1109+
}
1110+
9771111
[Fact]
9781112
public void Should_Set_Credentials()
9791113
{

src/Cake.AzureDevOps/AzureDevOpsAliases.Pipelines.cs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,41 @@ public static AzureDevOpsBuild AzureDevOpsBuildUsingAzurePipelinesOAuthToken(
8989
return AzureDevOpsBuild(context, settings);
9090
}
9191

92+
/// <summary>
93+
/// Gets the description of a specific build which is running the access token provided by Azure Pipelines.
94+
/// Make sure the build has the 'Allow Scripts to access OAuth token' option enabled.
95+
/// </summary>
96+
/// <param name="context">The context.</param>
97+
/// <param name="buildId">ID of the build.</param>
98+
/// <example>
99+
/// <para>Get an Azure Pipelines build:</para>
100+
/// <code>
101+
/// <![CDATA[
102+
/// var build =
103+
/// AzureDevOpsBuildUsingAzurePipelinesOAuthToken();
104+
/// ]]>
105+
/// </code>
106+
/// </example>
107+
/// <returns>Description of the build.
108+
/// Returns <c>null</c> if build could not be found and
109+
/// <see cref="AzureDevOpsBuildSettings.ThrowExceptionIfBuildCouldNotBeFound"/> is set to <c>false</c>.</returns>
110+
/// <exception cref="AzureDevOpsBuildNotFoundException">If build could not be found and
111+
/// <see cref="AzureDevOpsBuildSettings.ThrowExceptionIfBuildCouldNotBeFound"/> is set to <c>true</c>.</exception>
112+
[CakeMethodAlias]
113+
[CakeAliasCategory("Azure Pipelines")]
114+
[CakeNamespaceImport("Cake.AzureDevOps.Pipelines")]
115+
public static AzureDevOpsBuild AzureDevOpsBuildUsingAzurePipelinesOAuthToken(
116+
this ICakeContext context,
117+
int buildId)
118+
{
119+
context.NotNull(nameof(context));
120+
buildId.NotNegativeOrZero(nameof(buildId));
121+
122+
var settings = AzureDevOpsBuildSettings.UsingAzurePipelinesOAuthToken(buildId);
123+
124+
return AzureDevOpsBuild(context, settings);
125+
}
126+
92127
/// <summary>
93128
/// Gets Azure Pipelines builds using the specified settings.
94129
/// </summary>

src/Cake.AzureDevOps/EnvironmentVariableHelper.cs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,5 +57,32 @@ public static string GetSystemTeamProject()
5757

5858
return projectName;
5959
}
60+
61+
/// <summary>
62+
/// Gets the value for the environment variable 'BUILD_BUILDID'.
63+
/// </summary>
64+
/// <returns>The value for the environment variable 'BUILD_BUILDID'.</returns>
65+
/// <exception cref="InvalidOperationException">If the environment variable was not found, the value is whitespace or less than 1.</exception>
66+
public static int GetBuildId()
67+
{
68+
var buildId = Environment.GetEnvironmentVariable("BUILD_BUILDID", EnvironmentVariableTarget.Process);
69+
if (string.IsNullOrWhiteSpace(buildId))
70+
{
71+
throw new InvalidOperationException(
72+
"Failed to read the BUILD_BUILDID environment variable. Make sure you are running in an Azure Pipelines build.");
73+
}
74+
75+
if (!int.TryParse(buildId, out int buildIdValue))
76+
{
77+
throw new InvalidOperationException("BUILD_BUILDID environment variable should contain integer value");
78+
}
79+
80+
if (buildIdValue <= 0)
81+
{
82+
throw new InvalidOperationException("BUILD_BUILDID environment variable should contain integer value and it should be greater than zero");
83+
}
84+
85+
return buildIdValue;
86+
}
6087
}
6188
}

src/Cake.AzureDevOps/Pipelines/AzureDevOpsBuildSettings.cs

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -83,25 +83,24 @@ public AzureDevOpsBuildSettings(IAzureDevOpsCredentials credentials)
8383
this.Credentials = credentials;
8484
this.CollectionUrl = EnvironmentVariableHelper.GetSystemTeamFoundationCollectionUri();
8585
this.ProjectName = EnvironmentVariableHelper.GetSystemTeamProject();
86+
this.BuildId = EnvironmentVariableHelper.GetBuildId();
87+
}
8688

87-
var buildId = Environment.GetEnvironmentVariable("BUILD_BUILDID", EnvironmentVariableTarget.Process);
88-
if (string.IsNullOrWhiteSpace(buildId))
89-
{
90-
throw new InvalidOperationException(
91-
"Failed to read the BUILD_BUILDID environment variable. Make sure you are running in an Azure Pipelines build.");
92-
}
93-
94-
if (!int.TryParse(buildId, out int buildIdValue))
95-
{
96-
throw new InvalidOperationException("BUILD_BUILDID environment variable should contain integer value");
97-
}
98-
99-
if (buildIdValue <= 0)
100-
{
101-
throw new InvalidOperationException("BUILD_BUILDID environment variable should contain integer value and it should be greater than zero");
102-
}
89+
/// <summary>
90+
/// Initializes a new instance of the <see cref="AzureDevOpsBuildSettings"/> class using environment variables
91+
/// as set by an Azure Pipelines build.
92+
/// </summary>
93+
/// <param name="buildId">ID of the build.</param>
94+
/// <param name="credentials">Credentials to use to authenticate against Azure DevOps.</param>
95+
public AzureDevOpsBuildSettings(int buildId, IAzureDevOpsCredentials credentials)
96+
{
97+
buildId.NotNegativeOrZero(nameof(buildId));
98+
credentials.NotNull(nameof(credentials));
10399

104-
this.BuildId = buildIdValue;
100+
this.BuildId = buildId;
101+
this.Credentials = credentials;
102+
this.CollectionUrl = EnvironmentVariableHelper.GetSystemTeamFoundationCollectionUri();
103+
this.ProjectName = EnvironmentVariableHelper.GetSystemTeamProject();
105104
}
106105

107106
/// <summary>
@@ -146,5 +145,18 @@ public static AzureDevOpsBuildSettings UsingAzurePipelinesOAuthToken()
146145
var accessToken = EnvironmentVariableHelper.GetSystemAccessToken();
147146
return new AzureDevOpsBuildSettings(new AzureDevOpsOAuthCredentials(accessToken));
148147
}
148+
149+
/// <summary>
150+
/// Constructs the settings object for a specific build using the access token provided by Azure Pipelines.
151+
/// </summary>
152+
/// <param name="buildId">ID of the build.</param>
153+
/// <returns>The instance of <see cref="AzureDevOpsBuildSettings"/> class.</returns>
154+
public static AzureDevOpsBuildSettings UsingAzurePipelinesOAuthToken(int buildId)
155+
{
156+
buildId.NotNegativeOrZero(nameof(buildId));
157+
158+
var accessToken = EnvironmentVariableHelper.GetSystemAccessToken();
159+
return new AzureDevOpsBuildSettings(buildId, new AzureDevOpsOAuthCredentials(accessToken));
160+
}
149161
}
150162
}

0 commit comments

Comments
 (0)