diff --git a/PinAction/Program.cs b/PinAction/Program.cs
index ee2398c..cc4e0d0 100644
--- a/PinAction/Program.cs
+++ b/PinAction/Program.cs
@@ -15,18 +15,14 @@ internal partial class Program
///
/// 参数
/// 退出代码
- static int Main(string[] args)
+ private static int Main(string[] args)
{
if (
(args.Length == 0) || // 不提供参数
- (
- // 单独提供帮助相关参数
- (args.Length == 1) &&
- (args[0] is "help"
- or "--help"
- or "-h"
- or "/?")
- )
+ args is ["help"
+ or "--help"
+ or "-h"
+ or "/?"]
)
{
Console.WriteLine(Strings.Help);
@@ -114,115 +110,111 @@ private static bool PinActionHash(string path)
for (int i = 0; i < lines.Length; i++)
{
- if (lines[i].Contains("uses:"))
- {
- // 移除注释
- string[] cleanLinePaths = lines[i].Split('#');
+ if (!lines[i].Contains("uses:")) continue;
- // 非注释内容匹配正则 "^\s+uses:\s*([^@]+)@([^@|\s]+)\s*$"
- Match match = UsesRegex().Match(cleanLinePaths[0]);
+ // 移除注释
+ string[] cleanLinePaths = lines[i].Split('#');
- if (match.Success)
- {
- string repo = match.Groups[1].Value;
- string tag = match.Groups[2].Value;
+ // 非注释内容匹配正则 "^\s+uses:\s*([^@]+)@([^@|\s]+)\s*$"
+ Match match = UsesRegex().Match(cleanLinePaths[0]);
+ if (!match.Success) continue;
+
+ string repo = match.Groups[1].Value;
+ string tag = match.Groups[2].Value;
+
+ AnsiConsole.MarkupLine($"{Print.MSHead.Information} {string.Format(Strings.FindAction, Path.GetRelativePath(Environment.CurrentDirectory, path), Markup.Escape($"{repo}@{tag}"))}");
+
+ // 在这里你可以定义排除哪些项
+ // 例如排除以 actions/ 开头的项(actions/*@*)
+ // if (repo.StartsWith("actions/"))
+ // {
+ // AnsiConsole.MarkupLine($"{Print.MSHead.Warning} 跳过 {repo}@{tag},因为它是官方工作流");
+ // continue;
+ // }
- AnsiConsole.MarkupLine($"{Print.MSHead.Information} {string.Format(Strings.FindAction, Path.GetRelativePath(Environment.CurrentDirectory, path), Markup.Escape($"{repo}@{tag}"))}");
- // 在这里你可以定义排除哪些项
- // 例如排除以 actions/ 开头的项(actions/*@*)
- // if (repo.StartsWith("actions/"))
- // {
- // AnsiConsole.MarkupLine($"{Print.MSHead.Warning} 跳过 {repo}@{tag},因为它是官方工作流");
- // continue;
- // }
+ // 操作前检查
+ // 检查是否已经是哈希值(40个十六进制字符)
+ if (HashRegex().IsMatch(tag))
+ {
+ AnsiConsole.MarkupLine($"{Print.MSHead.Information} {string.Format(Strings.SkippingAlreadyPinnedHashes, Markup.Escape($"{repo}@{tag}"))}");
+ continue;
+ }
+ // 检查仓库是否是 owner/repo 的格式
+ if (repo.Split('/').Length != 2)
+ {
+ AnsiConsole.MarkupLine($"{Print.MSHead.Warning} {Markup.Escape(repo)} 看起来不像是仓库的格式,跳过 {Markup.Escape($"{repo}@{tag}")}");
+ continue;
+ }
- // 操作前检查
- // 检查是否已经是哈希值(40个十六进制字符)
- if (HashRegex().IsMatch(tag))
+ if (!PinedActions.TryGetValue($"{repo}@{tag}", out string? hash))
+ {
+ // 尝试 tags/{tag} 和 heads/{tag}
+ foreach (string refType in new[] { "tags", "heads" })
+ {
+ try
{
- AnsiConsole.MarkupLine($"{Print.MSHead.Information} {string.Format(Strings.SkippingAlreadyPinnedHashes, Markup.Escape($"{repo}@{tag}"))}");
- continue;
+ // 获取该版本的 git commit hash
+ Reference reference = GitHubClient.Git.Reference.Get(repo.Split('/')[0], repo.Split('/')[1], $"{refType}/{tag}").Result;
+ hash = reference.Object.Sha;
+
+ PinedActions.TryAdd($"{repo}@{tag}", hash);
+ break;
}
- // 检查仓库是否是 owner/repo 的格式
- if (repo.Split('/').Length != 2)
+ catch (AggregateException ex) when (ex.InnerException != null)
{
- AnsiConsole.MarkupLine($"{Print.MSHead.Warning} {Markup.Escape(repo)} 看起来不像是仓库的格式,跳过 {Markup.Escape($"{repo}@{tag}")}");
- continue;
- }
-
+ AnsiConsole.Markup($"{Print.MSHead.Warning} {Strings.ErrorGetHashFailed}");
- string? hash;
- if (!pinedActions.TryGetValue($"{repo}@{tag}", out hash))
- {
- // 尝试 tags/{tag} 和 heads/{tag}
- foreach (string refType in new[] { "tags", "heads" })
+ switch (ex.InnerException)
{
- try
- {
- // 获取该版本的 git commit hash
- Reference reference = GitHubClient.Git.Reference.Get(repo.Split('/')[0], repo.Split('/')[1], $"{refType}/{tag}").Result;
- hash = reference.Object.Sha;
-
- pinedActions.TryAdd($"{repo}@{tag}", hash);
- break;
- }
- catch (AggregateException ex) when (ex.InnerException != null)
- {
- AnsiConsole.Markup($"{Print.MSHead.Warning} {Strings.ErrorGetHashFailed}");
-
- switch (ex.InnerException)
+ // 还要再试的用 break;
+ // 最后一次的用 continue;
+ // 直接整个程序失败的 return false;
+ case Octokit.NotFoundException:
+ if (refType == "tags")
+ {
+ AnsiConsole.MarkupLineInterpolated($"[yellow]{string.Format(Strings.ErrorTagNotFound, tag)}[/]");
+ break;
+ }
+ else
{
- // 还要再试的用 break;
- // 最后一次的用 continue;
- // 直接整个程序失败的 return false;
- case Octokit.NotFoundException:
- if (refType == "tags")
- {
- AnsiConsole.MarkupLineInterpolated($"[yellow]{string.Format(Strings.ErrorTagNotFound, tag)}[/]");
- break;
- }
- else
- {
- AnsiConsole.MarkupLineInterpolated($"[red]{string.Format(Strings.ErrorBranchNotFound, tag, $"{repo}@{tag}")}[/]");
- continue;
- }
- case Octokit.RateLimitExceededException:
- AnsiConsole.MarkupLine($"[yellow]{Strings.ErrorRateLimitExceeded}[/]");
- return false;
- default:
- AnsiConsole.MarkupLineInterpolated($"[red]{ex.InnerException.Message}[/]");
- continue;
+ AnsiConsole.MarkupLineInterpolated($"[red]{string.Format(Strings.ErrorBranchNotFound, tag, $"{repo}@{tag}")}[/]");
+ continue;
}
- }
+ case Octokit.RateLimitExceededException:
+ AnsiConsole.MarkupLine($"[yellow]{Strings.ErrorRateLimitExceeded}[/]");
+ return false;
+ default:
+ AnsiConsole.MarkupLineInterpolated($"[red]{ex.InnerException.Message}[/]");
+ continue;
}
}
+ }
+ }
#if DEBUG
- else
- {
- AnsiConsole.MarkupLine($"{Print.MSHead.Debug} 读取缓存 {Markup.Escape($"{repo}@{hash}")} # {Markup.Escape(tag)}");
- }
+ else
+ {
+ AnsiConsole.MarkupLine($"{Print.MSHead.Debug} 读取缓存 {Markup.Escape($"{repo}@{hash}")} # {Markup.Escape(tag)}");
+ }
#endif
- if (hash is null)
- {
- continue;
- }
-
- lines[i] = $"{cleanLinePaths[0].Replace($"{repo}@{tag}", $"{repo}@{hash}")} # {tag}";
- if (cleanLinePaths.Length > 1)
- {
- // 将注释部分重新添加到行末
- foreach (string commentPart in cleanLinePaths.Skip(1))
- {
- lines[i] += commentPart;
- }
- }
+ if (hash is null)
+ {
+ continue;
+ }
- AnsiConsole.MarkupLine($"{Print.MSHead.Success} {Strings.Pinned} {Markup.Escape($"{repo}@{hash}")} # {Markup.Escape(tag)}");
+ lines[i] = $"{cleanLinePaths[0].Replace($"{repo}@{tag}", $"{repo}@{hash}")} # {tag}";
+ if (cleanLinePaths.Length > 1)
+ {
+ // 将注释部分重新添加到行末
+ foreach (string commentPart in cleanLinePaths.Skip(1))
+ {
+ lines[i] += commentPart;
}
}
+
+ AnsiConsole.MarkupLine($"{Print.MSHead.Success} {Strings.Pinned} {Markup.Escape($"{repo}@{hash}")} # {Markup.Escape(tag)}");
}
// 将修改后的内容写回文件
@@ -241,7 +233,7 @@ private static bool PinActionHash(string path)
/// 缓存已固定哈希值的 Action,第二次遇到时不用再去请求 GitHub API 获取。
/// 按 repo@tag, hash 一对存储。
///
- private static readonly ConcurrentDictionary pinedActions = new();
+ private static readonly ConcurrentDictionary PinedActions = new();
[GeneratedRegex(@"^\s*uses:\s*([^@]+)@([^@|\s]+)\s*$")]
private static partial Regex UsesRegex();