Skip to content

Commit b653ce3

Browse files
Support Gitea Absolute Actions via Feature Flag (#563)
* including tokens * system.runner.server.absolute_actions
1 parent 050c706 commit b653ce3

7 files changed

Lines changed: 58 additions & 2 deletions

File tree

src/Runner.Server/Controllers/ActionDownloadInfoController.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,11 +124,20 @@ public async Task<IActionResult> Get(Guid scopeIdentifier, string hubName, Guid
124124
ActionDownloadInfo defDownloadInfo = null;
125125
foreach(var downloadUrl in downloadUrls) {
126126
try {
127-
var downloadinfo = new ActionDownloadInfo() {NameWithOwner = item.NameWithOwner, Ref = item.Ref, ResolvedNameWithOwner = item.NameWithOwner, ResolvedSha = item.Ref };
127+
// : is otherwise put on the filesystem and windows forbids it
128+
var sanitizedNameWithOwner = item.NameWithOwner;//.Replace("://", "__");
129+
var downloadinfo = new ActionDownloadInfo() {NameWithOwner = sanitizedNameWithOwner, Ref = item.Ref, ResolvedNameWithOwner = sanitizedNameWithOwner, ResolvedSha = item.Ref };
128130
// Allow access to the original action
129131
if(islocalcheckout && item.NameWithOwner == localcheckout && item.Ref.StartsWith(BuildConstants.Source.CommitHash)) {
130132
item.Ref = item.Ref.Substring(BuildConstants.Source.CommitHash.Length);
131133
}
134+
if(item.NameWithOwner.StartsWith("http~//") || item.NameWithOwner.StartsWith("https~//")) {
135+
downloadinfo.TarballUrl = item.NameWithOwner.Replace('~', ':') + "/archive/" + item.Ref + ".tar.gz";
136+
downloadinfo.ZipballUrl = item.NameWithOwner.Replace('~', ':') + "/archive/" + item.Ref + ".zip";
137+
downloadinfo.Authentication = new ActionDownloadAuthentication() { Token = "dummy-token" };
138+
actions[name] = downloadinfo;
139+
break;
140+
}
132141
downloadinfo.TarballUrl = String.Format(downloadUrl.TarballUrl, item.NameWithOwner, item.Ref);
133142
downloadinfo.ZipballUrl = String.Format(downloadUrl.ZipballUrl, item.NameWithOwner, item.Ref);
134143
if(defDownloadInfo == null) {

src/Runner.Server/Controllers/MessageController.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -637,6 +637,8 @@ private static TemplateContext CreateTemplateContext(GitHub.DistributedTask.Obje
637637
if(context.HasFeature("system.runner.server.FailInvalidActionsIfExpression")) {
638638
flags |= ExpressionFlags.FailInvalidActionsIfExpression;
639639
}
640+
// For Gitea Actions
641+
var absoluteActions = context.HasFeature("system.runner.server.absolute_actions");
640642
var templateContext = new TemplateContext() {
641643
Flags = flags,
642644
CancellationToken = CancellationToken.None,
@@ -646,7 +648,8 @@ private static TemplateContext CreateTemplateContext(GitHub.DistributedTask.Obje
646648
maxEvents: 1000000,
647649
maxBytes: 10 * 1024 * 1024),
648650
TraceWriter = traceWriter,
649-
Schema = PipelineTemplateSchemaFactory.GetSchema()
651+
Schema = PipelineTemplateSchemaFactory.GetSchema(),
652+
AbsoluteActions = absoluteActions,
650653
};
651654
if(context.FeatureToggles.TryGetValue("system.runner.server.workflow_schema", out var workflow_schema)) {
652655
var objectReader = new JsonObjectReader(null, workflow_schema);

src/Runner.Worker/ActionManager.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,11 @@ public sealed class ActionManager : RunnerService, IActionManager
205205
throw new Exception($"Missing download info for {lookupKey}");
206206
}
207207

208+
if (action.Reference is Pipelines.RepositoryPathReference repoAction && repoAction.Token != null)
209+
{
210+
downloadInfo.Authentication = new ActionDownloadAuthentication { Token = repoAction.Token };
211+
}
212+
208213
await DownloadRepositoryActionAsync(executionContext, downloadInfo);
209214
}
210215

src/Runner.Worker/ActionManifestManager.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,8 @@ private TemplateContext CreateTemplateContext(
328328
if(executionContext.Global.Variables.GetBoolean("system.runner.server.FailInvalidActionsIfExpression") == true) {
329329
flags |= ExpressionFlags.FailInvalidActionsIfExpression;
330330
}
331+
// For Gitea Actions
332+
var absoluteActions = executionContext.Global.Variables.GetBoolean("system.runner.server.absolute_actions") == true;
331333
var result = new TemplateContext
332334
{
333335
Flags = flags,
@@ -339,6 +341,7 @@ private TemplateContext CreateTemplateContext(
339341
maxBytes: 10 * 1024 * 1024),
340342
Schema = schema,
341343
TraceWriter = executionContext.ToTemplateTraceWriter(),
344+
AbsoluteActions = absoluteActions,
342345
};
343346

344347
// Expression values from execution context

src/Sdk/DTObjectTemplating/ObjectTemplating/TemplateContext.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ internal class AutoCompleteEntry {
3333
public sealed class TemplateContext
3434
{
3535
public ExpressionFlags Flags { get; set; }
36+
public bool AbsoluteActions { get; set; }
3637
internal CancellationToken CancellationToken { get; set; }
3738

3839
public int? Column { get; set; }

src/Sdk/DTPipelines/Pipelines/ActionStepDefinitionReference.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ private RepositoryPathReference(RepositoryPathReference referenceToClone)
7979
this.Ref = referenceToClone.Ref;
8080
this.RepositoryType = referenceToClone.RepositoryType;
8181
this.Path = referenceToClone.Path;
82+
this.Token = referenceToClone.Token;
8283
}
8384

8485
[DataMember(EmitDefaultValue = false)]
@@ -124,6 +125,16 @@ public string Path
124125
set;
125126
}
126127

128+
/// <summary>
129+
/// For Gitea Basic Auth Token
130+
/// </summary>
131+
[DataMember(EmitDefaultValue = false)]
132+
public string Token
133+
{
134+
get;
135+
set;
136+
}
137+
127138
public override ActionStepDefinitionReference Clone()
128139
{
129140
return new RepositoryPathReference(this);

src/Sdk/DTPipelines/Pipelines/ObjectTemplating/PipelineTemplateConverter.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -563,6 +563,29 @@ private static ActionStep ConvertToStep(
563563
var usesSegments = uses.Value.Split('@');
564564
var pathSegments = usesSegments[0].Split(new[] { '/', '\\' }, StringSplitOptions.RemoveEmptyEntries);
565565
var gitRef = usesSegments.Length == 2 ? usesSegments[1] : String.Empty;
566+
string token = null;
567+
if(usesSegments.Length >= 2 && usesSegments.Length <= 3 && context.AbsoluteActions)
568+
{
569+
foreach (var proto in new [] {"http://", "https://"})
570+
{
571+
if (usesSegments[0].StartsWith(proto))
572+
{
573+
// Includes basic auth
574+
if (usesSegments.Length == 3)
575+
{
576+
usesSegments = new string[] { string.Join("@", usesSegments.Take(2)), usesSegments[2] };
577+
// Remove auth part and extract the token for loading
578+
var absoluteUrl = new Uri(usesSegments[0]);
579+
usesSegments[0] = absoluteUrl.GetComponents(UriComponents.AbsoluteUri & ~UriComponents.UserInfo, UriFormat.UriEscaped);
580+
token = string.Join(":", absoluteUrl.UserInfo?.Split(':').Skip(1));
581+
gitRef = usesSegments[1];
582+
}
583+
pathSegments = usesSegments[0].Substring(proto.Length).Split('/');
584+
pathSegments = pathSegments.Skip(2).Prepend((proto + string.Join("/", pathSegments.Take(2))).Replace(':', '~')).ToArray();
585+
break;
586+
}
587+
}
588+
}
566589

567590
if (usesSegments.Length != 2 ||
568591
pathSegments.Length < 2 ||
@@ -584,6 +607,7 @@ private static ActionStep ConvertToStep(
584607
Name = repositoryName,
585608
Ref = gitRef,
586609
Path = directoryPath,
610+
Token = token,
587611
};
588612
}
589613
}

0 commit comments

Comments
 (0)