mirror of
https://gitea.com/gitea/act_runner.git
synced 2026-08-01 12:26:36 +00:00
A docker action can declare `runs.pre-entrypoint` and `runs.post-entrypoint` next to `runs.entrypoint` — the docker equivalent of a javascript action's `runs.pre`/`runs.post`. Neither key existed on `ActionRuns`, so the YAML decoder dropped them and docker actions silently skipped their setup and cleanup stages. Only the entrypoint is stage specific. [`ContainerActionHandler`](https://github.com/actions/runner/blob/main/src/Runner.Worker/Handlers/ContainerActionHandler.cs) selects `Data.Pre`/`Data.Post` per stage but evaluates `runs.args` and `runs.env` unconditionally, so `docker create` receives the action's args and env on every stage. The `entrypoint` input stays main only, because it is read inside the main branch. The stage is carried as the existing `stepStage` value rather than a separate parameter, and the pre and post stages reuse the action path resolution that `runPreStep`/`runPostStep` already open-coded three times, so the diff also drops those copies. Known gap: `stepActionLocal.pre()` is a no-op for every `using`, so `pre-entrypoint` does not run for `uses: ./local-action` while `post-entrypoint` does. Closing it requires reading the action model before the main stage and adding a pre case to `getIfExpression` for `pre-if`, which also changes local node, go and composite actions — better as its own change. --------- Co-authored-by: silverwind <2021+silverwind@noreply.gitea.com> Co-authored-by: silverwind <me@silverwind.io> Reviewed-on: https://gitea.com/gitea/runner/pulls/1106 Reviewed-by: silverwind <2021+silverwind@noreply.gitea.com> Co-authored-by: bircni <bircni@icloud.com>
139 lines
4.5 KiB
Go
139 lines
4.5 KiB
Go
// Copyright 2023 The Gitea Authors. All rights reserved.
|
|
// Copyright 2020 The nektos/act Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package model
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"strings"
|
|
|
|
"go.yaml.in/yaml/v4"
|
|
)
|
|
|
|
// ActionRunsUsing is the type of runner for the action
|
|
type ActionRunsUsing string
|
|
|
|
func (a *ActionRunsUsing) UnmarshalYAML(unmarshal func(any) error) error {
|
|
var using string
|
|
if err := unmarshal(&using); err != nil {
|
|
return err
|
|
}
|
|
|
|
// Force input to lowercase for case insensitive comparison
|
|
format := ActionRunsUsing(strings.ToLower(using))
|
|
switch format {
|
|
case ActionRunsUsingNode24, ActionRunsUsingNode20, ActionRunsUsingNode16, ActionRunsUsingNode12, ActionRunsUsingDocker, ActionRunsUsingComposite, ActionRunsUsingGo:
|
|
*a = format
|
|
default:
|
|
return fmt.Errorf("The runs.using key in action.yml must be one of: %v, got %s", []string{
|
|
ActionRunsUsingComposite,
|
|
ActionRunsUsingDocker,
|
|
ActionRunsUsingNode12,
|
|
ActionRunsUsingNode16,
|
|
ActionRunsUsingNode20,
|
|
ActionRunsUsingNode24,
|
|
ActionRunsUsingGo,
|
|
}, format)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
const (
|
|
// ActionRunsUsingNode12 for running with node12
|
|
ActionRunsUsingNode12 = "node12"
|
|
// ActionRunsUsingNode16 for running with node16
|
|
ActionRunsUsingNode16 = "node16"
|
|
// ActionRunsUsingNode20 for running with node20
|
|
ActionRunsUsingNode20 = "node20"
|
|
// ActionRunsUsingNode24 for running with node24
|
|
ActionRunsUsingNode24 = "node24"
|
|
// ActionRunsUsingDocker for running with docker
|
|
ActionRunsUsingDocker = "docker"
|
|
// ActionRunsUsingComposite for running composite
|
|
ActionRunsUsingComposite = "composite"
|
|
// ActionRunsUsingGo for running with go
|
|
ActionRunsUsingGo = "go"
|
|
)
|
|
|
|
func (a ActionRunsUsing) IsNode() bool {
|
|
switch a {
|
|
case ActionRunsUsingNode12, ActionRunsUsingNode16, ActionRunsUsingNode20, ActionRunsUsingNode24:
|
|
return true
|
|
default:
|
|
return false
|
|
}
|
|
}
|
|
|
|
func (a ActionRunsUsing) IsDocker() bool {
|
|
return a == ActionRunsUsingDocker
|
|
}
|
|
|
|
func (a ActionRunsUsing) IsComposite() bool {
|
|
return a == ActionRunsUsingComposite
|
|
}
|
|
|
|
// ActionRuns are a field in Action
|
|
type ActionRuns struct {
|
|
Using ActionRunsUsing `yaml:"using"`
|
|
Env map[string]string `yaml:"env"`
|
|
Main string `yaml:"main"`
|
|
Pre string `yaml:"pre"`
|
|
PreIf string `yaml:"pre-if"`
|
|
Post string `yaml:"post"`
|
|
PostIf string `yaml:"post-if"`
|
|
Image string `yaml:"image"`
|
|
PreEntrypoint string `yaml:"pre-entrypoint"`
|
|
Entrypoint string `yaml:"entrypoint"`
|
|
PostEntrypoint string `yaml:"post-entrypoint"`
|
|
Args []string `yaml:"args"`
|
|
Steps []Step `yaml:"steps"`
|
|
}
|
|
|
|
// Action describes a metadata file for GitHub actions. The metadata filename must be either action.yml or action.yaml. The data in the metadata file defines the inputs, outputs and main entrypoint for your action.
|
|
type Action struct {
|
|
Name string `yaml:"name"`
|
|
Author string `yaml:"author"`
|
|
Description string `yaml:"description"`
|
|
Inputs map[string]Input `yaml:"inputs"`
|
|
Outputs map[string]Output `yaml:"outputs"`
|
|
Runs ActionRuns `yaml:"runs"`
|
|
Branding struct {
|
|
Color string `yaml:"color"`
|
|
Icon string `yaml:"icon"`
|
|
} `yaml:"branding"`
|
|
}
|
|
|
|
// Input parameters allow you to specify data that the action expects to use during runtime. GitHub stores input parameters as environment variables. Input ids with uppercase letters are converted to lowercase during runtime. We recommended using lowercase input ids.
|
|
type Input struct {
|
|
Description string `yaml:"description"`
|
|
Required bool `yaml:"required"`
|
|
Default string `yaml:"default"`
|
|
}
|
|
|
|
// Output parameters allow you to declare data that an action sets. Actions that run later in a workflow can use the output data set in previously run actions. For example, if you had an action that performed the addition of two inputs (x + y = z), the action could output the sum (z) for other actions to use as an input.
|
|
type Output struct {
|
|
Description string `yaml:"description"`
|
|
Value string `yaml:"value"`
|
|
}
|
|
|
|
// ReadAction reads an action from a reader
|
|
func ReadAction(in io.Reader) (*Action, error) {
|
|
a := new(Action)
|
|
err := yaml.NewDecoder(in).Decode(a)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// set defaults
|
|
if a.Runs.PreIf == "" {
|
|
a.Runs.PreIf = "always()"
|
|
}
|
|
if a.Runs.PostIf == "" {
|
|
a.Runs.PostIf = "always()"
|
|
}
|
|
|
|
return a, nil
|
|
}
|