From 01101fa098af8c8c2e217cc4dae73344c287692a Mon Sep 17 00:00:00 2001 From: Christopher Homberger Date: Tue, 26 May 2026 17:23:47 +0200 Subject: [PATCH 1/2] azp: Add Substring --- src/Sdk/AzurePipelines/descriptions.json | 3 ++ .../Expressions2/ExpressionConstants.cs | 2 + .../Sdk/Functions/v1/SubString.cs | 18 ++++++++ .../substring-function-1/pipeline.yml | 11 +++++ .../substring-function/pipeline.yml | 46 +++++++++++++++++++ 5 files changed, 80 insertions(+) create mode 100644 src/Sdk/DTExpressions2/Expressions2/Sdk/Functions/v1/SubString.cs create mode 100644 testworkflows/azpipelines/substring-function-1/pipeline.yml create mode 100644 testworkflows/azpipelines/substring-function/pipeline.yml diff --git a/src/Sdk/AzurePipelines/descriptions.json b/src/Sdk/AzurePipelines/descriptions.json index a6a4589a2e7..266a9846f2f 100644 --- a/src/Sdk/AzurePipelines/descriptions.json +++ b/src/Sdk/AzurePipelines/descriptions.json @@ -115,6 +115,9 @@ }, "trim": { "description": "* Returns the parameter without leading and trailing white spaces\n* Min parameters: 1. Max parameters: 1\n* Example: `trim(' variable ') ` returns 'variable'" + }, + "substring": { + "description": "* Returns a substring from the input string, starting at the specified index and having the specified length.\n* Min parameters: 3. Max parameters: 3\n* The first parameter is the input string. The second parameter is the zero-based starting index of the substring. The third parameter is the length of the substring.\n* Example: `substring('Hello world', 0, 5)` returns 'Hello'" } } } \ No newline at end of file diff --git a/src/Sdk/DTExpressions2/Expressions2/ExpressionConstants.cs b/src/Sdk/DTExpressions2/Expressions2/ExpressionConstants.cs index 332569eb5ae..621e37f16cf 100644 --- a/src/Sdk/DTExpressions2/Expressions2/ExpressionConstants.cs +++ b/src/Sdk/DTExpressions2/Expressions2/ExpressionConstants.cs @@ -45,6 +45,8 @@ static ExpressionConstants() // https://learn.microsoft.com/en-us/azure/devops/release-notes/2025/pipelines/sprint-248-update#new-pipeline-expression-functions AddAzureFunction("iif", 3, 3); AddAzureFunction("trim", 1, 1); + // Undocumented: + AddAzureFunction("substring", 3, 3); } private static void AddFunction(String name, Int32 minParameters, Int32 maxParameters) diff --git a/src/Sdk/DTExpressions2/Expressions2/Sdk/Functions/v1/SubString.cs b/src/Sdk/DTExpressions2/Expressions2/Sdk/Functions/v1/SubString.cs new file mode 100644 index 00000000000..ca811c99ac1 --- /dev/null +++ b/src/Sdk/DTExpressions2/Expressions2/Sdk/Functions/v1/SubString.cs @@ -0,0 +1,18 @@ +using System; + +namespace GitHub.DistributedTask.Expressions2.Sdk.Functions.v1 +{ + internal sealed class SubString : Function + { + protected sealed override Boolean TraceFullyRealized => false; + + protected sealed override Object EvaluateCore(EvaluationContext context, out ResultMemory memory) + { + memory = null; + String left = Parameters[0].EvaluateString(context) as String ?? String.Empty; + Int32 startIndex = (Int32)Parameters[1].Evaluate(context).ConvertToNumber(); + Int32 length = (Int32)Parameters[2].Evaluate(context).ConvertToNumber(); + return left.Substring(startIndex, length); + } + } +} diff --git a/testworkflows/azpipelines/substring-function-1/pipeline.yml b/testworkflows/azpipelines/substring-function-1/pipeline.yml new file mode 100644 index 00000000000..5182a1b4467 --- /dev/null +++ b/testworkflows/azpipelines/substring-function-1/pipeline.yml @@ -0,0 +1,11 @@ +trigger: none +pr: none + +pool: + vmImage: 'ubuntu-latest' + +steps: +- ${{ if ne(substring('Hello small World', 6, 5), 'small') }}: + - fail: true +- ${{ else }}: + - bash: echo "substring function works as expected" diff --git a/testworkflows/azpipelines/substring-function/pipeline.yml b/testworkflows/azpipelines/substring-function/pipeline.yml new file mode 100644 index 00000000000..5da8643fc9e --- /dev/null +++ b/testworkflows/azpipelines/substring-function/pipeline.yml @@ -0,0 +1,46 @@ +trigger: none +pr: none + +variables: + Tag: $[ substring(variables['Build.SourceVersion'], 0, 7) ] + ShortHash: $[ substring(variables['Build.SourceVersion'], 0, 7) ] + StaticSubstring: $[ substring('abcdef1234567890', 0, 7) ] + +pool: + vmImage: 'ubuntu-latest' + +steps: +- checkout: none + +- bash: | + set -euo pipefail + + echo "Build.SourceVersion: ${SOURCE_VERSION}" + echo "Tag: ${TAG_VALUE}" + echo "ShortHash: ${SHORT_HASH_VALUE}" + echo "StaticSubstring: ${STATIC_SUBSTRING_VALUE}" + + expected_short_hash="${SOURCE_VERSION:0:7}" + + if [ "${TAG_VALUE}" != "${expected_short_hash}" ]; then + echo "##vso[task.logissue type=error]Tag did not match expected short hash '${expected_short_hash}'" + exit 1 + fi + + if [ "${SHORT_HASH_VALUE}" != "${expected_short_hash}" ]; then + echo "##vso[task.logissue type=error]ShortHash did not match expected short hash '${expected_short_hash}'" + exit 1 + fi + + if [ "${STATIC_SUBSTRING_VALUE}" != "abcdef1" ]; then + echo "##vso[task.logissue type=error]StaticSubstring did not match expected value 'abcdef1'" + exit 1 + fi + + echo "substring runtime expressions evaluated successfully." + displayName: 'Test: substring runtime expression' + env: + SOURCE_VERSION: $(Build.SourceVersion) + TAG_VALUE: $(Tag) + SHORT_HASH_VALUE: $(ShortHash) + STATIC_SUBSTRING_VALUE: $(StaticSubstring) \ No newline at end of file From 2716de2bf312eb99aae9c2e53100ad2064df6682 Mon Sep 17 00:00:00 2001 From: Christopher Homberger Date: Tue, 26 May 2026 20:35:42 +0200 Subject: [PATCH 2/2] Skip actions schema for vscode extension due to openvsx secret scanning defect --- src/Sdk/Sdk.csproj | 2 +- src/azure-pipelines-vscode-ext/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Sdk/Sdk.csproj b/src/Sdk/Sdk.csproj index d3ad4df5414..505d64d839c 100644 --- a/src/Sdk/Sdk.csproj +++ b/src/Sdk/Sdk.csproj @@ -48,7 +48,7 @@ $(DefineConstants);HAVE_YAML_DOTNET_FORK - + GitHub.DistributedTask.Pipelines.ObjectTemplating.workflow-v1.0.json diff --git a/src/azure-pipelines-vscode-ext/package.json b/src/azure-pipelines-vscode-ext/package.json index 6692b7c8476..5065c67adf4 100644 --- a/src/azure-pipelines-vscode-ext/package.json +++ b/src/azure-pipelines-vscode-ext/package.json @@ -358,7 +358,7 @@ ] }, "scripts": { - "build": "dotnet build ext-core -c Release -o build && npx webpack", + "build": "dotnet build ext-core -p:AZURE_PIPELINES_TOOLS_WORKAROUND=1 -c Release -o build && npx webpack", "test": "npm run build && node ./test/runTest.js" }, "devDependencies": {