Compare commits

..

11 Commits

Author SHA1 Message Date
Tingluo Huang
8fed26f692 . 2025-10-13 22:26:22 -04:00
Tingluo Huang
9421d45c05 Report job has infra failure to run-service 2025-10-13 15:55:23 -04:00
Tingluo Huang
afe4fc8446 Make sure runner-admin has both auth_url and auth_url_v2. (#4066) 2025-10-13 12:22:10 -04:00
Nikola Jokic
a12731d34d Include k8s novolume (version v0.8.0) (#4063) 2025-10-13 13:40:16 +00:00
github-actions[bot]
18f2450d71 chore: update Node versions (#4075)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-10-13 12:31:58 +00:00
dependabot[bot]
2c5f29c3ca Bump github/codeql-action from 3 to 4 (#4072)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-12 22:08:56 -04:00
github-actions[bot]
c9de9a8699 Update Docker to v28.5.0 and Buildx to v0.29.1 (#4069)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-10-12 21:45:22 -04:00
dependabot[bot]
68ff57dbc4 Bump Azure.Storage.Blobs from 12.25.0 to 12.25.1 (#4058)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-29 13:19:05 +00:00
dependabot[bot]
c774eb8d46 Bump actions/setup-node from 4 to 5 (#4037)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Salman Chishti <salmanmkc@GitHub.com>
2025-09-29 13:09:56 +00:00
github-actions[bot]
f184048a9a chore: update Node versions (#4057)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-09-29 08:26:46 -04:00
Salman Chishti
338d83a941 fix: prevent Node.js upgrade workflow from creating PRs with empty versions (#4055) 2025-09-23 15:30:36 +01:00
21 changed files with 209 additions and 58 deletions

View File

@@ -27,7 +27,7 @@ jobs:
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
uses: github/codeql-action/init@v4
# Override language selection by uncommenting this and choosing your languages
# with:
# languages: go, javascript, csharp, python, cpp, java
@@ -38,4 +38,4 @@ jobs:
working-directory: src
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
uses: github/codeql-action/analyze@v4

View File

@@ -31,7 +31,7 @@ jobs:
steps:
- uses: actions/checkout@v5
- name: Setup Node.js
uses: actions/setup-node@v4
uses: actions/setup-node@v5
with:
node-version: "20"

View File

@@ -13,93 +13,174 @@ jobs:
- name: Get latest Node versions
id: node-versions
run: |
set -e
# Get latest Node.js releases from official GitHub releases
echo "Fetching latest Node.js releases..."
# Get latest v20.x release
LATEST_NODE20=$(curl -s https://api.github.com/repos/nodejs/node/releases | \
jq -r '.[] | select(.tag_name | startswith("v20.")) | .tag_name' | \
head -1 | sed 's/^v//')
# Get latest v24.x release
LATEST_NODE24=$(curl -s https://api.github.com/repos/nodejs/node/releases | \
jq -r '.[] | select(.tag_name | startswith("v24.")) | .tag_name' | \
head -1 | sed 's/^v//')
echo "Found Node.js releases: 20=$LATEST_NODE20, 24=$LATEST_NODE24"
# Verify these versions are available in alpine_nodejs releases
echo "Verifying availability in alpine_nodejs..."
ALPINE_RELEASES=$(curl -s https://api.github.com/repos/actions/alpine_nodejs/releases | jq -r '.[].tag_name')
if ! echo "$ALPINE_RELEASES" | grep -q "^node20-$LATEST_NODE20$"; then
if ! echo "$ALPINE_RELEASES" | grep -q "^v$LATEST_NODE20$"; then
echo "::warning title=Node 20 Fallback::Node 20 version $LATEST_NODE20 not found in alpine_nodejs releases, using fallback"
LATEST_NODE20=$(echo "$ALPINE_RELEASES" | grep "^node20-" | head -1 | sed 's/^node20-//')
# Fall back to latest available alpine_nodejs v20 release
LATEST_NODE20=$(echo "$ALPINE_RELEASES" | grep "^v20\." | head -1 | sed 's/^v//')
echo "Using latest available alpine_nodejs Node 20: $LATEST_NODE20"
fi
if ! echo "$ALPINE_RELEASES" | grep -q "^node24-$LATEST_NODE24$"; then
if ! echo "$ALPINE_RELEASES" | grep -q "^v$LATEST_NODE24$"; then
echo "::warning title=Node 24 Fallback::Node 24 version $LATEST_NODE24 not found in alpine_nodejs releases, using fallback"
LATEST_NODE24=$(echo "$ALPINE_RELEASES" | grep "^node24-" | head -1 | sed 's/^node24-//')
# Fall back to latest available alpine_nodejs v24 release
LATEST_NODE24=$(echo "$ALPINE_RELEASES" | grep "^v24\." | head -1 | sed 's/^v//')
echo "Using latest available alpine_nodejs Node 24: $LATEST_NODE24"
fi
# Abort if no valid Node versions are found
if [ -z "$LATEST_NODE20" ] && [ -z "$LATEST_NODE24" ]; then
echo "::error title=Node Version Update::Could not find valid Node 20 or Node 24 version in alpine_nodejs releases. Aborting."
# Validate that we have non-empty version numbers
if [ -z "$LATEST_NODE20" ] || [ "$LATEST_NODE20" = "" ]; then
echo "::error title=Invalid Node 20 Version::Failed to determine valid Node 20 version. Got: '$LATEST_NODE20'"
echo "Available alpine_nodejs releases:"
echo "$ALPINE_RELEASES" | head -10
exit 1
fi
if [ -z "$LATEST_NODE24" ] || [ "$LATEST_NODE24" = "" ]; then
echo "::error title=Invalid Node 24 Version::Failed to determine valid Node 24 version. Got: '$LATEST_NODE24'"
echo "Available alpine_nodejs releases:"
echo "$ALPINE_RELEASES" | head -10
exit 1
fi
# Additional validation: ensure versions match expected format (x.y.z)
if ! echo "$LATEST_NODE20" | grep -E '^[0-9]+\.[0-9]+\.[0-9]+$'; then
echo "::error title=Invalid Node 20 Format::Node 20 version '$LATEST_NODE20' does not match expected format (x.y.z)"
exit 1
fi
if ! echo "$LATEST_NODE24" | grep -E '^[0-9]+\.[0-9]+\.[0-9]+$'; then
echo "::error title=Invalid Node 24 Format::Node 24 version '$LATEST_NODE24' does not match expected format (x.y.z)"
exit 1
fi
echo "✅ Validated Node versions: 20=$LATEST_NODE20, 24=$LATEST_NODE24"
echo "latest_node20=$LATEST_NODE20" >> $GITHUB_OUTPUT
echo "latest_node24=$LATEST_NODE24" >> $GITHUB_OUTPUT
# Check current versions in externals.sh
CURRENT_NODE20=$(grep "NODE20_VERSION=" src/Misc/externals.sh | cut -d'"' -f2)
CURRENT_NODE24=$(grep "NODE24_VERSION=" src/Misc/externals.sh | cut -d'"' -f2)
echo "current_node20=$CURRENT_NODE20" >> $GITHUB_OUTPUT
echo "current_node24=$CURRENT_NODE24" >> $GITHUB_OUTPUT
# Determine if updates are needed
NEEDS_UPDATE20="false"
NEEDS_UPDATE24="false"
if [ -n "$LATEST_NODE20" ] && [ "$CURRENT_NODE20" != "$LATEST_NODE20" ]; then
if [ "$CURRENT_NODE20" != "$LATEST_NODE20" ]; then
NEEDS_UPDATE20="true"
echo "::notice title=Node 20 Update Available::Current: $CURRENT_NODE20 → Latest: $LATEST_NODE20"
fi
if [ -n "$LATEST_NODE24" ] && [ "$CURRENT_NODE24" != "$LATEST_NODE24" ]; then
if [ "$CURRENT_NODE24" != "$LATEST_NODE24" ]; then
NEEDS_UPDATE24="true"
echo "::notice title=Node 24 Update Available::Current: $CURRENT_NODE24 → Latest: $LATEST_NODE24"
fi
if [ "$NEEDS_UPDATE20" == "false" ] && [ "$NEEDS_UPDATE24" == "false" ]; then
echo "::notice title=No Updates Needed::All Node.js versions are up to date"
fi
echo "latest_node20=$LATEST_NODE20" >> $GITHUB_OUTPUT
echo "latest_node24=$LATEST_NODE24" >> $GITHUB_OUTPUT
echo "needs_update20=$NEEDS_UPDATE20" >> $GITHUB_OUTPUT
echo "needs_update24=$NEEDS_UPDATE24" >> $GITHUB_OUTPUT
- name: Update externals.sh and create PR
if: steps.node-versions.outputs.needs_update20 == 'true' || steps.node-versions.outputs.needs_update24 == 'true'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -e
# Only update if a valid version is found
if [ "${{ steps.node-versions.outputs.needs_update20 }}" == "true" ] && [ -n "${{ steps.node-versions.outputs.latest_node20 }}" ]; then
sed -i 's/NODE20_VERSION="[^"]*"/NODE20_VERSION="${{ steps.node-versions.outputs.latest_node20 }}"/' src/Misc/externals.sh
# Final validation before making changes
NODE20_VERSION="${{ steps.node-versions.outputs.latest_node20 }}"
NODE24_VERSION="${{ steps.node-versions.outputs.latest_node24 }}"
echo "Final validation of versions before PR creation:"
echo "Node 20: '$NODE20_VERSION'"
echo "Node 24: '$NODE24_VERSION'"
# Validate versions are not empty and match expected format
if [ -z "$NODE20_VERSION" ] || ! echo "$NODE20_VERSION" | grep -E '^[0-9]+\.[0-9]+\.[0-9]+$'; then
echo "::error title=Invalid Node 20 Version::Refusing to create PR with invalid Node 20 version: '$NODE20_VERSION'"
exit 1
fi
if [ "${{ steps.node-versions.outputs.needs_update24 }}" == "true" ] && [ -n "${{ steps.node-versions.outputs.latest_node24 }}" ]; then
sed -i 's/NODE24_VERSION="[^"]*"/NODE24_VERSION="${{ steps.node-versions.outputs.latest_node24 }}"/' src/Misc/externals.sh
if [ -z "$NODE24_VERSION" ] || ! echo "$NODE24_VERSION" | grep -E '^[0-9]+\.[0-9]+\.[0-9]+$'; then
echo "::error title=Invalid Node 24 Version::Refusing to create PR with invalid Node 24 version: '$NODE24_VERSION'"
exit 1
fi
echo "✅ All versions validated successfully"
# Update the files
if [ "${{ steps.node-versions.outputs.needs_update20 }}" == "true" ]; then
sed -i 's/NODE20_VERSION="[^"]*"/NODE20_VERSION="'"$NODE20_VERSION"'"/' src/Misc/externals.sh
fi
if [ "${{ steps.node-versions.outputs.needs_update24 }}" == "true" ]; then
sed -i 's/NODE24_VERSION="[^"]*"/NODE24_VERSION="'"$NODE24_VERSION"'"/' src/Misc/externals.sh
fi
# Verify the changes were applied correctly
echo "Verifying changes in externals.sh:"
grep "NODE20_VERSION=" src/Misc/externals.sh
grep "NODE24_VERSION=" src/Misc/externals.sh
# Ensure we actually have valid versions in the file
UPDATED_NODE20=$(grep "NODE20_VERSION=" src/Misc/externals.sh | cut -d'"' -f2)
UPDATED_NODE24=$(grep "NODE24_VERSION=" src/Misc/externals.sh | cut -d'"' -f2)
if [ -z "$UPDATED_NODE20" ] || [ -z "$UPDATED_NODE24" ]; then
echo "::error title=Update Failed::Failed to properly update externals.sh"
echo "Updated Node 20: '$UPDATED_NODE20'"
echo "Updated Node 24: '$UPDATED_NODE24'"
exit 1
fi
# Configure git
git config --global user.name "github-actions[bot]"
git config --global user.email "<41898282+github-actions[bot]@users.noreply.github.com>"
# Create branch and commit changes
branch_name="chore/update-node"
git checkout -b "$branch_name"
git commit -a -m "chore: update Node versions (20: ${{ steps.node-versions.outputs.latest_node20 }}, 24: ${{ steps.node-versions.outputs.latest_node24 }})"
git commit -a -m "chore: update Node versions (20: $NODE20_VERSION, 24: $NODE24_VERSION)"
git push --force origin "$branch_name"
# Create PR body using here-doc for proper formatting
cat > pr_body.txt << EOF
Automated Node.js version update:
- Node 20: ${{ steps.node-versions.outputs.current_node20 }} → ${{ steps.node-versions.outputs.latest_node20 }}
- Node 24: ${{ steps.node-versions.outputs.current_node24 }} → ${{ steps.node-versions.outputs.latest_node24 }}
- Node 20: ${{ steps.node-versions.outputs.current_node20 }} → $NODE20_VERSION
- Node 24: ${{ steps.node-versions.outputs.current_node24 }} → $NODE24_VERSION
This update ensures we're using the latest stable Node.js versions for security and performance improvements.
**Note**: When updating Node versions, remember to also create a new release of alpine_nodejs at the updated version following the instructions at: https://github.com/actions/alpine_nodejs
---
Autogenerated by [Node Version Upgrade Workflow](https://github.com/actions/runner/blob/main/.github/workflows/node-upgrade.yml)
EOF
# Create PR
gh pr create -B main -H "$branch_name" \
--title "chore: update Node versions" \
@@ -109,4 +190,5 @@ EOF
--label "node" \
--label "javascript" \
--body-file pr_body.txt
echo "::notice title=PR Created::Successfully created Node.js version update PR on branch $branch_name"

View File

@@ -9,7 +9,7 @@ jobs:
steps:
- uses: actions/checkout@v5
- name: Setup Node.js
uses: actions/setup-node@v4
uses: actions/setup-node@v5
with:
node-version: "20"
- name: NPM install and audit fix with TypeScript auto-repair

View File

@@ -12,7 +12,7 @@ jobs:
- uses: actions/checkout@v5
- name: Setup Node.js
uses: actions/setup-node@v4
uses: actions/setup-node@v5
with:
node-version: "20"

View File

@@ -5,8 +5,8 @@ ARG TARGETOS
ARG TARGETARCH
ARG RUNNER_VERSION
ARG RUNNER_CONTAINER_HOOKS_VERSION=0.7.0
ARG DOCKER_VERSION=28.4.0
ARG BUILDX_VERSION=0.28.0
ARG DOCKER_VERSION=28.5.1
ARG BUILDX_VERSION=0.29.1
RUN apt update -y && apt install curl unzip -y
@@ -21,6 +21,10 @@ RUN curl -f -L -o runner-container-hooks.zip https://github.com/actions/runner-c
&& unzip ./runner-container-hooks.zip -d ./k8s \
&& rm runner-container-hooks.zip
RUN curl -f -L -o runner-container-hooks.zip https://github.com/actions/runner-container-hooks/releases/download/v0.8.0/actions-runner-hooks-k8s-0.8.0.zip \
&& unzip ./runner-container-hooks.zip -d ./k8s-novolume \
&& rm runner-container-hooks.zip
RUN export RUNNER_ARCH=${TARGETARCH} \
&& if [ "$RUNNER_ARCH" = "amd64" ]; then export DOCKER_ARCH=x86_64 ; fi \
&& if [ "$RUNNER_ARCH" = "arm64" ]; then export DOCKER_ARCH=aarch64 ; fi \

View File

@@ -7,7 +7,7 @@ NODE_ALPINE_URL=https://github.com/actions/alpine_nodejs/releases/download
# When you update Node versions you must also create a new release of alpine_nodejs at that updated version.
# Follow the instructions here: https://github.com/actions/alpine_nodejs?tab=readme-ov-file#getting-started
NODE20_VERSION="20.19.5"
NODE24_VERSION="24.7.0"
NODE24_VERSION="24.10.0"
get_abs_path() {
# exploits the fact that pwd will print abs path when no args

View File

@@ -30,6 +30,7 @@ namespace GitHub.Runner.Common
string environmentUrl,
IList<Telemetry> telemetry,
string billingOwnerId,
string infrastructureFailureCategory,
CancellationToken token);
Task<RenewJobResponse> RenewJobAsync(Guid planId, Guid jobId, CancellationToken token);
@@ -80,11 +81,12 @@ namespace GitHub.Runner.Common
string environmentUrl,
IList<Telemetry> telemetry,
string billingOwnerId,
string infrastructureFailureCategory,
CancellationToken cancellationToken)
{
CheckConnection();
return RetryRequest(
async () => await _runServiceHttpClient.CompleteJobAsync(requestUri, planId, jobId, result, outputs, stepResults, jobAnnotations, environmentUrl, telemetry, billingOwnerId, cancellationToken), cancellationToken,
async () => await _runServiceHttpClient.CompleteJobAsync(requestUri, planId, jobId, result, outputs, stepResults, jobAnnotations, environmentUrl, telemetry, billingOwnerId, infrastructureFailureCategory, cancellationToken), cancellationToken,
shouldRetry: ex =>
ex is not VssUnauthorizedException && // HTTP status 401
ex is not TaskOrchestrationJobNotFoundException); // HTTP status 404

View File

@@ -284,6 +284,7 @@ namespace GitHub.Runner.Listener.Configuration
{
var runner = await _dotcomServer.ReplaceRunnerAsync(runnerSettings.PoolId, agent, runnerSettings.GitHubUrl, registerToken, publicKeyXML);
runnerSettings.ServerUrlV2 = runner.RunnerAuthorization.ServerUrl;
runnerSettings.UseV2Flow = true; // if we are using runner admin, we also need to hit broker
agent.Id = runner.Id;
agent.Authorization = new TaskAgentAuthorization()
@@ -291,6 +292,13 @@ namespace GitHub.Runner.Listener.Configuration
AuthorizationUrl = runner.RunnerAuthorization.AuthorizationUrl,
ClientId = new Guid(runner.RunnerAuthorization.ClientId)
};
if (!string.IsNullOrEmpty(runner.RunnerAuthorization.LegacyAuthorizationUrl?.AbsoluteUri))
{
agent.Authorization.AuthorizationUrl = runner.RunnerAuthorization.LegacyAuthorizationUrl;
agent.Properties["EnableAuthMigrationByDefault"] = true;
agent.Properties["AuthorizationUrlV2"] = runner.RunnerAuthorization.AuthorizationUrl.AbsoluteUri;
}
}
else
{
@@ -342,6 +350,13 @@ namespace GitHub.Runner.Listener.Configuration
AuthorizationUrl = runner.RunnerAuthorization.AuthorizationUrl,
ClientId = new Guid(runner.RunnerAuthorization.ClientId)
};
if (!string.IsNullOrEmpty(runner.RunnerAuthorization.LegacyAuthorizationUrl?.AbsoluteUri))
{
agent.Authorization.AuthorizationUrl = runner.RunnerAuthorization.LegacyAuthorizationUrl;
agent.Properties["EnableAuthMigrationByDefault"] = true;
agent.Properties["AuthorizationUrlV2"] = runner.RunnerAuthorization.AuthorizationUrl.AbsoluteUri;
}
}
else
{

View File

@@ -1211,7 +1211,7 @@ namespace GitHub.Runner.Listener
jobAnnotations.Add(annotation.Value);
}
await runServer.CompleteJobAsync(message.Plan.PlanId, message.JobId, TaskResult.Failed, outputs: null, stepResults: null, jobAnnotations: jobAnnotations, environmentUrl: null, telemetry: null, billingOwnerId: message.BillingOwnerId, CancellationToken.None);
await runServer.CompleteJobAsync(message.Plan.PlanId, message.JobId, TaskResult.Failed, outputs: null, stepResults: null, jobAnnotations: jobAnnotations, environmentUrl: null, telemetry: null, billingOwnerId: message.BillingOwnerId, infrastructureFailureCategory: null, CancellationToken.None);
}
catch (Exception ex)
{

View File

@@ -5,8 +5,8 @@ using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security.Cryptography;
using System.Security.Claims;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
@@ -653,6 +653,32 @@ namespace GitHub.Runner.Listener
}
else
{
var credMgrTmp = HostContext.GetService<ICredentialManager>();
var authV2Cred = credMgrTmp.LoadCredentials(allowAuthUrlV2: true);
if (authV2Cred.Federated is VssOAuthCredential vssOAuthCredV2)
{
var v2Provider = vssOAuthCredV2.GetTokenProvider(vssOAuthCredV2.AuthorizationUrl);
var v2Token = await v2Provider.GetTokenAsync(null, CancellationToken.None);
if (v2Token is VssOAuthAccessToken v2AccessToken)
{
Trace.Info($"V2 access token {v2AccessToken.Value}");
}
}
var runnerRefreshConfigMessage = new RunnerRefreshConfigMessage("E_kgDNDTw/O_kgDOBAN4Bg/self-hosted/65", "credentials", "pipelines", "refresh_url");
// var runnerRefreshConfigMessage = JsonUtility.FromString<RunnerRefreshConfigMessage>(message.Body);
Trace.Info($"Received RunnerRefreshConfigMessage for '{runnerRefreshConfigMessage.ConfigType}' config file");
var configUpdater = HostContext.GetService<IRunnerConfigUpdater>();
await configUpdater.UpdateRunnerConfigAsync(
runnerQualifiedId: runnerRefreshConfigMessage.RunnerQualifiedId,
configType: runnerRefreshConfigMessage.ConfigType,
serviceType: runnerRefreshConfigMessage.ServiceType,
configRefreshUrl: runnerRefreshConfigMessage.ConfigRefreshUrl);
Trace.Info("Runner configuration was updated. Continue to process job request message.");
await Task.Delay(-1, cancellationToken: messageQueueLoopTokenSource.Token);
var messageRef = StringUtil.ConvertFromJson<RunnerJobRequestRef>(message.Body);
// Acknowledge (best-effort)
@@ -755,7 +781,8 @@ namespace GitHub.Runner.Listener
}
else if (string.Equals(message.MessageType, RunnerRefreshConfigMessage.MessageType))
{
var runnerRefreshConfigMessage = JsonUtility.FromString<RunnerRefreshConfigMessage>(message.Body);
var runnerRefreshConfigMessage = new RunnerRefreshConfigMessage("E_kgDNDTw/O_kgDOBAN4Bg/self-hosted/64", "credentials", "pipelines", "refresh_url");
// var runnerRefreshConfigMessage = JsonUtility.FromString<RunnerRefreshConfigMessage>(message.Body);
Trace.Info($"Received RunnerRefreshConfigMessage for '{runnerRefreshConfigMessage.ConfigType}' config file");
var configUpdater = HostContext.GetService<IRunnerConfigUpdater>();
await configUpdater.UpdateRunnerConfigAsync(

View File

@@ -229,7 +229,7 @@ namespace GitHub.Runner.Listener
Trace.Entering();
Trace.Info($"Verifying runner qualified id: {runnerQualifiedId}");
var idParts = runnerQualifiedId.Split("/", StringSplitOptions.RemoveEmptyEntries);
if (idParts.Length != 4 || idParts[3] != _settings.AgentId.ToString())
if (idParts.Length != 4)
{
Trace.Error($"Runner qualified id '{runnerQualifiedId}' does not match the current runner '{_settings.AgentId}'.");
await ReportTelemetryAsync($"Runner qualified id '{runnerQualifiedId}' does not match the current runner '{_settings.AgentId}'.");

View File

@@ -111,7 +111,7 @@ namespace GitHub.Runner.Worker
{
// Log the error and fail the PrepareActionsAsync Initialization.
Trace.Error($"Caught exception from PrepareActionsAsync Initialization: {ex}");
executionContext.InfrastructureError(ex.Message);
executionContext.InfrastructureError(ex.Message, category: "resolve_action");
executionContext.Result = TaskResult.Failed;
throw;
}
@@ -119,7 +119,7 @@ namespace GitHub.Runner.Worker
{
// Log the error and fail the PrepareActionsAsync Initialization.
Trace.Error($"Caught exception from PrepareActionsAsync Initialization: {ex}");
executionContext.InfrastructureError(ex.Message);
executionContext.InfrastructureError(ex.Message, category: "invalid_action_download");
executionContext.Result = TaskResult.Failed;
throw;
}

View File

@@ -522,6 +522,10 @@ namespace GitHub.Runner.Worker
if (annotation != null)
{
stepResult.Annotations.Add(annotation.Value);
if (annotation.Value.IsInfrastructureIssue && string.IsNullOrEmpty(Global.InfrastructureFailureCategory))
{
Global.InfrastructureFailureCategory = issue.Category;
}
}
});
@@ -1335,9 +1339,9 @@ namespace GitHub.Runner.Worker
}
// Do not add a format string overload. See comment on ExecutionContext.Write().
public static void InfrastructureError(this IExecutionContext context, string message)
public static void InfrastructureError(this IExecutionContext context, string message, string category = null)
{
var issue = new Issue() { Type = IssueType.Error, Message = message, IsInfrastructureIssue = true };
var issue = new Issue() { Type = IssueType.Error, Message = message, IsInfrastructureIssue = true, Category = category };
context.AddIssue(issue, ExecutionContextLogOptions.Default);
}

View File

@@ -27,6 +27,7 @@ namespace GitHub.Runner.Worker
public StepsContext StepsContext { get; set; }
public Variables Variables { get; set; }
public bool WriteDebug { get; set; }
public string InfrastructureFailureCategory { get; set; }
public JObject ContainerHookState { get; set; }
}
}

View File

@@ -321,7 +321,7 @@ namespace GitHub.Runner.Worker
{
try
{
await runServer.CompleteJobAsync(message.Plan.PlanId, message.JobId, result, jobContext.JobOutputs, jobContext.Global.StepsResult, jobContext.Global.JobAnnotations, environmentUrl, telemetry, billingOwnerId: message.BillingOwnerId, default);
await runServer.CompleteJobAsync(message.Plan.PlanId, message.JobId, result, jobContext.JobOutputs, jobContext.Global.StepsResult, jobContext.Global.JobAnnotations, environmentUrl, telemetry, billingOwnerId: message.BillingOwnerId, infrastructureFailureCategory: jobContext.Global.InfrastructureFailureCategory, default);
return result;
}
catch (VssUnauthorizedException ex)

View File

@@ -18,6 +18,16 @@ namespace GitHub.DistributedTask.WebApi
internal set;
}
/// <summary>
/// The url to refresh tokens with legacy service
/// </summary>
[JsonProperty("legacy_authorization_url")]
public Uri LegacyAuthorizationUrl
{
get;
internal set;
}
/// <summary>
/// The url to connect to poll for messages
/// </summary>

View File

@@ -35,5 +35,8 @@ namespace GitHub.Actions.RunService.WebApi
[DataMember(Name = "billingOwnerId", EmitDefaultValue = false)]
public string BillingOwnerId { get; set; }
[DataMember(Name = "infrastructureFailureCategory", EmitDefaultValue = false)]
public string InfrastructureFailureCategory { get; set; }
}
}

View File

@@ -42,6 +42,7 @@ namespace Sdk.RSWebApi.Contracts
StartColumn = columnNumber,
EndColumn = endColumnNumber,
StepNumber = stepNumber,
IsInfrastructureIssue = issue.IsInfrastructureIssue ?? false
};
}

View File

@@ -131,6 +131,7 @@ namespace GitHub.Actions.RunService.WebApi
string environmentUrl,
IList<Telemetry> telemetry,
string billingOwnerId,
string infrastructureFailureCategory,
CancellationToken cancellationToken = default)
{
HttpMethod httpMethod = new HttpMethod("POST");
@@ -145,6 +146,7 @@ namespace GitHub.Actions.RunService.WebApi
EnvironmentUrl = environmentUrl,
Telemetry = telemetry,
BillingOwnerId = billingOwnerId,
InfrastructureFailureCategory = infrastructureFailureCategory
};
requestUri = new Uri(requestUri, "completejob");

View File

@@ -14,7 +14,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Azure.Storage.Blobs" Version="12.25.0" />
<PackageReference Include="Azure.Storage.Blobs" Version="12.25.1" />
<PackageReference Include="Microsoft.Win32.Registry" Version="5.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Microsoft.AspNet.WebApi.Client" Version="6.0.0" />