Compare commits

...

10 Commits

Author SHA1 Message Date
ed08d1dcb4 chore: update configuration files and improve linting for Windows
Some checks failed
Codespell / Check for spelling errors (push) Has been cancelled
promote / promote (push) Has been cancelled
- Added `go1.24.0.linux-amd64.tar.gz` to `.gitignore`.
- Removed unnecessary newline in `.mergify.yml`.
- Updated `codecov.yml` to correct indentation for ignored files.
- Enhanced `Makefile` to support linting on Windows.
- Adjusted `.github/dependabot.yml` for proper indentation.
- Fixed string quotes in `.github/workflows/checks.yml`.
- Modified `pkg/container/util_windows.go` to ignore unused parameter.
- Updated error handling in `pkg/lookpath/lp_windows.go`.
- Refactored `pkg/runner/step_action_remote.go` to improve URL handling.
- Updated `pkg/runner/hashfiles/index.js` with significant changes for better performance and structure.
2025-08-03 04:28:08 +07:00
github-actions[bot]
bf8e52ba71 chore: bump VERSION to 0.2.80 2025-08-01 02:53:02 +00:00
ChristopherHX
61396d8085 fix: use ubuntu-latest bookworm instead of buster for tests (#5884)
* buster is now end of life
* apt-get update fails for some tests using ubuntu-latest
* buster cdn moved to archived domain
2025-07-25 20:33:59 +00:00
dependabot[bot]
5319acf6e2 build(deps): bump the dependencies group with 5 updates (#5861)
Bumps the dependencies group with 5 updates:

| Package | From | To |
| --- | --- | --- |
| [github.com/docker/cli](https://github.com/docker/cli) | `28.2.2+incompatible` | `28.3.0+incompatible` |
| [github.com/docker/docker](https://github.com/docker/docker) | `28.2.2+incompatible` | `28.3.0+incompatible` |
| [github.com/go-git/go-git/v5](https://github.com/go-git/go-git) | `5.16.0` | `5.16.2` |
| [go.etcd.io/bbolt](https://github.com/etcd-io/bbolt) | `1.4.0` | `1.4.2` |
| [golang.org/x/term](https://github.com/golang/term) | `0.31.0` | `0.32.0` |


Updates `github.com/docker/cli` from 28.2.2+incompatible to 28.3.0+incompatible
- [Commits](https://github.com/docker/cli/compare/v28.2.2...v28.3.0)

Updates `github.com/docker/docker` from 28.2.2+incompatible to 28.3.0+incompatible
- [Release notes](https://github.com/docker/docker/releases)
- [Commits](https://github.com/docker/docker/compare/v28.2.2...v28.3.0)

Updates `github.com/go-git/go-git/v5` from 5.16.0 to 5.16.2
- [Release notes](https://github.com/go-git/go-git/releases)
- [Commits](https://github.com/go-git/go-git/compare/v5.16.0...v5.16.2)

Updates `go.etcd.io/bbolt` from 1.4.0 to 1.4.2
- [Release notes](https://github.com/etcd-io/bbolt/releases)
- [Commits](https://github.com/etcd-io/bbolt/compare/v1.4.0...v1.4.2)

Updates `golang.org/x/term` from 0.31.0 to 0.32.0
- [Commits](https://github.com/golang/term/compare/v0.31.0...v0.32.0)

---
updated-dependencies:
- dependency-name: github.com/docker/cli
  dependency-version: 28.3.0+incompatible
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: dependencies
- dependency-name: github.com/docker/docker
  dependency-version: 28.3.0+incompatible
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: dependencies
- dependency-name: github.com/go-git/go-git/v5
  dependency-version: 5.16.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dependencies
- dependency-name: go.etcd.io/bbolt
  dependency-version: 1.4.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dependencies
- dependency-name: golang.org/x/term
  dependency-version: 0.32.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
2025-07-01 06:25:55 +00:00
github-actions[bot]
7e22245859 chore: bump VERSION to 0.2.79 2025-07-01 02:46:18 +00:00
dependabot[bot]
dd58f5e20f build(deps): bump github.com/go-viper/mapstructure/v2 (#5837)
Bumps [github.com/go-viper/mapstructure/v2](https://github.com/go-viper/mapstructure) from 2.2.1 to 2.3.0.
- [Release notes](https://github.com/go-viper/mapstructure/releases)
- [Changelog](https://github.com/go-viper/mapstructure/blob/main/CHANGELOG.md)
- [Commits](https://github.com/go-viper/mapstructure/compare/v2.2.1...v2.3.0)

---
updated-dependencies:
- dependency-name: github.com/go-viper/mapstructure/v2
  dependency-version: 2.3.0
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-27 17:16:33 +00:00
Ryan Fleet
0bc47aea68 added info log when container image platform mismatched (#3225)
* added info log when container image platform mismatched

* inline image architecture comparison into ImageExistsLocally function as per review request
2025-06-19 21:37:15 +00:00
ChristopherHX
7c7b383c10 fix: post step failure is job failure (#5297)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
2025-06-13 16:53:18 +00:00
ChristopherHX
515dd6612c feat: allow workflow description (#5326)
Otherwise act would reject such workflows right away
2025-06-13 16:33:10 +00:00
ChristopherHX
4ba1c2bde6 feat: --validate and --strict (#2717)
* feat: `--validate` and `--strict`

* fix missing changes

* add test for strict validate

---------

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
2025-06-11 22:02:16 +00:00
29 changed files with 5818 additions and 4799 deletions

View File

@@ -49,7 +49,7 @@ jobs:
- name: Test Summary - name: Test Summary
uses: test-summary/action@v2 uses: test-summary/action@v2
with: with:
paths: "unit-tests.xml" paths: 'unit-tests.xml'
if: always() if: always()
- name: Run act from cli - name: Run act from cli
run: go run main.go -P ubuntu-latest=node:16-buster-slim -C ./pkg/runner/testdata/ -W ./basic/push.yml run: go run main.go -P ubuntu-latest=node:16-buster-slim -C ./pkg/runner/testdata/ -W ./basic/push.yml
@@ -83,10 +83,9 @@ jobs:
- name: Test Summary - name: Test Summary
uses: test-summary/action@v2 uses: test-summary/action@v2
with: with:
paths: "unit-tests.xml" paths: 'unit-tests.xml'
if: always() if: always()
snapshot: snapshot:
name: snapshot name: snapshot
runs-on: ubuntu-latest runs-on: ubuntu-latest

1
.gitignore vendored
View File

@@ -32,3 +32,4 @@ unit-tests.xml
# megalinter # megalinter
report/ report/
go1.24.0.linux-amd64.tar.gz

View File

@@ -1,4 +1,3 @@
pull_request_rules: pull_request_rules:
- name: warn on conflicts - name: warn on conflicts
conditions: conditions:

View File

@@ -53,11 +53,19 @@ lint-md:
.PHONY: lint-rest .PHONY: lint-rest
lint-rest: lint-rest:
ifeq ($(OS),Windows_NT)
docker run --rm -it \
-v "$(shell cd):/tmp/lint" \
-e GITHUB_STATUS_REPORTER=false \
-e GITHUB_COMMENT_REPORTER=false \
megalinter/megalinter-go:v5
else
docker run --rm -it \ docker run --rm -it \
-v $(PWD):/tmp/lint \ -v $(PWD):/tmp/lint \
-e GITHUB_STATUS_REPORTER=false \ -e GITHUB_STATUS_REPORTER=false \
-e GITHUB_COMMENT_REPORTER=false \ -e GITHUB_COMMENT_REPORTER=false \
megalinter/megalinter-go:v5 megalinter/megalinter-go:v5
endif
.PHONY: lint .PHONY: lint
lint: lint-go lint-rest lint: lint-go lint-rest

View File

@@ -1 +1 @@
0.2.78 0.2.80

View File

@@ -62,6 +62,8 @@ type Input struct {
useNewActionCache bool useNewActionCache bool
localRepository []string localRepository []string
listOptions bool listOptions bool
validate bool
strict bool
concurrentJobs int concurrentJobs int
} }

View File

@@ -66,6 +66,8 @@ func createRootCommand(ctx context.Context, input *Input, version string) *cobra
} }
rootCmd.Flags().BoolP("watch", "w", false, "watch the contents of the local repo and run when files change") rootCmd.Flags().BoolP("watch", "w", false, "watch the contents of the local repo and run when files change")
rootCmd.Flags().BoolVar(&input.validate, "validate", false, "validate workflows")
rootCmd.Flags().BoolVar(&input.strict, "strict", false, "use strict workflow schema")
rootCmd.Flags().BoolP("list", "l", false, "list workflows") rootCmd.Flags().BoolP("list", "l", false, "list workflows")
rootCmd.Flags().BoolP("graph", "g", false, "draw workflows") rootCmd.Flags().BoolP("graph", "g", false, "draw workflows")
rootCmd.Flags().StringP("job", "j", "", "run a specific job ID") rootCmd.Flags().StringP("job", "j", "", "run a specific job ID")
@@ -446,7 +448,7 @@ func newRunCommand(ctx context.Context, input *Input) func(*cobra.Command, []str
matrixes := parseMatrix(input.matrix) matrixes := parseMatrix(input.matrix)
log.Debugf("Evaluated matrix inclusions: %v", matrixes) log.Debugf("Evaluated matrix inclusions: %v", matrixes)
planner, err := model.NewWorkflowPlanner(input.WorkflowsPath(), input.noWorkflowRecurse) planner, err := model.NewWorkflowPlanner(input.WorkflowsPath(), input.noWorkflowRecurse, input.strict)
if err != nil { if err != nil {
return err return err
} }
@@ -462,6 +464,11 @@ func newRunCommand(ctx context.Context, input *Input) func(*cobra.Command, []str
return err return err
} }
// check if we should just validate the workflows
if input.validate {
return err
}
// check if we should just draw the graph // check if we should just draw the graph
graph, err := cmd.Flags().GetBool("graph") graph, err := cmd.Flags().GetBool("graph")
if err != nil { if err != nil {

18
go.mod
View File

@@ -8,11 +8,11 @@ require (
github.com/adrg/xdg v0.5.3 github.com/adrg/xdg v0.5.3
github.com/andreaskoch/go-fswatch v1.0.0 github.com/andreaskoch/go-fswatch v1.0.0
github.com/creack/pty v1.1.24 github.com/creack/pty v1.1.24
github.com/docker/cli v28.2.2+incompatible github.com/docker/cli v28.3.0+incompatible
github.com/docker/docker v28.2.2+incompatible github.com/docker/docker v28.3.0+incompatible
github.com/docker/go-connections v0.5.0 github.com/docker/go-connections v0.5.0
github.com/go-git/go-billy/v5 v5.6.2 github.com/go-git/go-billy/v5 v5.6.2
github.com/go-git/go-git/v5 v5.16.0 github.com/go-git/go-git/v5 v5.16.2
github.com/joho/godotenv v1.5.1 github.com/joho/godotenv v1.5.1
github.com/julienschmidt/httprouter v1.3.0 github.com/julienschmidt/httprouter v1.3.0
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51
@@ -28,16 +28,18 @@ require (
github.com/spf13/pflag v1.0.6 github.com/spf13/pflag v1.0.6
github.com/stretchr/testify v1.10.0 github.com/stretchr/testify v1.10.0
github.com/timshannon/bolthold v0.0.0-20240314194003-30aac6950928 github.com/timshannon/bolthold v0.0.0-20240314194003-30aac6950928
go.etcd.io/bbolt v1.4.0 go.etcd.io/bbolt v1.4.2
golang.org/x/term v0.31.0 golang.org/x/term v0.32.0
gopkg.in/yaml.v3 v3.0.1 gopkg.in/yaml.v3 v3.0.1
gotest.tools/v3 v3.5.2 gotest.tools/v3 v3.5.2
) )
require ( require (
dario.cat/mergo v1.0.2 dario.cat/mergo v1.0.2
github.com/containerd/errdefs v1.0.0
github.com/distribution/reference v0.6.0 github.com/distribution/reference v0.6.0
github.com/golang-jwt/jwt/v5 v5.2.2 github.com/golang-jwt/jwt/v5 v5.2.2
github.com/moby/go-archive v0.1.0
google.golang.org/protobuf v1.36.6 google.golang.org/protobuf v1.36.6
) )
@@ -46,7 +48,6 @@ require (
github.com/ProtonMail/go-crypto v1.1.6 // indirect github.com/ProtonMail/go-crypto v1.1.6 // indirect
github.com/bmatcuk/doublestar/v4 v4.8.0 // indirect github.com/bmatcuk/doublestar/v4 v4.8.0 // indirect
github.com/cloudflare/circl v1.6.1 // indirect github.com/cloudflare/circl v1.6.1 // indirect
github.com/containerd/errdefs v1.0.0 // indirect
github.com/containerd/errdefs/pkg v0.3.0 // indirect github.com/containerd/errdefs/pkg v0.3.0 // indirect
github.com/containerd/log v0.1.0 // indirect github.com/containerd/log v0.1.0 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.6 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.6 // indirect
@@ -60,7 +61,7 @@ require (
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/logr v1.4.2 // indirect
github.com/go-logr/stdr v1.2.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-viper/mapstructure/v2 v2.2.1 // indirect github.com/go-viper/mapstructure/v2 v2.3.0 // indirect
github.com/gogo/protobuf v1.3.2 // indirect github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect
github.com/google/go-cmp v0.7.0 // indirect github.com/google/go-cmp v0.7.0 // indirect
@@ -74,7 +75,6 @@ require (
github.com/mattn/go-shellwords v1.0.12 // indirect github.com/mattn/go-shellwords v1.0.12 // indirect
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect
github.com/moby/docker-image-spec v1.3.1 // indirect github.com/moby/docker-image-spec v1.3.1 // indirect
github.com/moby/go-archive v0.1.0 // indirect
github.com/moby/sys/atomicwriter v0.1.0 // indirect github.com/moby/sys/atomicwriter v0.1.0 // indirect
github.com/moby/sys/sequential v0.6.0 // indirect github.com/moby/sys/sequential v0.6.0 // indirect
github.com/moby/sys/user v0.4.0 // indirect github.com/moby/sys/user v0.4.0 // indirect
@@ -105,7 +105,7 @@ require (
golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 // indirect golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 // indirect
golang.org/x/net v0.39.0 // indirect golang.org/x/net v0.39.0 // indirect
golang.org/x/sync v0.13.0 // indirect golang.org/x/sync v0.13.0 // indirect
golang.org/x/sys v0.32.0 // indirect golang.org/x/sys v0.33.0 // indirect
golang.org/x/text v0.24.0 // indirect golang.org/x/text v0.24.0 // indirect
golang.org/x/time v0.6.0 // indirect golang.org/x/time v0.6.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 // indirect

28
go.sum
View File

@@ -47,10 +47,10 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
github.com/docker/cli v28.2.2+incompatible h1:qzx5BNUDFqlvyq4AHzdNB7gSyVTmU4cgsyN9SdInc1A= github.com/docker/cli v28.3.0+incompatible h1:s+ttruVLhB5ayeuf2BciwDVxYdKi+RoUlxmwNHV3Vfo=
github.com/docker/cli v28.2.2+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/cli v28.3.0+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/docker v28.2.2+incompatible h1:CjwRSksz8Yo4+RmQ339Dp/D2tGO5JxwYeqtMOEe0LDw= github.com/docker/docker v28.3.0+incompatible h1:ffS62aKWupCWdvcee7nBU9fhnmknOqDPaJAMtfK0ImQ=
github.com/docker/docker v28.2.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v28.3.0+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker-credential-helpers v0.8.2 h1:bX3YxiGzFP5sOXWc3bTPEXdEaZSeVMrFgOr3T+zrFAo= github.com/docker/docker-credential-helpers v0.8.2 h1:bX3YxiGzFP5sOXWc3bTPEXdEaZSeVMrFgOr3T+zrFAo=
github.com/docker/docker-credential-helpers v0.8.2/go.mod h1:P3ci7E3lwkZg6XiHdRKft1KckHiO9a2rNtyFbZ/ry9M= github.com/docker/docker-credential-helpers v0.8.2/go.mod h1:P3ci7E3lwkZg6XiHdRKft1KckHiO9a2rNtyFbZ/ry9M=
github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c=
@@ -73,15 +73,15 @@ github.com/go-git/go-billy/v5 v5.6.2 h1:6Q86EsPXMa7c3YZ3aLAQsMA0VlWmy43r6FHqa/UN
github.com/go-git/go-billy/v5 v5.6.2/go.mod h1:rcFC2rAsp/erv7CMz9GczHcuD0D32fWzH+MJAU+jaUU= github.com/go-git/go-billy/v5 v5.6.2/go.mod h1:rcFC2rAsp/erv7CMz9GczHcuD0D32fWzH+MJAU+jaUU=
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4= github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4=
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII= github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII=
github.com/go-git/go-git/v5 v5.16.0 h1:k3kuOEpkc0DeY7xlL6NaaNg39xdgQbtH5mwCafHO9AQ= github.com/go-git/go-git/v5 v5.16.2 h1:fT6ZIOjE5iEnkzKyxTHK1W4HGAsPhqEqiSAssSO77hM=
github.com/go-git/go-git/v5 v5.16.0/go.mod h1:4Ge4alE/5gPs30F2H1esi2gPd69R0C39lolkucHBOp8= github.com/go-git/go-git/v5 v5.16.2/go.mod h1:4Ge4alE/5gPs30F2H1esi2gPd69R0C39lolkucHBOp8=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-viper/mapstructure/v2 v2.2.1 h1:ZAaOCxANMuZx5RCeg0mBdEZk7DZasvvZIxtHqx8aGss= github.com/go-viper/mapstructure/v2 v2.3.0 h1:27XbWsHIqhbdR5TIC911OfYvgSaW93HM+dX7970Q7jk=
github.com/go-viper/mapstructure/v2 v2.2.1/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/go-viper/mapstructure/v2 v2.3.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang-jwt/jwt/v5 v5.2.2 h1:Rl4B7itRWVtYIHFrSNd7vhTiz9UpLdi6gZhZ3wEeDy8= github.com/golang-jwt/jwt/v5 v5.2.2 h1:Rl4B7itRWVtYIHFrSNd7vhTiz9UpLdi6gZhZ3wEeDy8=
@@ -220,8 +220,8 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
go.etcd.io/bbolt v1.3.8/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= go.etcd.io/bbolt v1.3.8/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw=
go.etcd.io/bbolt v1.4.0 h1:TU77id3TnN/zKr7CO/uk+fBCwF2jGcMuw2B/FMAzYIk= go.etcd.io/bbolt v1.4.2 h1:IrUHp260R8c+zYx/Tm8QZr04CX+qWS5PGfPdevhdm1I=
go.etcd.io/bbolt v1.4.0/go.mod h1:AsD+OCi/qPN1giOX1aiLAha3o1U8rAz65bvN4j0sRuk= go.etcd.io/bbolt v1.4.2/go.mod h1:Is8rSHO/b4f3XigBC0lL0+4FwAQv3HXEEIgFMuKHceM=
go.etcd.io/gofail v0.1.0/go.mod h1:VZBCXYGZhHAinaBiiqYvuDynvahNsAyLFwB3kEHKz1M= go.etcd.io/gofail v0.1.0/go.mod h1:VZBCXYGZhHAinaBiiqYvuDynvahNsAyLFwB3kEHKz1M=
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
@@ -283,12 +283,12 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20= golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.31.0 h1:erwDkOK1Msy6offm1mOgvspSkslFnIGsFnxOKoufg3o= golang.org/x/term v0.32.0 h1:DR4lr0TjUs3epypdhTOkMmuF5CDFJ/8pOnbzMZPQ7bg=
golang.org/x/term v0.31.0/go.mod h1:R4BeIy7D95HzImkxGkTW1UQTtP54tio2RyHz7PwK0aw= golang.org/x/term v0.32.0/go.mod h1:uZG1FhGx848Sqfsq4/DlJr3xGGsYMu/L5GW4abiaEPQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=

View File

@@ -298,7 +298,7 @@ func runTestJobFile(ctx context.Context, t *testing.T, tjfi TestJobFileInfo) {
runner, err := runner.New(runnerConfig) runner, err := runner.New(runnerConfig)
assert.Nil(t, err, tjfi.workflowPath) assert.Nil(t, err, tjfi.workflowPath)
planner, err := model.NewWorkflowPlanner(fullWorkflowPath, true) planner, err := model.NewWorkflowPlanner(fullWorkflowPath, true, false)
assert.Nil(t, err, fullWorkflowPath) assert.Nil(t, err, fullWorkflowPath)
plan, err := planner.PlanEvent(tjfi.eventName) plan, err := planner.PlanEvent(tjfi.eventName)

View File

@@ -8,6 +8,7 @@ import (
cerrdefs "github.com/containerd/errdefs" cerrdefs "github.com/containerd/errdefs"
"github.com/docker/docker/api/types/image" "github.com/docker/docker/api/types/image"
"github.com/nektos/act/pkg/common"
) )
// ImageExistsLocally returns a boolean indicating if an image with the // ImageExistsLocally returns a boolean indicating if an image with the
@@ -26,10 +27,15 @@ func ImageExistsLocally(ctx context.Context, imageName string, platform string)
return false, err return false, err
} }
if platform == "" || platform == "any" || fmt.Sprintf("%s/%s", inspectImage.Os, inspectImage.Architecture) == platform { imagePlatform := fmt.Sprintf("%s/%s", inspectImage.Os, inspectImage.Architecture)
if platform == "" || platform == "any" || imagePlatform == platform {
return true, nil return true, nil
} }
logger := common.Logger(ctx)
logger.Infof("image found but platform does not match: %s (image) != %s (platform)\n", imagePlatform, platform)
return false, nil return false, nil
} }

View File

@@ -6,7 +6,7 @@ import (
"syscall" "syscall"
) )
func getSysProcAttr(cmdLine string, tty bool) *syscall.SysProcAttr { func getSysProcAttr(cmdLine string, _ bool) *syscall.SysProcAttr {
return &syscall.SysProcAttr{CmdLine: cmdLine, CreationFlags: syscall.CREATE_NEW_PROCESS_GROUP} return &syscall.SysProcAttr{CmdLine: cmdLine, CreationFlags: syscall.CREATE_NEW_PROCESS_GROUP}
} }

View File

@@ -77,9 +77,8 @@ func LookPath2(file string, lenv Env) (string, error) {
if strings.ContainsAny(file, `:\/`) { if strings.ContainsAny(file, `:\/`) {
if f, err := findExecutable(file, exts); err == nil { if f, err := findExecutable(file, exts); err == nil {
return f, nil return f, nil
} else {
return "", &Error{file, err}
} }
return "", &Error{file, ErrNotFound}
} }
if f, err := findExecutable(filepath.Join(".", file), exts); err == nil { if f, err := findExecutable(filepath.Join(".", file), exts); err == nil {
return f, nil return f, nil

View File

@@ -56,7 +56,7 @@ type WorkflowFiles struct {
} }
// NewWorkflowPlanner will load a specific workflow, all workflows from a directory or all workflows from a directory and its subdirectories // NewWorkflowPlanner will load a specific workflow, all workflows from a directory or all workflows from a directory and its subdirectories
func NewWorkflowPlanner(path string, noWorkflowRecurse bool) (WorkflowPlanner, error) { func NewWorkflowPlanner(path string, noWorkflowRecurse, strict bool) (WorkflowPlanner, error) {
path, err := filepath.Abs(path) path, err := filepath.Abs(path)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -124,7 +124,7 @@ func NewWorkflowPlanner(path string, noWorkflowRecurse bool) (WorkflowPlanner, e
} }
log.Debugf("Reading workflow '%s'", f.Name()) log.Debugf("Reading workflow '%s'", f.Name())
workflow, err := ReadWorkflow(f) workflow, err := ReadWorkflow(f, strict)
if err != nil { if err != nil {
_ = f.Close() _ = f.Close()
if err == io.EOF { if err == io.EOF {
@@ -161,7 +161,7 @@ func NewSingleWorkflowPlanner(name string, f io.Reader) (WorkflowPlanner, error)
wp := new(workflowPlanner) wp := new(workflowPlanner)
log.Debugf("Reading workflow %s", name) log.Debugf("Reading workflow %s", name)
workflow, err := ReadWorkflow(f) workflow, err := ReadWorkflow(f, false)
if err != nil { if err != nil {
if err == io.EOF { if err == io.EOF {
return nil, fmt.Errorf("unable to read workflow '%s': file is empty: %w", name, err) return nil, fmt.Errorf("unable to read workflow '%s': file is empty: %w", name, err)

View File

@@ -31,7 +31,7 @@ func TestPlanner(t *testing.T) {
assert.NoError(t, err, workdir) assert.NoError(t, err, workdir)
for _, table := range tables { for _, table := range tables {
fullWorkflowPath := filepath.Join(workdir, table.workflowPath) fullWorkflowPath := filepath.Join(workdir, table.workflowPath)
_, err = NewWorkflowPlanner(fullWorkflowPath, table.noWorkflowRecurse) _, err = NewWorkflowPlanner(fullWorkflowPath, table.noWorkflowRecurse, false)
if table.errorMessage == "" { if table.errorMessage == "" {
assert.NoError(t, err, "WorkflowPlanner should exit without any error") assert.NoError(t, err, "WorkflowPlanner should exit without any error")
} else { } else {

View File

@@ -80,6 +80,20 @@ func (w *Workflow) UnmarshalYAML(node *yaml.Node) error {
return node.Decode((*WorkflowDefault)(w)) return node.Decode((*WorkflowDefault)(w))
} }
type WorkflowStrict Workflow
func (w *WorkflowStrict) UnmarshalYAML(node *yaml.Node) error {
// Validate the schema before deserializing it into our model
if err := (&schema.Node{
Definition: "workflow-root-strict",
Schema: schema.GetWorkflowSchema(),
}).UnmarshalYAML(node); err != nil {
return errors.Join(err, fmt.Errorf("Actions YAML Strict Schema Validation Error detected:\nFor more information, see: https://nektosact.com/usage/schema.html"))
}
type WorkflowDefault Workflow
return node.Decode((*WorkflowDefault)(w))
}
type WorkflowDispatchInput struct { type WorkflowDispatchInput struct {
Description string `yaml:"description"` Description string `yaml:"description"`
Required bool `yaml:"required"` Required bool `yaml:"required"`
@@ -711,7 +725,12 @@ func (s *Step) Type() StepType {
} }
// ReadWorkflow returns a list of jobs for a given workflow file reader // ReadWorkflow returns a list of jobs for a given workflow file reader
func ReadWorkflow(in io.Reader) (*Workflow, error) { func ReadWorkflow(in io.Reader, strict bool) (*Workflow, error) {
if strict {
w := new(WorkflowStrict)
err := yaml.NewDecoder(in).Decode(w)
return (*Workflow)(w), err
}
w := new(Workflow) w := new(Workflow)
err := yaml.NewDecoder(in).Decode(w) err := yaml.NewDecoder(in).Decode(w)
return w, err return w, err

View File

@@ -19,7 +19,7 @@ jobs:
- uses: ./actions/docker-url - uses: ./actions/docker-url
` `
workflow, err := ReadWorkflow(strings.NewReader(yaml)) workflow, err := ReadWorkflow(strings.NewReader(yaml), false)
assert.NoError(t, err, "read workflow should succeed") assert.NoError(t, err, "read workflow should succeed")
assert.Len(t, workflow.On(), 1) assert.Len(t, workflow.On(), 1)
@@ -38,7 +38,7 @@ jobs:
- uses: ./actions/docker-url - uses: ./actions/docker-url
` `
workflow, err := ReadWorkflow(strings.NewReader(yaml)) workflow, err := ReadWorkflow(strings.NewReader(yaml), false)
assert.NoError(t, err, "read workflow should succeed") assert.NoError(t, err, "read workflow should succeed")
assert.Len(t, workflow.On(), 2) assert.Len(t, workflow.On(), 2)
@@ -64,7 +64,7 @@ jobs:
- uses: ./actions/docker-url - uses: ./actions/docker-url
` `
workflow, err := ReadWorkflow(strings.NewReader(yaml)) workflow, err := ReadWorkflow(strings.NewReader(yaml), false)
assert.NoError(t, err, "read workflow should succeed") assert.NoError(t, err, "read workflow should succeed")
assert.Len(t, workflow.On(), 2) assert.Len(t, workflow.On(), 2)
assert.Contains(t, workflow.On(), "push") assert.Contains(t, workflow.On(), "push")
@@ -83,7 +83,7 @@ jobs:
steps: steps:
- uses: ./actions/docker-url` - uses: ./actions/docker-url`
workflow, err := ReadWorkflow(strings.NewReader(yaml)) workflow, err := ReadWorkflow(strings.NewReader(yaml), false)
assert.NoError(t, err, "read workflow should succeed") assert.NoError(t, err, "read workflow should succeed")
assert.Equal(t, workflow.Jobs["test"].RunsOn(), []string{"ubuntu-latest"}) assert.Equal(t, workflow.Jobs["test"].RunsOn(), []string{"ubuntu-latest"})
} }
@@ -101,7 +101,7 @@ jobs:
steps: steps:
- uses: ./actions/docker-url` - uses: ./actions/docker-url`
workflow, err := ReadWorkflow(strings.NewReader(yaml)) workflow, err := ReadWorkflow(strings.NewReader(yaml), false)
assert.NoError(t, err, "read workflow should succeed") assert.NoError(t, err, "read workflow should succeed")
assert.Equal(t, workflow.Jobs["test"].RunsOn(), []string{"ubuntu-latest", "linux"}) assert.Equal(t, workflow.Jobs["test"].RunsOn(), []string{"ubuntu-latest", "linux"})
} }
@@ -126,7 +126,7 @@ jobs:
- uses: ./actions/docker-url - uses: ./actions/docker-url
` `
workflow, err := ReadWorkflow(strings.NewReader(yaml)) workflow, err := ReadWorkflow(strings.NewReader(yaml), false)
assert.NoError(t, err, "read workflow should succeed") assert.NoError(t, err, "read workflow should succeed")
assert.Len(t, workflow.Jobs, 2) assert.Len(t, workflow.Jobs, 2)
assert.Contains(t, workflow.Jobs["test"].Container().Image, "nginx:latest") assert.Contains(t, workflow.Jobs["test"].Container().Image, "nginx:latest")
@@ -156,7 +156,7 @@ jobs:
- uses: ./actions/docker-url - uses: ./actions/docker-url
` `
workflow, err := ReadWorkflow(strings.NewReader(yaml)) workflow, err := ReadWorkflow(strings.NewReader(yaml), false)
assert.NoError(t, err, "read workflow should succeed") assert.NoError(t, err, "read workflow should succeed")
assert.Len(t, workflow.Jobs, 1) assert.Len(t, workflow.Jobs, 1)
@@ -194,7 +194,7 @@ jobs:
uses: ./some/path/to/workflow.yaml uses: ./some/path/to/workflow.yaml
` `
workflow, err := ReadWorkflow(strings.NewReader(yaml)) workflow, err := ReadWorkflow(strings.NewReader(yaml), false)
assert.NoError(t, err, "read workflow should succeed") assert.NoError(t, err, "read workflow should succeed")
assert.Len(t, workflow.Jobs, 6) assert.Len(t, workflow.Jobs, 6)
@@ -238,7 +238,7 @@ jobs:
uses: some/path/to/workflow.yaml uses: some/path/to/workflow.yaml
` `
workflow, err := ReadWorkflow(strings.NewReader(yaml)) workflow, err := ReadWorkflow(strings.NewReader(yaml), false)
assert.NoError(t, err, "read workflow should succeed") assert.NoError(t, err, "read workflow should succeed")
assert.Len(t, workflow.Jobs, 4) assert.Len(t, workflow.Jobs, 4)
@@ -280,7 +280,7 @@ jobs:
uses: ./local-action uses: ./local-action
` `
_, err := ReadWorkflow(strings.NewReader(yaml)) _, err := ReadWorkflow(strings.NewReader(yaml), false)
assert.Error(t, err, "read workflow should fail") assert.Error(t, err, "read workflow should fail")
} }
@@ -312,7 +312,7 @@ jobs:
echo "${{ needs.test1.outputs.some-b-key }}" echo "${{ needs.test1.outputs.some-b-key }}"
` `
workflow, err := ReadWorkflow(strings.NewReader(yaml)) workflow, err := ReadWorkflow(strings.NewReader(yaml), false)
assert.NoError(t, err, "read workflow should succeed") assert.NoError(t, err, "read workflow should succeed")
assert.Len(t, workflow.Jobs, 2) assert.Len(t, workflow.Jobs, 2)
@@ -327,7 +327,7 @@ jobs:
} }
func TestReadWorkflow_Strategy(t *testing.T) { func TestReadWorkflow_Strategy(t *testing.T) {
w, err := NewWorkflowPlanner("testdata/strategy/push.yml", true) w, err := NewWorkflowPlanner("testdata/strategy/push.yml", true, false)
assert.NoError(t, err) assert.NoError(t, err)
p, err := w.PlanJob("strategy-only-max-parallel") p, err := w.PlanJob("strategy-only-max-parallel")
@@ -418,7 +418,7 @@ func TestReadWorkflow_WorkflowDispatchConfig(t *testing.T) {
yaml := ` yaml := `
name: local-action-docker-url name: local-action-docker-url
` `
workflow, err := ReadWorkflow(strings.NewReader(yaml)) workflow, err := ReadWorkflow(strings.NewReader(yaml), false)
assert.NoError(t, err, "read workflow should succeed") assert.NoError(t, err, "read workflow should succeed")
workflowDispatch := workflow.WorkflowDispatchConfig() workflowDispatch := workflow.WorkflowDispatchConfig()
assert.Nil(t, workflowDispatch) assert.Nil(t, workflowDispatch)
@@ -427,7 +427,7 @@ func TestReadWorkflow_WorkflowDispatchConfig(t *testing.T) {
name: local-action-docker-url name: local-action-docker-url
on: push on: push
` `
workflow, err = ReadWorkflow(strings.NewReader(yaml)) workflow, err = ReadWorkflow(strings.NewReader(yaml), false)
assert.NoError(t, err, "read workflow should succeed") assert.NoError(t, err, "read workflow should succeed")
workflowDispatch = workflow.WorkflowDispatchConfig() workflowDispatch = workflow.WorkflowDispatchConfig()
assert.Nil(t, workflowDispatch) assert.Nil(t, workflowDispatch)
@@ -436,7 +436,7 @@ func TestReadWorkflow_WorkflowDispatchConfig(t *testing.T) {
name: local-action-docker-url name: local-action-docker-url
on: workflow_dispatch on: workflow_dispatch
` `
workflow, err = ReadWorkflow(strings.NewReader(yaml)) workflow, err = ReadWorkflow(strings.NewReader(yaml), false)
assert.NoError(t, err, "read workflow should succeed") assert.NoError(t, err, "read workflow should succeed")
workflowDispatch = workflow.WorkflowDispatchConfig() workflowDispatch = workflow.WorkflowDispatchConfig()
assert.NotNil(t, workflowDispatch) assert.NotNil(t, workflowDispatch)
@@ -446,7 +446,7 @@ func TestReadWorkflow_WorkflowDispatchConfig(t *testing.T) {
name: local-action-docker-url name: local-action-docker-url
on: [push, pull_request] on: [push, pull_request]
` `
workflow, err = ReadWorkflow(strings.NewReader(yaml)) workflow, err = ReadWorkflow(strings.NewReader(yaml), false)
assert.NoError(t, err, "read workflow should succeed") assert.NoError(t, err, "read workflow should succeed")
workflowDispatch = workflow.WorkflowDispatchConfig() workflowDispatch = workflow.WorkflowDispatchConfig()
assert.Nil(t, workflowDispatch) assert.Nil(t, workflowDispatch)
@@ -455,7 +455,7 @@ func TestReadWorkflow_WorkflowDispatchConfig(t *testing.T) {
name: local-action-docker-url name: local-action-docker-url
on: [push, workflow_dispatch] on: [push, workflow_dispatch]
` `
workflow, err = ReadWorkflow(strings.NewReader(yaml)) workflow, err = ReadWorkflow(strings.NewReader(yaml), false)
assert.NoError(t, err, "read workflow should succeed") assert.NoError(t, err, "read workflow should succeed")
workflowDispatch = workflow.WorkflowDispatchConfig() workflowDispatch = workflow.WorkflowDispatchConfig()
assert.NotNil(t, workflowDispatch) assert.NotNil(t, workflowDispatch)
@@ -467,7 +467,7 @@ func TestReadWorkflow_WorkflowDispatchConfig(t *testing.T) {
- push - push
- workflow_dispatch - workflow_dispatch
` `
workflow, err = ReadWorkflow(strings.NewReader(yaml)) workflow, err = ReadWorkflow(strings.NewReader(yaml), false)
assert.NoError(t, err, "read workflow should succeed") assert.NoError(t, err, "read workflow should succeed")
workflowDispatch = workflow.WorkflowDispatchConfig() workflowDispatch = workflow.WorkflowDispatchConfig()
assert.NotNil(t, workflowDispatch) assert.NotNil(t, workflowDispatch)
@@ -479,7 +479,7 @@ func TestReadWorkflow_WorkflowDispatchConfig(t *testing.T) {
push: push:
pull_request: pull_request:
` `
workflow, err = ReadWorkflow(strings.NewReader(yaml)) workflow, err = ReadWorkflow(strings.NewReader(yaml), false)
assert.NoError(t, err, "read workflow should succeed") assert.NoError(t, err, "read workflow should succeed")
workflowDispatch = workflow.WorkflowDispatchConfig() workflowDispatch = workflow.WorkflowDispatchConfig()
assert.Nil(t, workflowDispatch) assert.Nil(t, workflowDispatch)
@@ -501,7 +501,7 @@ func TestReadWorkflow_WorkflowDispatchConfig(t *testing.T) {
- warning - warning
- debug - debug
` `
workflow, err = ReadWorkflow(strings.NewReader(yaml)) workflow, err = ReadWorkflow(strings.NewReader(yaml), false)
assert.NoError(t, err, "read workflow should succeed") assert.NoError(t, err, "read workflow should succeed")
workflowDispatch = workflow.WorkflowDispatchConfig() workflowDispatch = workflow.WorkflowDispatchConfig()
assert.NotNil(t, workflowDispatch) assert.NotNil(t, workflowDispatch)
@@ -517,3 +517,19 @@ func TestReadWorkflow_WorkflowDispatchConfig(t *testing.T) {
Type: "choice", Type: "choice",
}, workflowDispatch.Inputs["logLevel"]) }, workflowDispatch.Inputs["logLevel"])
} }
func TestReadWorkflow_InvalidStringEvent(t *testing.T) {
yaml := `
name: local-action-docker-url
on: push2
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: ./actions/docker-url
`
_, err := ReadWorkflow(strings.NewReader(yaml), true)
assert.Error(t, err, "read workflow should succeed")
}

File diff suppressed because it is too large Load Diff

View File

@@ -92,7 +92,7 @@ func newJobExecutor(info jobInfo, sf stepFactory, rc *RunContext) common.Executo
return nil return nil
})) }))
postExec := useStepLogger(rc, stepModel, stepStagePost, step.post()) postExec := useStepLogger(rc, stepModel, stepStagePost, step.post().ThenError(setJobError))
if postExecutor != nil { if postExecutor != nil {
// run the post executor in reverse order // run the post executor in reverse order
postExecutor = postExec.Finally(postExecutor) postExecutor = postExec.Finally(postExecutor)

View File

@@ -115,7 +115,7 @@ func cloneIfRequired(rc *RunContext, remoteReusableWorkflow remoteReusableWorkfl
func newReusableWorkflowExecutor(rc *RunContext, directory string, workflow string) common.Executor { func newReusableWorkflowExecutor(rc *RunContext, directory string, workflow string) common.Executor {
return func(ctx context.Context) error { return func(ctx context.Context) error {
planner, err := model.NewWorkflowPlanner(path.Join(directory, workflow), true) planner, err := model.NewWorkflowPlanner(path.Join(directory, workflow), true, false)
if err != nil { if err != nil {
return err return err
} }

View File

@@ -25,7 +25,7 @@ import (
) )
var ( var (
baseImage = "node:16-buster-slim" baseImage = "node:24-bookworm-slim"
platforms map[string]string platforms map[string]string
logLevel = log.DebugLevel logLevel = log.DebugLevel
workdir = "testdata" workdir = "testdata"
@@ -55,7 +55,7 @@ func init() {
} }
func TestNoWorkflowsFoundByPlanner(t *testing.T) { func TestNoWorkflowsFoundByPlanner(t *testing.T) {
planner, err := model.NewWorkflowPlanner("res", true) planner, err := model.NewWorkflowPlanner("res", true, false)
assert.NoError(t, err) assert.NoError(t, err)
out := log.StandardLogger().Out out := log.StandardLogger().Out
@@ -75,7 +75,7 @@ func TestNoWorkflowsFoundByPlanner(t *testing.T) {
} }
func TestGraphMissingEvent(t *testing.T) { func TestGraphMissingEvent(t *testing.T) {
planner, err := model.NewWorkflowPlanner("testdata/issue-1595/no-event.yml", true) planner, err := model.NewWorkflowPlanner("testdata/issue-1595/no-event.yml", true, false)
assert.NoError(t, err) assert.NoError(t, err)
out := log.StandardLogger().Out out := log.StandardLogger().Out
@@ -93,7 +93,7 @@ func TestGraphMissingEvent(t *testing.T) {
} }
func TestGraphMissingFirst(t *testing.T) { func TestGraphMissingFirst(t *testing.T) {
planner, err := model.NewWorkflowPlanner("testdata/issue-1595/no-first.yml", true) planner, err := model.NewWorkflowPlanner("testdata/issue-1595/no-first.yml", true, false)
assert.NoError(t, err) assert.NoError(t, err)
plan, err := planner.PlanEvent("push") plan, err := planner.PlanEvent("push")
@@ -103,7 +103,7 @@ func TestGraphMissingFirst(t *testing.T) {
} }
func TestGraphWithMissing(t *testing.T) { func TestGraphWithMissing(t *testing.T) {
planner, err := model.NewWorkflowPlanner("testdata/issue-1595/missing.yml", true) planner, err := model.NewWorkflowPlanner("testdata/issue-1595/missing.yml", true, false)
assert.NoError(t, err) assert.NoError(t, err)
out := log.StandardLogger().Out out := log.StandardLogger().Out
@@ -122,7 +122,7 @@ func TestGraphWithMissing(t *testing.T) {
func TestGraphWithSomeMissing(t *testing.T) { func TestGraphWithSomeMissing(t *testing.T) {
log.SetLevel(log.DebugLevel) log.SetLevel(log.DebugLevel)
planner, err := model.NewWorkflowPlanner("testdata/issue-1595/", true) planner, err := model.NewWorkflowPlanner("testdata/issue-1595/", true, false)
assert.NoError(t, err) assert.NoError(t, err)
out := log.StandardLogger().Out out := log.StandardLogger().Out
@@ -140,7 +140,7 @@ func TestGraphWithSomeMissing(t *testing.T) {
} }
func TestGraphEvent(t *testing.T) { func TestGraphEvent(t *testing.T) {
planner, err := model.NewWorkflowPlanner("testdata/basic", true) planner, err := model.NewWorkflowPlanner("testdata/basic", true, false)
assert.NoError(t, err) assert.NoError(t, err)
plan, err := planner.PlanEvent("push") plan, err := planner.PlanEvent("push")
@@ -198,7 +198,7 @@ func (j *TestJobFileInfo) runTest(ctx context.Context, t *testing.T, cfg *Config
runner, err := New(runnerConfig) runner, err := New(runnerConfig)
assert.Nil(t, err, j.workflowPath) assert.Nil(t, err, j.workflowPath)
planner, err := model.NewWorkflowPlanner(fullWorkflowPath, true) planner, err := model.NewWorkflowPlanner(fullWorkflowPath, true, false)
if j.errorMessage != "" && err != nil { if j.errorMessage != "" && err != nil {
assert.Error(t, err, j.errorMessage) assert.Error(t, err, j.errorMessage)
} else if assert.Nil(t, err, fullWorkflowPath) { } else if assert.Nil(t, err, fullWorkflowPath) {
@@ -376,13 +376,24 @@ func (factory *captureJobLoggerFactory) WithJobLogger() *logrus.Logger {
return logger return logger
} }
func TestPullFailureIsJobFailure(t *testing.T) { func TestPullAndPostStepFailureIsJobFailure(t *testing.T) {
if testing.Short() { if testing.Short() {
t.Skip("skipping integration test") t.Skip("skipping integration test")
} }
tables := []TestJobFileInfo{ defCache := &GoGitActionCache{
{workdir, "checkout", "push", "pull failure", map[string]string{"ubuntu-latest": "localhost:0000/missing:latest"}, secrets}, path.Clean(path.Join(workdir, "cache")),
}
mockCache := &mockCache{}
tables := []struct {
TestJobFileInfo
ActionCache ActionCache
SetupResult string
}{
{TestJobFileInfo{workdir, "checkout", "push", "pull failure", map[string]string{"ubuntu-latest": "localhost:0000/missing:latest"}, secrets}, defCache, "failure"},
{TestJobFileInfo{workdir, "post-step-failure-is-job-failure", "push", "post failure", map[string]string{"ubuntu-latest": "-self-hosted"}, secrets}, mockCache, "success"},
} }
for _, table := range tables { for _, table := range tables {
@@ -397,9 +408,7 @@ func TestPullFailureIsJobFailure(t *testing.T) {
if _, err := os.Stat(eventFile); err == nil { if _, err := os.Stat(eventFile); err == nil {
config.EventPath = eventFile config.EventPath = eventFile
} }
config.ActionCache = &GoGitActionCache{ config.ActionCache = table.ActionCache
path.Clean(path.Join(workdir, "cache")),
}
logger := logrus.New() logger := logrus.New()
logger.SetOutput(&factory.buffer) logger.SetOutput(&factory.buffer)
@@ -418,7 +427,7 @@ func TestPullFailureIsJobFailure(t *testing.T) {
hasJobResult = true hasJobResult = true
} }
if val, ok := entry["stepResult"]; ok && !hasStepResult { if val, ok := entry["stepResult"]; ok && !hasStepResult {
assert.Equal(t, "failure", val) assert.Equal(t, table.SetupResult, val)
hasStepResult = true hasStepResult = true
} }
} }

View File

@@ -50,7 +50,6 @@ func (sar *stepActionRemote) prepareActionExecutor() common.Executor {
} }
github := sar.getGithubContext(ctx) github := sar.getGithubContext(ctx)
sar.remoteAction.URL = github.ServerURL
if sar.remoteAction.IsCheckout() && isLocalCheckout(github, sar.Step) && !sar.RunContext.Config.NoSkipCheckout { if sar.remoteAction.IsCheckout() && isLocalCheckout(github, sar.Step) && !sar.RunContext.Config.NoSkipCheckout {
common.Logger(ctx).Debugf("Skipping local actions/checkout because workdir was already copied") common.Logger(ctx).Debugf("Skipping local actions/checkout because workdir was already copied")
@@ -111,7 +110,7 @@ func (sar *stepActionRemote) prepareActionExecutor() common.Executor {
URL: sar.remoteAction.CloneURL(), URL: sar.remoteAction.CloneURL(),
Ref: sar.remoteAction.Ref, Ref: sar.remoteAction.Ref,
Dir: actionDir, Dir: actionDir,
Token: github.Token, Token: "",
OfflineMode: sar.RunContext.Config.ActionOfflineMode, OfflineMode: sar.RunContext.Config.ActionOfflineMode,
}) })
var ntErr common.Executor var ntErr common.Executor
@@ -270,6 +269,26 @@ func (ra *remoteAction) IsCheckout() bool {
} }
func newRemoteAction(action string) *remoteAction { func newRemoteAction(action string) *remoteAction {
// support http(s)://host/owner/repo@v3
for _, schema := range []string{"https://", "http://"} {
if strings.HasPrefix(action, schema) {
splits := strings.SplitN(strings.TrimPrefix(action, schema), "/", 2)
if len(splits) != 2 {
return nil
}
ret := parseAction(splits[1])
if ret == nil {
return nil
}
ret.URL = schema + splits[0]
return ret
}
}
return parseAction(action)
}
func parseAction(action string) *remoteAction {
// GitHub's document[^] describes: // GitHub's document[^] describes:
// > We strongly recommend that you include the version of // > We strongly recommend that you include the version of
// > the action you are using by specifying a Git ref, SHA, or Docker tag number. // > the action you are using by specifying a Git ref, SHA, or Docker tag number.
@@ -285,7 +304,7 @@ func newRemoteAction(action string) *remoteAction {
Repo: matches[2], Repo: matches[2],
Path: matches[4], Path: matches[4],
Ref: matches[6], Ref: matches[6],
URL: "https://github.com", URL: "",
} }
} }

View File

@@ -0,0 +1,4 @@
runs:
using: node20
main: main.js
post: post.js

View File

@@ -0,0 +1,2 @@
console.log('This is a post step failure test');
process.exit(1);

View File

@@ -0,0 +1,9 @@
name: basic
on: push
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: ./post-step-failure-is-job-failure/post-step-failure

View File

@@ -7,6 +7,7 @@
"properties": { "properties": {
"on": "on", "on": "on",
"name": "workflow-name", "name": "workflow-name",
"description": "string",
"run-name": "run-name", "run-name": "run-name",
"defaults": "workflow-defaults", "defaults": "workflow-defaults",
"env": "workflow-env", "env": "workflow-env",
@@ -28,6 +29,7 @@
"required": true "required": true
}, },
"name": "workflow-name", "name": "workflow-name",
"description": "string",
"run-name": "run-name", "run-name": "run-name",
"defaults": "workflow-defaults", "defaults": "workflow-defaults",
"env": "workflow-env", "env": "workflow-env",