v0.3.0 8f98fd3

containers_node.go RawHistoryFolder

1// SPDX-License-Identifier: MIT
2
3package executor
4
5import (
6	"fmt"
7	"path/filepath"
8	"runtime"
9	"strings"
10)
11
12// alpineCheck is the command of ContainerStepHost.DetermineNodeRuntimeVersion
13// (StepHost.cs:176): the distribution is read from the release files.
14const alpineCheck = `cat /etc/*release | grep ^ID`
15
16// nodeInContainer is ContainerStepHost.DetermineNodeRuntimeVersion
17// (StepHost.cs:154-196, container hooks off): "<version>_alpine" when the
18// image is Alpine (musl, where the glibc builds do not run), else the version
19// itself. The output of the probe is not logged, only the command is.
20func (j *job) nodeInContainer(s *stepRun, c *container, version string, cancel <-chan struct{}) (string, error) {
21	cmd := j.newDockerCmd("exec", dockerPart{line: ""}, raw(c.id),
22		dockerPart{line: `sh -c "` + alpineCheck + `"`, args: []string{"sh", "-c", alpineCheck}})
23	j.out(s.num, "##[command]"+cmd.line)
24	var out []string
25	res, err := runProcess(procSpec{
26		Argv: cmd.argv, Dir: dirOrCwd(j.githubValue("workspace")), Env: j.processEnv(newOrdered()), Credential: j.cfg.Credential,
27		OnLine: func(l string) {
28			if l != "" {
29				out = append(out, l)
30			}
31		},
32		OnErrLine: func(l string) {
33			if l != "" {
34				out = append(out, l)
35			}
36		},
37		Cancel: cancel, TermAfter: j.cfg.TermAfter, KillAfter: j.cfg.KillAfter, WaitDelay: j.cfg.WaitDelay, Signal: j.cfg.Signal,
38	})
39	if err != nil {
40		return "", err
41	}
42	if res.Cancelled {
43		return "", errCancelled
44	}
45	if res.ExitCode == 0 {
46		for _, l := range out {
47			j.debug(s.num, l)
48			if strings.Contains(strings.ToLower(l), "alpine") {
49				return j.alpineNode(s, version)
50			}
51		}
52	}
53	j.debug(s.num, "Running JavaScript Action with default external tool: "+version)
54	return version, nil
55}
56
57// alpineNode is CheckPlatformForAlpineContainer (StepHost.cs:248-279): the
58// alpine builds exist for x64 only.
59func (j *job) alpineNode(s *stepRun, version string) (string, error) {
60	if runtime.GOARCH != "amd64" {
61		arch := map[string]string{"arm64": "Arm64", "arm": "Arm", "386": "X86"}[runtime.GOARCH]
62		if arch == "" {
63			arch = runtime.GOARCH
64		}
65		return "", fmt.Errorf("JavaScript Actions in Alpine containers are only supported on x64 Linux runners. Detected Linux %s", arch)
66	}
67	v := version + "_alpine"
68	j.debug(s.num, "Container distribution is alpine. Running JavaScript Action with external tool: "+v)
69	return v, nil
70}
71
72// runNodeInContainer is NodeScriptActionHandler.RunAsync (:127-190) with a
73// ContainerStepHost: the node of the externals mounted at /__e runs the script
74// at its container path, in the container's workspace.
75func (j *job) runNodeInContainer(s *stepRun, c *container, script string, env *ordered, cancel <-chan struct{}) stepResult {
76	num := s.num
77	fail := func(err error) stepResult { j.errorf(num, "%s", err.Error()); return resFailed }
78	if err := j.containerReady(); err != nil {
79		return fail(err)
80	}
81	version, err := j.nodeInContainer(s, c, s.nodeVersion, cancel)
82	if err != nil {
83		return j.containerResult(s, err)
84	}
85	file := c.resolvePath(filepath.Join(j.externalsDir(), version, "bin", "node"))
86	j.mu.Lock()
87	wd := j.state.GitHub("workspace")
88	j.mu.Unlock()
89	henv := j.handlerEnv(env)
90	if err := checkEnvNames(henv.Keys()); err != nil {
91		return fail(err)
92	}
93	argv, penv := j.execArgv(c, c.resolvePath(wd), henv, file, []string{c.resolvePath(`"` + script + `"`)})
94	s.rawEnvList = penv
95	return j.runProc(s, file, j.state.Layout().WorkRoot, argv, "Node Action run completed with exit code %d", cancel)
96}

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