detached 76ad031

feat(executor): create the artifacts and artifacts_list file commands

commit
76ad031a05c22b803249c262a9db9512ad77bbc7
author
brice · · 2026-10-12 22:46 UTC
parent
61fc6ee
signature
GPG VerifiedCD88F9E564E0102646FB6077A1A07C7C7C3E349D · arch-gpg Verified for the committer email
2 files · +23 -2
M internal/executor/filecmd.go +19 -1
@@ -30,6 +30,11 @@ const (
3030 cmdStepSummary = "step_summary"
3131 cmdState = "state"
3232 cmdOutput = "output"
33+ // The two artifact files exist on GitHub-hosted runners (recordings: the
34+ // github context has artifacts and artifacts_list, the steps GITHUB_ARTIFACTS
35+ // and GITHUB_ARTIFACTS_LIST). ermite does not process them, see below.
36+ cmdArtifacts = "artifacts"
37+ cmdArtifactsList = "artifacts_list"
3338 )
3439
3540 // fileCommand describes one file command like the IFileCommandExtension of
@@ -47,10 +52,21 @@ var fileCommands = []fileCommand{
4752 {cmdStepSummary, "step_summary_"}, // CreateStepSummaryCommand (:221)
4853 {cmdState, "save_state_"}, // SaveStateFileCommand (:295)
4954 {cmdOutput, "set_output_"}, // SetOutputFileCommand (:328)
55+ // CreateArtifactsFileCommand (CreateArtifactsFileCommand.cs:39) and
56+ // ArtifactsListFileCommand (ArtifactsListFileCommand.cs:37), registered in
57+ // ExtensionManager.cs:65-66. Both do nothing unless the feature flag
58+ // actions_runner_allow_artifacts_file or ACTIONS_RUNNER_ALLOW_ARTIFACTS_FILE
59+ // is on (CreateArtifactsFileCommand.cs:67-79); ermite has neither, so the
60+ // files are created empty (as the C# runner does when the feature is off)
61+ // and what a step writes to them is ignored. Artifact subjects are not
62+ // declared yet.
63+ {cmdArtifacts, "artifacts_"},
64+ {cmdArtifactsList, "artifacts_list_"},
5065 }
5166
5267 // EnvVarName returns the environment variable that holds the file of a command:
53-// GITHUB_ENV, GITHUB_OUTPUT, GITHUB_PATH, GITHUB_STATE, GITHUB_STEP_SUMMARY
68+// GITHUB_ARTIFACTS, GITHUB_ARTIFACTS_LIST, GITHUB_ENV, GITHUB_OUTPUT, GITHUB_PATH,
69+// GITHUB_STATE, GITHUB_STEP_SUMMARY
5470 // (GitHubContext.GetRuntimeEnvironmentVariables, GitHubContext.cs:52).
5571 func envVarName(contextName string) string { return "GITHUB_" + strings.ToUpper(contextName) }
5672
@@ -166,6 +182,8 @@ func (f *FileCommands) Process(sink Sink) {
166182 err = processStepSummary(sink, f.root, p)
167183 case cmdState:
168184 err = processPairs(sink, f.root, p, sink.SaveState, func(k, v string) { sink.Debug(fmt.Sprintf("Save intra-action state %s = %s", k, v)) })
185+ case cmdArtifacts, cmdArtifactsList:
186+ // Disabled feature: nothing to process (see fileCommands).
169187 case cmdOutput:
170188 err = processPairs(sink, f.root, p, sink.SetOutput, func(k, v string) { sink.Debug(fmt.Sprintf("Set output %s = %s", k, v)) })
171189 }
@@ -30,6 +30,11 @@ const (
30 cmdStepSummary = "step_summary"30 cmdStepSummary = "step_summary"
31 cmdState = "state"31 cmdState = "state"
32 cmdOutput = "output"32 cmdOutput = "output"
33+ // The two artifact files exist on GitHub-hosted runners (recordings: the
34+ // github context has artifacts and artifacts_list, the steps GITHUB_ARTIFACTS
35+ // and GITHUB_ARTIFACTS_LIST). ermite does not process them, see below.
36+ cmdArtifacts = "artifacts"
37+ cmdArtifactsList = "artifacts_list"
33 )38 )
34 39
35 // fileCommand describes one file command like the IFileCommandExtension of40 // fileCommand describes one file command like the IFileCommandExtension of
@@ -47,10 +52,21 @@ var fileCommands = []fileCommand{
47 {cmdStepSummary, "step_summary_"}, // CreateStepSummaryCommand (:221)52 {cmdStepSummary, "step_summary_"}, // CreateStepSummaryCommand (:221)
48 {cmdState, "save_state_"}, // SaveStateFileCommand (:295)53 {cmdState, "save_state_"}, // SaveStateFileCommand (:295)
49 {cmdOutput, "set_output_"}, // SetOutputFileCommand (:328)54 {cmdOutput, "set_output_"}, // SetOutputFileCommand (:328)
55+ // CreateArtifactsFileCommand (CreateArtifactsFileCommand.cs:39) and
56+ // ArtifactsListFileCommand (ArtifactsListFileCommand.cs:37), registered in
57+ // ExtensionManager.cs:65-66. Both do nothing unless the feature flag
58+ // actions_runner_allow_artifacts_file or ACTIONS_RUNNER_ALLOW_ARTIFACTS_FILE
59+ // is on (CreateArtifactsFileCommand.cs:67-79); ermite has neither, so the
60+ // files are created empty (as the C# runner does when the feature is off)
61+ // and what a step writes to them is ignored. Artifact subjects are not
62+ // declared yet.
63+ {cmdArtifacts, "artifacts_"},
64+ {cmdArtifactsList, "artifacts_list_"},
50 }65 }
51 66
52 // EnvVarName returns the environment variable that holds the file of a command:67 // EnvVarName returns the environment variable that holds the file of a command:
53-// GITHUB_ENV, GITHUB_OUTPUT, GITHUB_PATH, GITHUB_STATE, GITHUB_STEP_SUMMARY68+// GITHUB_ARTIFACTS, GITHUB_ARTIFACTS_LIST, GITHUB_ENV, GITHUB_OUTPUT, GITHUB_PATH,
69+// GITHUB_STATE, GITHUB_STEP_SUMMARY
54 // (GitHubContext.GetRuntimeEnvironmentVariables, GitHubContext.cs:52).70 // (GitHubContext.GetRuntimeEnvironmentVariables, GitHubContext.cs:52).
55 func envVarName(contextName string) string { return "GITHUB_" + strings.ToUpper(contextName) }71 func envVarName(contextName string) string { return "GITHUB_" + strings.ToUpper(contextName) }
56 72
@@ -166,6 +182,8 @@ func (f *FileCommands) Process(sink Sink) {
166 err = processStepSummary(sink, f.root, p)182 err = processStepSummary(sink, f.root, p)
167 case cmdState:183 case cmdState:
168 err = processPairs(sink, f.root, p, sink.SaveState, func(k, v string) { sink.Debug(fmt.Sprintf("Save intra-action state %s = %s", k, v)) })184 err = processPairs(sink, f.root, p, sink.SaveState, func(k, v string) { sink.Debug(fmt.Sprintf("Save intra-action state %s = %s", k, v)) })
185+ case cmdArtifacts, cmdArtifactsList:
186+ // Disabled feature: nothing to process (see fileCommands).
169 case cmdOutput:187 case cmdOutput:
170 err = processPairs(sink, f.root, p, sink.SetOutput, func(k, v string) { sink.Debug(fmt.Sprintf("Set output %s = %s", k, v)) })188 err = processPairs(sink, f.root, p, sink.SetOutput, func(k, v string) { sink.Debug(fmt.Sprintf("Set output %s = %s", k, v)) })
171 }189 }
M internal/executor/filecmd_test.go +4 -1
@@ -104,7 +104,7 @@ func TestFileCommandsInit(t *testing.T) {
104104 if err != nil {
105105 t.Fatal(err)
106106 }
107- for _, name := range []string{"GITHUB_PATH", "GITHUB_ENV", "GITHUB_STEP_SUMMARY", "GITHUB_STATE", "GITHUB_OUTPUT"} {
107+ for _, name := range []string{"GITHUB_PATH", "GITHUB_ENV", "GITHUB_STEP_SUMMARY", "GITHUB_STATE", "GITHUB_OUTPUT", "GITHUB_ARTIFACTS", "GITHUB_ARTIFACTS_LIST"} {
108108 p := env[name]
109109 if p == "" || filepath.Dir(p) != dir {
110110 t.Fatalf("%s = %q", name, p)
@@ -116,6 +116,9 @@ func TestFileCommandsInit(t *testing.T) {
116116 if !strings.HasPrefix(filepath.Base(env["GITHUB_ENV"]), "set_env_") || !strings.HasPrefix(filepath.Base(env["GITHUB_PATH"]), "add_path_") {
117117 t.Fatalf("prefixes: %v", env)
118118 }
119+ if !strings.HasPrefix(filepath.Base(env["GITHUB_ARTIFACTS"]), "artifacts_") || !strings.HasPrefix(filepath.Base(env["GITHUB_ARTIFACTS_LIST"]), "artifacts_list_") {
120+ t.Fatalf("artifact prefixes: %v", env)
121+ }
119122 // A second Init deletes the previous files and uses new names.
120123 env2, _ := fc.Init()
121124 if env2["GITHUB_ENV"] == env["GITHUB_ENV"] {
@@ -104,7 +104,7 @@ func TestFileCommandsInit(t *testing.T) {
104 if err != nil {104 if err != nil {
105 t.Fatal(err)105 t.Fatal(err)
106 }106 }
107- for _, name := range []string{"GITHUB_PATH", "GITHUB_ENV", "GITHUB_STEP_SUMMARY", "GITHUB_STATE", "GITHUB_OUTPUT"} {107+ for _, name := range []string{"GITHUB_PATH", "GITHUB_ENV", "GITHUB_STEP_SUMMARY", "GITHUB_STATE", "GITHUB_OUTPUT", "GITHUB_ARTIFACTS", "GITHUB_ARTIFACTS_LIST"} {
108 p := env[name]108 p := env[name]
109 if p == "" || filepath.Dir(p) != dir {109 if p == "" || filepath.Dir(p) != dir {
110 t.Fatalf("%s = %q", name, p)110 t.Fatalf("%s = %q", name, p)
@@ -116,6 +116,9 @@ func TestFileCommandsInit(t *testing.T) {
116 if !strings.HasPrefix(filepath.Base(env["GITHUB_ENV"]), "set_env_") || !strings.HasPrefix(filepath.Base(env["GITHUB_PATH"]), "add_path_") {116 if !strings.HasPrefix(filepath.Base(env["GITHUB_ENV"]), "set_env_") || !strings.HasPrefix(filepath.Base(env["GITHUB_PATH"]), "add_path_") {
117 t.Fatalf("prefixes: %v", env)117 t.Fatalf("prefixes: %v", env)
118 }118 }
119+ if !strings.HasPrefix(filepath.Base(env["GITHUB_ARTIFACTS"]), "artifacts_") || !strings.HasPrefix(filepath.Base(env["GITHUB_ARTIFACTS_LIST"]), "artifacts_list_") {
120+ t.Fatalf("artifact prefixes: %v", env)
121+ }
119 // A second Init deletes the previous files and uses new names.122 // A second Init deletes the previous files and uses new names.
120 env2, _ := fc.Init()123 env2, _ := fc.Init()
121 if env2["GITHUB_ENV"] == env["GITHUB_ENV"] {124 if env2["GITHUB_ENV"] == env["GITHUB_ENV"] {

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 4

Tags 11

↑↓ moveenter openesc close