Compare commits

..

81 Commits

Author SHA1 Message Date
Jason Song
22d91e3ac3 Merge tag 'nektos/v0.2.49'
Conflicts:
	cmd/input.go
	go.mod
	go.sum
	pkg/exprparser/interpreter.go
	pkg/model/workflow.go
	pkg/runner/expression.go
	pkg/runner/job_executor.go
	pkg/runner/runner.go
2023-08-02 11:52:14 +08:00
GitHub Actions
d5d8548546 chore: bump VERSION to 0.2.49 2023-08-01 02:21:38 +00:00
dependabot[bot]
8bf10cf876 build(deps): bump github.com/go-git/go-git/v5 from 5.8.0 to 5.8.1 (#1934)
Bumps [github.com/go-git/go-git/v5](https://github.com/go-git/go-git) from 5.8.0 to 5.8.1.
- [Release notes](https://github.com/go-git/go-git/releases)
- [Commits](https://github.com/go-git/go-git/compare/v5.8.0...v5.8.1)

---
updated-dependencies:
- dependency-name: github.com/go-git/go-git/v5
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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>
2023-07-31 03:49:57 +00:00
dependabot[bot]
8e6c7c11fe build(deps): bump github.com/docker/cli (#1932)
Bumps [github.com/docker/cli](https://github.com/docker/cli) from 24.0.4+incompatible to 24.0.5+incompatible.
- [Commits](https://github.com/docker/cli/compare/v24.0.4...v24.0.5)

---
updated-dependencies:
- dependency-name: github.com/docker/cli
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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>
2023-07-31 03:29:28 +00:00
dependabot[bot]
d720ff09a2 build(deps): bump github.com/docker/docker (#1933)
Bumps [github.com/docker/docker](https://github.com/docker/docker) from 24.0.5-0.20230714235725-36e9e796c6fc+incompatible to 24.0.5+incompatible.
- [Release notes](https://github.com/docker/docker/releases)
- [Commits](https://github.com/docker/docker/commits/v24.0.5)

---
updated-dependencies:
- dependency-name: github.com/docker/docker
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-07-31 03:12:43 +00:00
dependabot[bot]
17bf4fc5af build(deps): bump github.com/go-git/go-git/v5 from 5.7.0 to 5.8.0 (#1925)
Bumps [github.com/go-git/go-git/v5](https://github.com/go-git/go-git) from 5.7.0 to 5.8.0.
- [Release notes](https://github.com/go-git/go-git/releases)
- [Commits](https://github.com/go-git/go-git/compare/v5.7.0...v5.8.0)

---
updated-dependencies:
- dependency-name: github.com/go-git/go-git/v5
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-07-24 02:53:35 +00:00
taytzehao
67f4baa618 local runner doc (#1911)
* local runner doc

* correct would would

---------

Co-authored-by: tzehaoo <tzehao@intnt.ai>
Co-authored-by: Casey Lee <cplee@nektos.com>
2023-07-21 16:56:11 +00:00
Thomas Eddy
83b0a5b1f2 Add new CLI flag to log just the job id and not the entire job name (#1920)
* Add new CLI flag to log just the job id and not the entire job name

* Up the action test timeout to 20m from 15m
2023-07-19 21:45:44 +00:00
dependabot[bot]
4810f69367 build(deps): bump github.com/moby/buildkit from 0.11.6 to 0.12.0 (#1917)
update moby/moby to snapshot
2023-07-17 19:55:17 +00:00
sillyguodong
cdc6d4bc6a Support expression in uses (#75)
Since actions can specify the download source via a url prefix. The prefix may contain some sensitive information that needs to be stored in secrets or variable context, so we need to interpolate the expression value for`uses` firstly.

Reviewed-on: https://gitea.com/gitea/act/pulls/75
Co-authored-by: sillyguodong <gedong_1994@163.com>
Co-committed-by: sillyguodong <gedong_1994@163.com>
2023-07-17 03:46:34 +00:00
dependabot[bot]
e343ea9d5f build(deps): bump golang.org/x/term from 0.9.0 to 0.10.0 (#1906)
Bumps [golang.org/x/term](https://github.com/golang/term) from 0.9.0 to 0.10.0.
- [Commits](https://github.com/golang/term/compare/v0.9.0...v0.10.0)

---
updated-dependencies:
- dependency-name: golang.org/x/term
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-07-11 15:14:01 +00:00
Casey Lee
94bc8b319c Bump dockercli (#1905)
* updates to support newer version of docker sdk

Bumps [github.com/docker/cli](https://github.com/docker/cli) from 24.0.2+incompatible to 24.0.4+incompatible.
- [Commits](https://github.com/docker/cli/compare/v24.0.2...v24.0.4)

---
updated-dependencies:
- dependency-name: github.com/docker/cli
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* feat: upgrade to go 1.20

* feat: upgrade to go 1.20

* chore: use go version from go.mod

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-07-10 21:55:53 -07:00
Josh McCullough
808cf5a2c3 throw when invalid uses key is provided (#1804)
* throw if `uses` is invalid

* update JobType to return error

* lint

* put //nolint:dupl on wrong test

* update error message to remove end punctuation

* lint

* update remote job type check

* move if statement

* rm nolint:dupl ... we'll see how that goes

---------

Co-authored-by: Casey Lee <cplee@nektos.com>
2023-07-10 21:27:43 -07:00
Jason Song
8c7c0f53c1 fix: handle zero size (#1888) 2023-07-10 20:35:27 -07:00
Zettat123
2069b04779 Fix missed ValidVolumes for docker steps (#74)
Fixes https://gitea.com/gitea/act_runner/issues/277

Thanks @ChristopherHX for finding the cause of the bug.

Reviewed-on: https://gitea.com/gitea/act/pulls/74
Co-authored-by: Zettat123 <zettat123@gmail.com>
Co-committed-by: Zettat123 <zettat123@gmail.com>
2023-07-11 02:08:22 +00:00
Casey Lee
724ec918c9 chore: upgrade golangci-lint and address findings (#1904) 2023-07-10 17:12:12 -07:00
dependabot[bot]
79f93beef2 build(deps): bump golangci/golangci-lint-action from 3.5.0 to 3.6.0 (#1868)
Bumps [golangci/golangci-lint-action](https://github.com/golangci/golangci-lint-action) from 3.5.0 to 3.6.0.
- [Release notes](https://github.com/golangci/golangci-lint-action/releases)
- [Commits](https://github.com/golangci/golangci-lint-action/compare/v3.5.0...v3.6.0)

---
updated-dependencies:
- dependency-name: golangci/golangci-lint-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

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>
Co-authored-by: Casey Lee <cplee@nektos.com>
2023-07-10 23:55:19 +00:00
dependabot[bot]
70956f2929 build(deps): bump gotest.tools/v3 from 3.4.0 to 3.5.0 (#1892)
Bumps [gotest.tools/v3](https://github.com/gotestyourself/gotest.tools) from 3.4.0 to 3.5.0.
- [Release notes](https://github.com/gotestyourself/gotest.tools/releases)
- [Commits](https://github.com/gotestyourself/gotest.tools/compare/v3.4.0...v3.5.0)

---
updated-dependencies:
- dependency-name: gotest.tools/v3
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Casey Lee <cplee@nektos.com>
2023-07-10 16:22:50 -07:00
Reisen Usagi
ef79bb284d Normalize path outputs emitted by the artifact server download endpoint (#1898)
Co-authored-by: Casey Lee <cplee@nektos.com>
2023-07-10 16:19:30 -07:00
GitHub Actions
3a0a6425a8 chore: bump VERSION to 0.2.48 2023-07-10 20:03:46 +00:00
dependabot[bot]
4c8da8558d build(deps): bump github.com/moby/buildkit from 0.11.5 to 0.11.6 (#1884)
Bumps [github.com/moby/buildkit](https://github.com/moby/buildkit) from 0.11.5 to 0.11.6.
- [Release notes](https://github.com/moby/buildkit/releases)
- [Commits](https://github.com/moby/buildkit/compare/v0.11.5...v0.11.6)

---
updated-dependencies:
- dependency-name: github.com/moby/buildkit
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-07-10 17:51:29 +00:00
dependabot[bot]
f40d0b873d build(deps): bump github.com/opencontainers/image-spec (#1893)
Bumps [github.com/opencontainers/image-spec](https://github.com/opencontainers/image-spec) from 1.1.0-rc.3 to 1.1.0-rc4.
- [Release notes](https://github.com/opencontainers/image-spec/releases)
- [Changelog](https://github.com/opencontainers/image-spec/blob/main/RELEASES.md)
- [Commits](https://github.com/opencontainers/image-spec/compare/v1.1.0-rc3...v1.1.0-rc4)

---
updated-dependencies:
- dependency-name: github.com/opencontainers/image-spec
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Casey Lee <cplee@nektos.com>
2023-07-10 17:31:59 +00:00
Jason Song
15618d1187 Remove archives.replacements in goreleaser.yaml (#1895)
* fix: update name template in goreleaser

* fix: add arm version

* fix: space

* fix: --clean

---------

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
2023-07-10 17:15:16 +00:00
ChristopherHX
e597046195 refactor: open boltdb only while using it (#1879)
* refactor: open boltdb only while using it

* patch

* Update handler_test.go

* Update handler_test.go

* Update handler_test.go

* Update handler.go

* timeout * 10

* pr feedback

* fixup
2023-07-10 16:57:06 +00:00
sati.ac
3813f40cba use remoteAction.URL if not empty (#71)
Fixes https://github.com/go-gitea/gitea/issues/25615

Reviewed-on: https://gitea.com/gitea/act/pulls/71
Co-authored-by: sati.ac <sati.ac@noreply.gitea.com>
Co-committed-by: sati.ac <sati.ac@noreply.gitea.com>
2023-07-03 03:43:44 +00:00
GitHub Actions
310cb79e81 chore: bump VERSION to 0.2.47 2023-07-01 02:34:27 +00:00
Jason Song
eb19987893 Revert "Support for multiple default URLs for getting actions (#58)" (#70)
Follow https://github.com/go-gitea/gitea/pull/25581 .

Reviewed-on: https://gitea.com/gitea/act/pulls/70
2023-06-30 07:45:13 +00:00
Zettat123
545802b97b Fix the error when removing network in self-hosted mode (#69)
Fixes https://gitea.com/gitea/act_runner/issues/255

Reviewed-on: https://gitea.com/gitea/act/pulls/69
Co-authored-by: Zettat123 <zettat123@gmail.com>
Co-committed-by: Zettat123 <zettat123@gmail.com>
2023-06-28 02:27:12 +00:00
Sam Foo
e60018a6d9 Allow inputs for workflow_calls (#1845) 2023-06-27 17:32:04 +00:00
dependabot[bot]
70e1e37280 build(deps): bump github.com/opencontainers/image-spec (#1883)
Bumps [github.com/opencontainers/image-spec](https://github.com/opencontainers/image-spec) from 1.1.0-rc2.0.20221005185240-3a7f492d3f1b to 1.1.0-rc.3.
- [Release notes](https://github.com/opencontainers/image-spec/releases)
- [Changelog](https://github.com/opencontainers/image-spec/blob/main/RELEASES.md)
- [Commits](https://github.com/opencontainers/image-spec/commits/v1.1.0-rc3)

---
updated-dependencies:
- dependency-name: github.com/opencontainers/image-spec
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-06-26 04:00:05 +00:00
dependabot[bot]
3d1d8a9aca build(deps): bump github.com/moby/buildkit from 0.11.5 to 0.11.6 (#1882)
Bumps [github.com/moby/buildkit](https://github.com/moby/buildkit) from 0.11.5 to 0.11.6.
- [Release notes](https://github.com/moby/buildkit/releases)
- [Commits](https://github.com/moby/buildkit/compare/v0.11.5...v0.11.6)

---
updated-dependencies:
- dependency-name: github.com/moby/buildkit
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-06-26 03:43:21 +00:00
dependabot[bot]
f9dcb58db2 build(deps): bump github.com/opencontainers/image-spec (#1881)
Bumps [github.com/opencontainers/image-spec](https://github.com/opencontainers/image-spec) from 1.1.0-rc2.0.20221005185240-3a7f492d3f1b to 1.1.0-rc.3.
- [Release notes](https://github.com/opencontainers/image-spec/releases)
- [Changelog](https://github.com/opencontainers/image-spec/blob/main/RELEASES.md)
- [Commits](https://github.com/opencontainers/image-spec/commits/v1.1.0-rc3)

---
updated-dependencies:
- dependency-name: github.com/opencontainers/image-spec
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-06-26 03:27:46 +00:00
dependabot[bot]
a0307d3b7c build(deps): bump github.com/moby/buildkit from 0.11.5 to 0.11.6 (#1880)
Bumps [github.com/moby/buildkit](https://github.com/moby/buildkit) from 0.11.5 to 0.11.6.
- [Release notes](https://github.com/moby/buildkit/releases)
- [Commits](https://github.com/moby/buildkit/compare/v0.11.5...v0.11.6)

---
updated-dependencies:
- dependency-name: github.com/moby/buildkit
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-06-26 03:12:03 +00:00
Tomasz Duda
515c2c429d fix action cloning, set correct server_url for act_runner exec (#68)
1. Newest act is not able to clone action based on --default-actions-url
It might be side effect of https://gitea.com/gitea/act/pulls/67.
2. Set correct server_url, api_url, graphql_url for act_runner exec

Reviewed-on: https://gitea.com/gitea/act/pulls/68
Reviewed-by: Jason Song <i@wolfogre.com>
Co-authored-by: Tomasz Duda <tomaszduda23@gmail.com>
Co-committed-by: Tomasz Duda <tomaszduda23@gmail.com>
2023-06-20 07:36:10 +00:00
dependabot[bot]
4fc176f556 build(deps): bump github.com/rhysd/actionlint from 1.6.24 to 1.6.25 (#1870)
Bumps [github.com/rhysd/actionlint](https://github.com/rhysd/actionlint) from 1.6.24 to 1.6.25.
- [Release notes](https://github.com/rhysd/actionlint/releases)
- [Changelog](https://github.com/rhysd/actionlint/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rhysd/actionlint/compare/v1.6.24...v1.6.25)

---
updated-dependencies:
- dependency-name: github.com/rhysd/actionlint
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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>
2023-06-19 04:18:27 +00:00
dependabot[bot]
df44dffd30 build(deps): bump github.com/AlecAivazis/survey/v2 from 2.3.6 to 2.3.7 (#1872)
Bumps [github.com/AlecAivazis/survey/v2](https://github.com/AlecAivazis/survey) from 2.3.6 to 2.3.7.
- [Release notes](https://github.com/AlecAivazis/survey/releases)
- [Commits](https://github.com/AlecAivazis/survey/compare/v2.3.6...v2.3.7)

---
updated-dependencies:
- dependency-name: github.com/AlecAivazis/survey/v2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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>
2023-06-19 04:03:04 +00:00
dependabot[bot]
b2191ae204 build(deps): bump golang.org/x/term from 0.8.0 to 0.9.0 (#1869)
Bumps [golang.org/x/term](https://github.com/golang/term) from 0.8.0 to 0.9.0.
- [Commits](https://github.com/golang/term/compare/v0.8.0...v0.9.0)

---
updated-dependencies:
- dependency-name: golang.org/x/term
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

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>
2023-06-19 03:30:12 +00:00
dependabot[bot]
ef608854d0 build(deps): bump github.com/opencontainers/image-spec (#1871)
Bumps [github.com/opencontainers/image-spec](https://github.com/opencontainers/image-spec) from 1.1.0-rc2.0.20221005185240-3a7f492d3f1b to 1.1.0-rc.3.
- [Release notes](https://github.com/opencontainers/image-spec/releases)
- [Changelog](https://github.com/opencontainers/image-spec/blob/main/RELEASES.md)
- [Commits](https://github.com/opencontainers/image-spec/commits/v1.1.0-rc3)

---
updated-dependencies:
- dependency-name: github.com/opencontainers/image-spec
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-06-19 03:12:23 +00:00
Zettat123
a165e17878 Add support for glob syntax when checking volumes (#64)
Follow #60

Reviewed-on: https://gitea.com/gitea/act/pulls/64
Reviewed-by: Jason Song <i@wolfogre.com>
Co-authored-by: Zettat123 <zettat123@gmail.com>
Co-committed-by: Zettat123 <zettat123@gmail.com>
2023-06-16 05:24:01 +00:00
Zettat123
56e103b4ba Fix the missing URL when using remote reusable workflow (#67)
Reviewed-on: https://gitea.com/gitea/act/pulls/67
Reviewed-by: Jason Song <i@wolfogre.com>
Co-authored-by: Zettat123 <zettat123@gmail.com>
Co-committed-by: Zettat123 <zettat123@gmail.com>
2023-06-16 05:12:43 +00:00
Marius Zwicker
422cbdf446 Allow to override location of action cache dir (#65)
Adds an explicit config option to specify the directory
below which action contents will be cached. If left empty
the previous location at `$XDG_CACHE_HOME/act` or
`$HOME/.cache/act` will be used respectively.

Required to resolve gitea/act_runner#235

Co-authored-by: Marius Zwicker <marius@mlba-team.de>
Reviewed-on: https://gitea.com/gitea/act/pulls/65
Reviewed-by: Jason Song <i@wolfogre.com>
Co-authored-by: Marius Zwicker <emzeat@noreply.gitea.com>
Co-committed-by: Marius Zwicker <emzeat@noreply.gitea.com>
2023-06-16 03:41:39 +00:00
Jason Song
8c56bd3aa5 Merge tag 'nektos/v0.2.46' 2023-06-16 11:08:39 +08:00
Marius Zwicker
74c27db4dd Allow to override location of action cache dir (#1863)
Adds an option to specify the directory below which actions
and host workspaces will be stored. If left empty the previous
location at $XDG_CACHE_HOME/act or $HOME/.cache/act will be used
respectively.

Co-authored-by: Casey Lee <cplee@nektos.com>
2023-06-15 01:16:00 +00:00
Jason Song
24348ff1ee Drop disappeared wei/curl@v1 (#1864)
* chore: trigger actions

* fix: use curl command directly

* fix: use node:16-buster

* fix: remove --fail-with-body

* chore: format codes
2023-06-13 21:24:31 +00:00
dependabot[bot]
b92d95f899 build(deps): bump github.com/moby/buildkit from 0.11.5 to 0.11.6 (#1858)
Bumps [github.com/moby/buildkit](https://github.com/moby/buildkit) from 0.11.5 to 0.11.6.
- [Release notes](https://github.com/moby/buildkit/releases)
- [Commits](https://github.com/moby/buildkit/compare/v0.11.5...v0.11.6)

---
updated-dependencies:
- dependency-name: github.com/moby/buildkit
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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>
2023-06-12 04:28:49 +00:00
dependabot[bot]
3555d65d08 build(deps): bump megalinter/megalinter from 7.0.4 to 7.1.0 (#1857)
Bumps [megalinter/megalinter](https://github.com/megalinter/megalinter) from 7.0.4 to 7.1.0.
- [Release notes](https://github.com/megalinter/megalinter/releases)
- [Changelog](https://github.com/oxsecurity/megalinter/blob/main/CHANGELOG.md)
- [Commits](https://github.com/megalinter/megalinter/compare/v7.0.4...v7.1.0)

---
updated-dependencies:
- dependency-name: megalinter/megalinter
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

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>
2023-06-12 03:33:28 +00:00
dependabot[bot]
e912ab32c2 build(deps): bump github.com/mattn/go-isatty from 0.0.18 to 0.0.19 (#1859)
Bumps [github.com/mattn/go-isatty](https://github.com/mattn/go-isatty) from 0.0.18 to 0.0.19.
- [Commits](https://github.com/mattn/go-isatty/compare/v0.0.18...v0.0.19)

---
updated-dependencies:
- dependency-name: github.com/mattn/go-isatty
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-06-12 03:13:51 +00:00
Troy Gaines
80f6de51d5 fix: spelling mistake in readme (#1854)
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
2023-06-10 18:42:54 +00:00
Kuan Yong
6ce45e3f24 feature: Add support for github action variables (#1833)
* feature: Add support for github action variables

* add --var flag for github variables

* unitests: Updated unittests to cover vars context.

* Remove syntax extension for vars and correct unit tests

* Update pkg/runner/expression.go

Co-authored-by: ChristopherHX <christopher.homberger@web.de>

---------

Co-authored-by: kuanyong-wong-partior <kuanyong.wong@partior.com>
Co-authored-by: ChristopherHX <christopher.homberger@web.de>
2023-06-10 18:09:27 +00:00
psa
3ac2b726f2 Fix bug in processing jobs on platforms without Docker (#1834)
* Log incoming jobs.

Log the full contents of the job protobuf to make debugging jobs easier

* Ensure that the parallel executor always uses at least one thread.

The caller may mis-calculate the number of CPUs as zero, in which case
ensure that at least one thread is spawned.

* Use runtime.NumCPU for CPU counts.

For hosts without docker, GetHostInfo() returns a blank struct which
has zero CPUs and causes downstream trouble.

---------

Co-authored-by: Paul Armstrong <psa@users.noreply.gitea.com>
Co-authored-by: Jason Song <i@wolfogre.com>
2023-06-06 03:00:54 +00:00
dependabot[bot]
c70a6743f6 build(deps): bump github.com/stretchr/testify from 1.8.2 to 1.8.4 (#1842)
Bumps [github.com/stretchr/testify](https://github.com/stretchr/testify) from 1.8.2 to 1.8.4.
- [Release notes](https://github.com/stretchr/testify/releases)
- [Commits](https://github.com/stretchr/testify/compare/v1.8.2...v1.8.4)

---
updated-dependencies:
- dependency-name: github.com/stretchr/testify
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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>
2023-06-05 04:46:40 +00:00
dependabot[bot]
04b5c739d2 build(deps): bump megalinter/megalinter from 7.0.2 to 7.0.4 (#1838)
Bumps [megalinter/megalinter](https://github.com/megalinter/megalinter) from 7.0.2 to 7.0.4.
- [Release notes](https://github.com/megalinter/megalinter/releases)
- [Changelog](https://github.com/oxsecurity/megalinter/blob/main/CHANGELOG.md)
- [Commits](https://github.com/megalinter/megalinter/compare/v7.0.2...v7.0.4)

---
updated-dependencies:
- dependency-name: megalinter/megalinter
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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>
2023-06-05 04:27:58 +00:00
dependabot[bot]
e48c07988e build(deps): bump github.com/docker/cli (#1843)
Bumps [github.com/docker/cli](https://github.com/docker/cli) from 24.0.1+incompatible to 24.0.2+incompatible.
- [Commits](https://github.com/docker/cli/compare/v24.0.1...v24.0.2)

---
updated-dependencies:
- dependency-name: github.com/docker/cli
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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>
2023-06-05 04:06:57 +00:00
dependabot[bot]
0b05ee8e0b build(deps): bump github.com/imdario/mergo from 0.3.15 to 0.3.16 (#1840)
Bumps [github.com/imdario/mergo](https://github.com/imdario/mergo) from 0.3.15 to 0.3.16.
- [Release notes](https://github.com/imdario/mergo/releases)
- [Commits](https://github.com/imdario/mergo/compare/v0.3.15...v0.3.16)

---
updated-dependencies:
- dependency-name: github.com/imdario/mergo
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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>
2023-06-05 03:51:00 +00:00
dependabot[bot]
e150310da7 build(deps): bump github.com/sirupsen/logrus from 1.9.2 to 1.9.3 (#1841)
Bumps [github.com/sirupsen/logrus](https://github.com/sirupsen/logrus) from 1.9.2 to 1.9.3.
- [Release notes](https://github.com/sirupsen/logrus/releases)
- [Changelog](https://github.com/sirupsen/logrus/blob/master/CHANGELOG.md)
- [Commits](https://github.com/sirupsen/logrus/compare/v1.9.2...v1.9.3)

---
updated-dependencies:
- dependency-name: github.com/sirupsen/logrus
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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>
2023-06-05 03:35:57 +00:00
dependabot[bot]
34db86138b build(deps): bump golangci/golangci-lint-action from 3.4.0 to 3.5.0 (#1839)
Bumps [golangci/golangci-lint-action](https://github.com/golangci/golangci-lint-action) from 3.4.0 to 3.5.0.
- [Release notes](https://github.com/golangci/golangci-lint-action/releases)
- [Commits](https://github.com/golangci/golangci-lint-action/compare/v3.4.0...v3.5.0)

---
updated-dependencies:
- dependency-name: golangci/golangci-lint-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-06-05 03:13:17 +00:00
GitHub Actions
b0d0cec71f chore: bump VERSION to 0.2.46 2023-06-01 02:39:05 +00:00
dependabot[bot]
26f1b1f4b6 build(deps): bump github.com/opencontainers/image-spec (#1829)
Bumps [github.com/opencontainers/image-spec](https://github.com/opencontainers/image-spec) from 1.1.0-rc2.0.20221005185240-3a7f492d3f1b to 1.1.0-rc.3.
- [Release notes](https://github.com/opencontainers/image-spec/releases)
- [Changelog](https://github.com/opencontainers/image-spec/blob/main/RELEASES.md)
- [Commits](https://github.com/opencontainers/image-spec/commits/v1.1.0-rc3)

---
updated-dependencies:
- dependency-name: github.com/opencontainers/image-spec
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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>
2023-05-31 17:36:12 +00:00
dependabot[bot]
9c1f1f8d84 build(deps): bump github.com/docker/cli (#1816)
Bumps [github.com/docker/cli](https://github.com/docker/cli) from 23.0.6+incompatible to 24.0.1+incompatible.
- [Commits](https://github.com/docker/cli/compare/v23.0.6...v24.0.1)

---
updated-dependencies:
- dependency-name: github.com/docker/cli
  dependency-type: direct:production
  update-type: version-update:semver-major
...

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>
2023-05-31 15:43:03 +00:00
Joseph Mearman
3cfc2cf9c3 add instruction for using gh auth token (#1831) 2023-05-31 14:24:24 +00:00
dependabot[bot]
b0996e0577 build(deps): bump github.com/go-git/go-git/v5 (#1830)
Bumps [github.com/go-git/go-git/v5](https://github.com/go-git/go-git) from 5.6.2-0.20230411180853-ce62f3e9ff86 to 5.7.0.
- [Release notes](https://github.com/go-git/go-git/releases)
- [Commits](https://github.com/go-git/go-git/commits/v5.7.0)

---
updated-dependencies:
- dependency-name: github.com/go-git/go-git/v5
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

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>
2023-05-29 03:35:06 +00:00
dependabot[bot]
481999f59d build(deps): bump megalinter/megalinter from 6.22.2 to 7.0.2 (#1827)
Bumps [megalinter/megalinter](https://github.com/megalinter/megalinter) from 6.22.2 to 7.0.2.
- [Release notes](https://github.com/megalinter/megalinter/releases)
- [Changelog](https://github.com/oxsecurity/megalinter/blob/main/CHANGELOG.md)
- [Commits](https://github.com/megalinter/megalinter/compare/v6.22.2...v7.0.2)

---
updated-dependencies:
- dependency-name: megalinter/megalinter
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-05-29 03:12:45 +00:00
ab-pkandhari
11dd2ac745 fix: Update ARCH environment variable used in runners/actions (#1818) 2023-05-23 12:26:47 +00:00
dependabot[bot]
16c574cd26 build(deps): bump github.com/moby/buildkit from 0.11.5 to 0.11.6 (#1817)
Bumps [github.com/moby/buildkit](https://github.com/moby/buildkit) from 0.11.5 to 0.11.6.
- [Release notes](https://github.com/moby/buildkit/releases)
- [Commits](https://github.com/moby/buildkit/compare/v0.11.5...v0.11.6)

---
updated-dependencies:
- dependency-name: github.com/moby/buildkit
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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>
2023-05-22 04:02:38 +00:00
dependabot[bot]
06054d2931 build(deps): bump github.com/sirupsen/logrus from 1.9.0 to 1.9.2 (#1814)
Bumps [github.com/sirupsen/logrus](https://github.com/sirupsen/logrus) from 1.9.0 to 1.9.2.
- [Release notes](https://github.com/sirupsen/logrus/releases)
- [Changelog](https://github.com/sirupsen/logrus/blob/master/CHANGELOG.md)
- [Commits](https://github.com/sirupsen/logrus/compare/v1.9.0...v1.9.2)

---
updated-dependencies:
- dependency-name: github.com/sirupsen/logrus
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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>
2023-05-22 03:29:31 +00:00
dependabot[bot]
1371215aab build(deps): bump codecov/codecov-action from 3.1.3 to 3.1.4 (#1813)
Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 3.1.3 to 3.1.4.
- [Release notes](https://github.com/codecov/codecov-action/releases)
- [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/codecov/codecov-action/compare/v3.1.3...v3.1.4)

---
updated-dependencies:
- dependency-name: codecov/codecov-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-05-22 03:12:14 +00:00
dependabot[bot]
1eacf23dcb build(deps): bump github.com/opencontainers/image-spec (#1807)
Bumps [github.com/opencontainers/image-spec](https://github.com/opencontainers/image-spec) from 1.1.0-rc2.0.20221005185240-3a7f492d3f1b to 1.1.0-rc.3.
- [Release notes](https://github.com/opencontainers/image-spec/releases)
- [Changelog](https://github.com/opencontainers/image-spec/blob/main/RELEASES.md)
- [Commits](https://github.com/opencontainers/image-spec/commits/v1.1.0-rc3)

---
updated-dependencies:
- dependency-name: github.com/opencontainers/image-spec
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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>
2023-05-15 03:43:06 +00:00
dependabot[bot]
c00810bdf4 build(deps): bump github.com/docker/docker (#1806)
Bumps [github.com/docker/docker](https://github.com/docker/docker) from 23.0.5+incompatible to 23.0.6+incompatible.
- [Release notes](https://github.com/docker/docker/releases)
- [Commits](https://github.com/docker/docker/compare/v23.0.5...v23.0.6)

---
updated-dependencies:
- dependency-name: github.com/docker/docker
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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>
2023-05-15 03:28:21 +00:00
dependabot[bot]
39abbce4e6 build(deps): bump github.com/docker/cli (#1805)
Bumps [github.com/docker/cli](https://github.com/docker/cli) from 23.0.5+incompatible to 23.0.6+incompatible.
- [Commits](https://github.com/docker/cli/compare/v23.0.5...v23.0.6)

---
updated-dependencies:
- dependency-name: github.com/docker/cli
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-05-15 03:12:21 +00:00
dependabot[bot]
b5fa24537f build(deps): bump github.com/docker/distribution (#1801)
Bumps [github.com/docker/distribution](https://github.com/docker/distribution) from 2.8.1+incompatible to 2.8.2+incompatible.
- [Release notes](https://github.com/docker/distribution/releases)
- [Commits](https://github.com/docker/distribution/compare/v2.8.1...v2.8.2)

---
updated-dependencies:
- dependency-name: github.com/docker/distribution
  dependency-type: direct:production
...

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>
2023-05-11 21:19:02 +00:00
dependabot[bot]
046f5aa715 build(deps): bump github.com/cloudflare/circl from 1.1.0 to 1.3.3 (#1800)
Bumps [github.com/cloudflare/circl](https://github.com/cloudflare/circl) from 1.1.0 to 1.3.3.
- [Release notes](https://github.com/cloudflare/circl/releases)
- [Commits](https://github.com/cloudflare/circl/compare/v1.1.0...v1.3.3)

---
updated-dependencies:
- dependency-name: github.com/cloudflare/circl
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-05-11 21:00:01 +00:00
dependabot[bot]
65ef31f102 build(deps): bump github.com/moby/buildkit from 0.11.5 to 0.11.6 (#1791)
Bumps [github.com/moby/buildkit](https://github.com/moby/buildkit) from 0.11.5 to 0.11.6.
- [Release notes](https://github.com/moby/buildkit/releases)
- [Commits](https://github.com/moby/buildkit/compare/v0.11.5...v0.11.6)

---
updated-dependencies:
- dependency-name: github.com/moby/buildkit
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-05-08 03:15:32 +00:00
benbaker76
f84a566ded Replace backslash in GetActPath() for Windows (#1777)
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
2023-05-03 19:12:36 +00:00
ChristopherHX
8913375af8 feat: implement steps.timeout-minutes (#1776)
* feat: implement steps.timeout-minutes

* Add imports

* refactor code

---------

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
2023-05-03 18:08:11 +00:00
ChristopherHX
ca9b783491 fix: don't allow -self-hosted mode as container image (#1783)
* fix: don't allow `-self-hosted` mode as container image

* fix: jobcontainer in hostmode platform

* Update run_context.go

---------

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
2023-05-03 17:49:17 +00:00
ChristopherHX
568124ca69 Refactor evaluate yaml node do not alter nested nodes (#1761)
* refactor: EvaluateYamlNode do not alter nested nodes

* fix build error

* fix op

* fix lint

* ...

* fixup

---------

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
2023-05-03 17:26:28 +00:00
ChristopherHX
aa21277380 fix: fallback to unauthenticated pull (#1774)
* fix: fallback to unauthenticated pull

* move logger def

* fixup

* add import

* .

---------

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
2023-05-03 16:44:26 +00:00
Shubh Bapna
4721abfa6d fix: remove hardcoded reference to github.com when using reusable remote workflows and remote actions (#1784)
* fix filename for remote reusable workflow and remove hardcoded reference to github.com

* remove hardcoded reference to github.com for remote action
2023-05-03 15:46:28 +00:00
dependabot[bot]
3eb6e83ea4 build(deps): bump github.com/docker/cli (#1780)
Bumps [github.com/docker/cli](https://github.com/docker/cli) from 23.0.4+incompatible to 23.0.5+incompatible.
- [Release notes](https://github.com/docker/cli/releases)
- [Commits](https://github.com/docker/cli/compare/v23.0.4...v23.0.5)

---
updated-dependencies:
- dependency-name: github.com/docker/cli
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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>
2023-05-01 03:49:17 +00:00
dependabot[bot]
15eb1fa92a build(deps): bump github.com/opencontainers/image-spec (#1781)
Bumps [github.com/opencontainers/image-spec](https://github.com/opencontainers/image-spec) from 1.1.0-rc2.0.20221005185240-3a7f492d3f1b to 1.1.0-rc.3.
- [Release notes](https://github.com/opencontainers/image-spec/releases)
- [Changelog](https://github.com/opencontainers/image-spec/blob/main/RELEASES.md)
- [Commits](https://github.com/opencontainers/image-spec/commits/v1.1.0-rc3)

---
updated-dependencies:
- dependency-name: github.com/opencontainers/image-spec
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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>
2023-05-01 03:30:50 +00:00
dependabot[bot]
1f9bbe12dd build(deps): bump github.com/docker/docker (#1779)
Bumps [github.com/docker/docker](https://github.com/docker/docker) from 23.0.4+incompatible to 23.0.5+incompatible.
- [Release notes](https://github.com/docker/docker/releases)
- [Commits](https://github.com/docker/docker/compare/v23.0.4...v23.0.5)

---
updated-dependencies:
- dependency-name: github.com/docker/docker
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-05-01 03:14:03 +00:00
52 changed files with 971 additions and 516 deletions

View File

@@ -54,7 +54,7 @@ runs:
} }
} }
}; };
var args = ['test', '-v', '-cover', '-coverprofile=coverage.txt', '-covermode=atomic', '-timeout', '15m']; var args = ['test', '-v', '-cover', '-coverprofile=coverage.txt', '-covermode=atomic', '-timeout', '20m'];
var filter = process.env.FILTER; var filter = process.env.FILTER;
if(filter) { if(filter) {
args.push('-run'); args.push('-run');

View File

@@ -8,7 +8,6 @@ concurrency:
env: env:
ACT_OWNER: ${{ github.repository_owner }} ACT_OWNER: ${{ github.repository_owner }}
ACT_REPOSITORY: ${{ github.repository }} ACT_REPOSITORY: ${{ github.repository }}
GO_VERSION: 1.18
CGO_ENABLED: 0 CGO_ENABLED: 0
jobs: jobs:
@@ -21,12 +20,13 @@ jobs:
fetch-depth: 0 fetch-depth: 0
- uses: actions/setup-go@v4 - uses: actions/setup-go@v4
with: with:
go-version: ${{ env.GO_VERSION }} go-version-file: go.mod
check-latest: true check-latest: true
- uses: golangci/golangci-lint-action@v3.4.0 - uses: golangci/golangci-lint-action@v3.6.0
with: with:
version: v1.47.2 version: v1.53
- uses: megalinter/megalinter/flavors/go@v6.22.2 only-new-issues: true
- uses: megalinter/megalinter/flavors/go@v7.1.0
env: env:
DEFAULT_BRANCH: master DEFAULT_BRANCH: master
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -45,7 +45,7 @@ jobs:
uses: docker/setup-qemu-action@v2 uses: docker/setup-qemu-action@v2
- uses: actions/setup-go@v4 - uses: actions/setup-go@v4
with: with:
go-version: ${{ env.GO_VERSION }} go-version-file: go.mod
check-latest: true check-latest: true
- uses: actions/cache@v3 - uses: actions/cache@v3
if: ${{ !env.ACT }} if: ${{ !env.ACT }}
@@ -61,7 +61,7 @@ jobs:
- 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
- name: Upload Codecov report - name: Upload Codecov report
uses: codecov/codecov-action@v3.1.3 uses: codecov/codecov-action@v3.1.4
with: with:
files: coverage.txt files: coverage.txt
fail_ci_if_error: true # optional (default = false) fail_ci_if_error: true # optional (default = false)
@@ -80,7 +80,7 @@ jobs:
fetch-depth: 2 fetch-depth: 2
- uses: actions/setup-go@v4 - uses: actions/setup-go@v4
with: with:
go-version: ${{ env.GO_VERSION }} go-version-file: go.mod
check-latest: true check-latest: true
- name: Run Tests - name: Run Tests
uses: ./.github/actions/run-tests uses: ./.github/actions/run-tests
@@ -95,7 +95,7 @@ jobs:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- uses: actions/setup-go@v4 - uses: actions/setup-go@v4
with: with:
go-version: ${{ env.GO_VERSION }} go-version-file: go.mod
check-latest: true check-latest: true
- uses: actions/cache@v3 - uses: actions/cache@v3
if: ${{ !env.ACT }} if: ${{ !env.ACT }}
@@ -108,7 +108,7 @@ jobs:
uses: goreleaser/goreleaser-action@v4 uses: goreleaser/goreleaser-action@v4
with: with:
version: latest version: latest
args: release --snapshot --rm-dist args: release --snapshot --clean
- name: Capture x86_64 (64-bit) Linux binary - name: Capture x86_64 (64-bit) Linux binary
if: ${{ !env.ACT }} if: ${{ !env.ACT }}
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v3

View File

@@ -4,9 +4,6 @@ on:
- cron: '0 2 1 * *' - cron: '0 2 1 * *'
workflow_dispatch: {} workflow_dispatch: {}
env:
GO_VERSION: 1.18
jobs: jobs:
release: release:
name: promote name: promote
@@ -20,7 +17,7 @@ jobs:
- uses: fregante/setup-git-user@v2 - uses: fregante/setup-git-user@v2
- uses: actions/setup-go@v4 - uses: actions/setup-go@v4
with: with:
go-version: ${{ env.GO_VERSION }} go-version-file: go.mod
check-latest: true check-latest: true
- uses: actions/cache@v3 - uses: actions/cache@v3
if: ${{ !env.ACT }} if: ${{ !env.ACT }}

View File

@@ -4,9 +4,6 @@ on:
tags: tags:
- v* - v*
env:
GO_VERSION: 1.18
jobs: jobs:
release: release:
name: release name: release
@@ -17,7 +14,7 @@ jobs:
fetch-depth: 0 fetch-depth: 0
- uses: actions/setup-go@v4 - uses: actions/setup-go@v4
with: with:
go-version: ${{ env.GO_VERSION }} go-version-file: go.mod
check-latest: true check-latest: true
- uses: actions/cache@v3 - uses: actions/cache@v3
if: ${{ !env.ACT }} if: ${{ !env.ACT }}
@@ -30,7 +27,7 @@ jobs:
uses: goreleaser/goreleaser-action@v4 uses: goreleaser/goreleaser-action@v4
with: with:
version: latest version: latest
args: release --rm-dist args: release --clean
env: env:
GITHUB_TOKEN: ${{ secrets.GORELEASER_GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GORELEASER_GITHUB_TOKEN }}
- name: Chocolatey - name: Chocolatey

View File

@@ -19,17 +19,15 @@ linters-settings:
- pkg: 'github.com/stretchr/testify/assert' - pkg: 'github.com/stretchr/testify/assert'
alias: assert alias: assert
depguard: depguard:
list-type: blacklist rules:
include-go-root: true main:
packages: deny:
- github.com/pkg/errors - pkg: github.com/pkg/errors
- gotest.tools/v3/assert desc: Please use "errors" package from standard library
- log - pkg: gotest.tools/v3
packages-with-error-message: desc: Please keep tests unified using only github.com/stretchr/testify
- github.com/pkg/errors: 'Please use "errors" package from standard library' - pkg: log
- gotest.tools/v3: 'Please keep tests unified using only github.com/stretchr/testify' desc: Please keep logging unified using only github.com/sirupsen/logrus
- log: 'Please keep logging unified using only github.com/sirupsen/logrus'
linters: linters:
enable: enable:
- megacheck - megacheck

View File

@@ -22,13 +22,13 @@ builds:
checksum: checksum:
name_template: 'checksums.txt' name_template: 'checksums.txt'
archives: archives:
- name_template: '{{ .ProjectName }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}{{ if .Mips }}_{{ .Mips }}{{ end }}' - name_template: >-
replacements: {{ .ProjectName }}_
darwin: Darwin {{- title .Os }}_
linux: Linux {{- if eq .Arch "amd64" }}x86_64
windows: Windows {{- else if eq .Arch "386" }}i386
386: i386 {{- else }}{{ .Arch }}{{ end }}
amd64: x86_64 {{- if .Arm }}v{{ .Arm }}{{ end }}
format_overrides: format_overrides:
- goos: windows - goos: windows
format: zip format: zip

View File

@@ -106,7 +106,7 @@ endif
.PHONY: snapshot .PHONY: snapshot
snapshot: snapshot:
goreleaser build \ goreleaser build \
--rm-dist \ --clean \
--single-target \ --single-target \
--snapshot --snapshot

View File

@@ -217,6 +217,12 @@ If your workflow depends on this token, you need to create a [personal access to
act -s GITHUB_TOKEN=[insert token or leave blank and omit equals for secure input] act -s GITHUB_TOKEN=[insert token or leave blank and omit equals for secure input]
``` ```
If [GitHub CLI](https://cli.github.com/) is installed, the [`gh auth token`](https://cli.github.com/manual/gh_auth_token) command can be used to automatically pass the token to act
```bash
act -s GITHUB_TOKEN="$(gh auth token)"
```
**WARNING**: `GITHUB_TOKEN` will be logged in shell history if not inserted through secure input or (depending on your shell config) the command is prefixed with a whitespace. **WARNING**: `GITHUB_TOKEN` will be logged in shell history if not inserted through secure input or (depending on your shell config) the command is prefixed with a whitespace.
# Known Issues # Known Issues
@@ -291,6 +297,15 @@ If you need an environment that works just like the corresponding GitHub runner
- [`catthehacker/ubuntu:full-*`](https://github.com/catthehacker/docker_images/pkgs/container/ubuntu) - built from Packer template provided by GitHub, see [catthehacker/virtual-environments-fork](https://github.com/catthehacker/virtual-environments-fork) or [catthehacker/docker_images](https://github.com/catthehacker/docker_images) for more information - [`catthehacker/ubuntu:full-*`](https://github.com/catthehacker/docker_images/pkgs/container/ubuntu) - built from Packer template provided by GitHub, see [catthehacker/virtual-environments-fork](https://github.com/catthehacker/virtual-environments-fork) or [catthehacker/docker_images](https://github.com/catthehacker/docker_images) for more information
## Using local runner images
The `--pull` flag is set to true by default due to a breaking on older default docker images. This would pull the docker image everytime act is executed.
Set `--pull` to false if a local docker image is needed
```sh
act --pull=false
```
## Use an alternative runner image ## Use an alternative runner image
To use a different image for the runner, use the `-P` option. To use a different image for the runner, use the `-P` option.
@@ -479,7 +494,7 @@ Want to contribute to act? Awesome! Check out the [contributing guidelines](CONT
## Manually building from source ## Manually building from source
- Install Go tools 1.18+ - (<https://golang.org/doc/install>) - Install Go tools 1.20+ - (<https://golang.org/doc/install>)
- Clone this repo `git clone git@github.com:nektos/act.git` - Clone this repo `git clone git@github.com:nektos/act.git`
- Run unit tests with `make test` - Run unit tests with `make test`
- Build and install: `make install` - Build and install: `make install`

View File

@@ -1 +1 @@
0.2.45 0.2.49

View File

@@ -54,6 +54,8 @@ type Input struct {
replaceGheActionWithGithubCom []string replaceGheActionWithGithubCom []string
replaceGheActionTokenWithGithubCom string replaceGheActionTokenWithGithubCom string
matrix []string matrix []string
actionCachePath string
logPrefixJobID bool
} }
func (i *Input) resolve(path string) string { func (i *Input) resolve(path string) string {

View File

@@ -75,6 +75,7 @@ func Execute(ctx context.Context, version string) {
rootCmd.PersistentFlags().StringVarP(&input.workdir, "directory", "C", ".", "working directory") rootCmd.PersistentFlags().StringVarP(&input.workdir, "directory", "C", ".", "working directory")
rootCmd.PersistentFlags().BoolP("verbose", "v", false, "verbose output") rootCmd.PersistentFlags().BoolP("verbose", "v", false, "verbose output")
rootCmd.PersistentFlags().BoolVar(&input.jsonLogger, "json", false, "Output logs in json format") rootCmd.PersistentFlags().BoolVar(&input.jsonLogger, "json", false, "Output logs in json format")
rootCmd.PersistentFlags().BoolVar(&input.logPrefixJobID, "log-prefix-job-id", false, "Output the job id within non-json logs instead of the entire name")
rootCmd.PersistentFlags().BoolVarP(&input.noOutput, "quiet", "q", false, "disable logging of output from steps") rootCmd.PersistentFlags().BoolVarP(&input.noOutput, "quiet", "q", false, "disable logging of output from steps")
rootCmd.PersistentFlags().BoolVarP(&input.dryrun, "dryrun", "n", false, "dryrun mode") rootCmd.PersistentFlags().BoolVarP(&input.dryrun, "dryrun", "n", false, "dryrun mode")
rootCmd.PersistentFlags().StringVarP(&input.secretfile, "secret-file", "", ".secrets", "file with list of secrets to read from (e.g. --secret-file .secrets)") rootCmd.PersistentFlags().StringVarP(&input.secretfile, "secret-file", "", ".secrets", "file with list of secrets to read from (e.g. --secret-file .secrets)")
@@ -94,6 +95,7 @@ func Execute(ctx context.Context, version string) {
rootCmd.PersistentFlags().StringVarP(&input.cacheServerPath, "cache-server-path", "", filepath.Join(CacheHomeDir, "actcache"), "Defines the path where the cache server stores caches.") rootCmd.PersistentFlags().StringVarP(&input.cacheServerPath, "cache-server-path", "", filepath.Join(CacheHomeDir, "actcache"), "Defines the path where the cache server stores caches.")
rootCmd.PersistentFlags().StringVarP(&input.cacheServerAddr, "cache-server-addr", "", common.GetOutboundIP().String(), "Defines the address to which the cache server binds.") rootCmd.PersistentFlags().StringVarP(&input.cacheServerAddr, "cache-server-addr", "", common.GetOutboundIP().String(), "Defines the address to which the cache server binds.")
rootCmd.PersistentFlags().Uint16VarP(&input.cacheServerPort, "cache-server-port", "", 0, "Defines the port where the artifact server listens. 0 means a randomly available port.") rootCmd.PersistentFlags().Uint16VarP(&input.cacheServerPort, "cache-server-port", "", 0, "Defines the port where the artifact server listens. 0 means a randomly available port.")
rootCmd.PersistentFlags().StringVarP(&input.actionCachePath, "action-cache-path", "", filepath.Join(CacheHomeDir, "act"), "Defines the path where the actions get cached and host workspaces created.")
rootCmd.SetArgs(args()) rootCmd.SetArgs(args())
if err := rootCmd.Execute(); err != nil { if err := rootCmd.Execute(); err != nil {
@@ -272,7 +274,7 @@ func readArgsFile(file string, split bool) []string {
return args return args
} }
func setup(inputs *Input) func(*cobra.Command, []string) { func setup(_ *Input) func(*cobra.Command, []string) {
return func(cmd *cobra.Command, _ []string) { return func(cmd *cobra.Command, _ []string) {
verbose, _ := cmd.Flags().GetBool("verbose") verbose, _ := cmd.Flags().GetBool("verbose")
if verbose { if verbose {
@@ -342,12 +344,11 @@ func parseMatrix(matrix []string) map[string]map[string]bool {
matrix := r.Split(m, 2) matrix := r.Split(m, 2)
if len(matrix) < 2 { if len(matrix) < 2 {
log.Fatalf("Invalid matrix format. Failed to parse %s", m) log.Fatalf("Invalid matrix format. Failed to parse %s", m)
} else {
if _, ok := matrixes[matrix[0]]; !ok {
matrixes[matrix[0]] = make(map[string]bool)
}
matrixes[matrix[0]][matrix[1]] = true
} }
if _, ok := matrixes[matrix[0]]; !ok {
matrixes[matrix[0]] = make(map[string]bool)
}
matrixes[matrix[0]][matrix[1]] = true
} }
return matrixes return matrixes
} }
@@ -580,9 +581,11 @@ func newRunCommand(ctx context.Context, input *Input) func(*cobra.Command, []str
ForceRebuild: input.forceRebuild, ForceRebuild: input.forceRebuild,
ReuseContainers: input.reuseContainers, ReuseContainers: input.reuseContainers,
Workdir: input.Workdir(), Workdir: input.Workdir(),
ActionCacheDir: input.actionCachePath,
BindWorkdir: input.bindWorkdir, BindWorkdir: input.bindWorkdir,
LogOutput: !input.noOutput, LogOutput: !input.noOutput,
JSONLogger: input.jsonLogger, JSONLogger: input.jsonLogger,
LogPrefixJobID: input.logPrefixJobID,
Env: envs, Env: envs,
Secrets: secrets, Secrets: secrets,
Vars: vars, Vars: vars,

61
go.mod
View File

@@ -1,61 +1,64 @@
module github.com/nektos/act module github.com/nektos/act
go 1.18 go 1.20
require ( require (
github.com/AlecAivazis/survey/v2 v2.3.6 github.com/AlecAivazis/survey/v2 v2.3.7
github.com/Masterminds/semver v1.5.0 github.com/Masterminds/semver v1.5.0
github.com/adrg/xdg v0.4.0 github.com/adrg/xdg v0.4.0
github.com/andreaskoch/go-fswatch v1.0.0 github.com/andreaskoch/go-fswatch v1.0.0
github.com/creack/pty v1.1.18 github.com/creack/pty v1.1.18
github.com/docker/cli v23.0.4+incompatible github.com/docker/cli v24.0.5+incompatible
github.com/docker/distribution v2.8.1+incompatible github.com/docker/distribution v2.8.2+incompatible
github.com/docker/docker v23.0.4+incompatible github.com/docker/docker v24.0.5+incompatible // 24.0 branch
github.com/docker/go-connections v0.4.0 github.com/docker/go-connections v0.4.0
github.com/go-git/go-billy/v5 v5.4.1 github.com/go-git/go-billy/v5 v5.4.1
github.com/go-git/go-git/v5 v5.6.2-0.20230411180853-ce62f3e9ff86 github.com/go-git/go-git/v5 v5.8.1
github.com/imdario/mergo v0.3.15 github.com/gobwas/glob v0.2.3
github.com/imdario/mergo v0.3.16
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
github.com/mattn/go-isatty v0.0.18 github.com/mattn/go-isatty v0.0.19
github.com/moby/buildkit v0.11.6 github.com/moby/buildkit v0.12.0
github.com/moby/patternmatcher v0.5.0 github.com/moby/patternmatcher v0.5.0
github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b github.com/opencontainers/image-spec v1.1.0-rc4
github.com/opencontainers/selinux v1.11.0 github.com/opencontainers/selinux v1.11.0
github.com/pkg/errors v0.9.1 github.com/pkg/errors v0.9.1
github.com/rhysd/actionlint v1.6.24 github.com/rhysd/actionlint v1.6.25
github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06 github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06
github.com/sirupsen/logrus v1.9.0 github.com/sirupsen/logrus v1.9.3
github.com/spf13/cobra v1.7.0 github.com/spf13/cobra v1.7.0
github.com/spf13/pflag v1.0.5 github.com/spf13/pflag v1.0.5
github.com/stretchr/testify v1.8.2 github.com/stretchr/testify v1.8.4
github.com/timshannon/bolthold v0.0.0-20210913165410-232392fc8a6a github.com/timshannon/bolthold v0.0.0-20210913165410-232392fc8a6a
go.etcd.io/bbolt v1.3.7 go.etcd.io/bbolt v1.3.7
golang.org/x/term v0.7.0 golang.org/x/term v0.10.0
gopkg.in/yaml.v3 v3.0.1 gopkg.in/yaml.v3 v3.0.1
gotest.tools/v3 v3.4.0 gotest.tools/v3 v3.5.0
) )
require ( require (
github.com/Microsoft/go-winio v0.5.2 // indirect dario.cat/mergo v1.0.0 // indirect
github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8 // indirect github.com/Microsoft/go-winio v0.6.1 // indirect
github.com/ProtonMail/go-crypto v0.0.0-20230717121422-5aa5874ade95 // indirect
github.com/acomagu/bufpipe v1.0.4 // indirect github.com/acomagu/bufpipe v1.0.4 // indirect
github.com/cloudflare/circl v1.1.0 // indirect github.com/cloudflare/circl v1.3.3 // indirect
github.com/containerd/containerd v1.6.20 // indirect github.com/containerd/containerd v1.7.2 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect
github.com/docker/docker-credential-helpers v0.7.0 // indirect github.com/docker/docker-credential-helpers v0.7.0 // indirect
github.com/docker/go-units v0.5.0 // indirect github.com/docker/go-units v0.5.0 // indirect
github.com/emirpasic/gods v1.18.1 // indirect github.com/emirpasic/gods v1.18.1 // indirect
github.com/fatih/color v1.15.0 // indirect github.com/fatih/color v1.15.0 // indirect
github.com/go-git/gcfg v1.5.0 // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
github.com/gogo/protobuf v1.3.2 // indirect github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/google/go-cmp v0.5.9 // indirect github.com/google/go-cmp v0.5.9 // indirect
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
github.com/kevinburke/ssh_config v1.2.0 // indirect github.com/kevinburke/ssh_config v1.2.0 // indirect
github.com/klauspost/compress v1.15.12 // indirect github.com/klauspost/compress v1.16.3 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-runewidth v0.0.14 // indirect github.com/mattn/go-runewidth v0.0.14 // indirect
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect
@@ -63,23 +66,25 @@ require (
github.com/moby/sys/sequential v0.5.0 // indirect github.com/moby/sys/sequential v0.5.0 // indirect
github.com/moby/term v0.0.0-20200312100748-672ec06f55cd // indirect github.com/moby/term v0.0.0-20200312100748-672ec06f55cd // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/runc v1.1.5 // indirect github.com/opencontainers/runc v1.1.7 // indirect
github.com/pjbgf/sha1cd v0.3.0 // indirect github.com/pjbgf/sha1cd v0.3.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rivo/uniseg v0.4.4 // indirect github.com/rivo/uniseg v0.4.4 // indirect
github.com/robfig/cron v1.2.0 // indirect github.com/robfig/cron v1.2.0 // indirect
github.com/sergi/go-diff v1.2.0 // indirect github.com/sergi/go-diff v1.2.0 // indirect
github.com/skeema/knownhosts v1.1.0 // indirect github.com/skeema/knownhosts v1.2.0 // indirect
github.com/stretchr/objx v0.5.0 // indirect github.com/stretchr/objx v0.5.0 // indirect
github.com/xanzy/ssh-agent v0.3.3 // indirect github.com/xanzy/ssh-agent v0.3.3 // indirect
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
github.com/xeipuuv/gojsonschema v1.2.0 // indirect github.com/xeipuuv/gojsonschema v1.2.0 // indirect
golang.org/x/crypto v0.6.0 // indirect golang.org/x/crypto v0.11.0 // indirect
golang.org/x/net v0.7.0 // indirect golang.org/x/mod v0.9.0 // indirect
golang.org/x/sync v0.1.0 // indirect golang.org/x/net v0.12.0 // indirect
golang.org/x/sys v0.7.0 // indirect golang.org/x/sync v0.2.0 // indirect
golang.org/x/text v0.7.0 // indirect golang.org/x/sys v0.10.0 // indirect
golang.org/x/text v0.11.0 // indirect
golang.org/x/tools v0.7.0 // indirect
gopkg.in/warnings.v0 v0.1.2 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect
) )

202
go.sum
View File

@@ -1,17 +1,20 @@
github.com/AlecAivazis/survey/v2 v2.3.6 h1:NvTuVHISgTHEHeBFqt6BHOe4Ny/NwGZr7w+F8S9ziyw= dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk=
github.com/AlecAivazis/survey/v2 v2.3.6/go.mod h1:4AuI9b7RjAR+G7v9+C4YSlX/YL3K3cWNXgWXOhllqvI= dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230106234847-43070de90fa1 h1:EKPd1INOIyr5hWOWhvpmQpY6tKjeG0hT1s3AMC/9fic=
github.com/AlecAivazis/survey/v2 v2.3.7 h1:6I/u8FvytdGsgonrYsVn2t8t4QiRnh6QSTqkkhIiSjQ=
github.com/AlecAivazis/survey/v2 v2.3.7/go.mod h1:xUTIdE4KCOIjsBAE1JYsUPoCqYdZ1reCfTwbto0Fduo=
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8= github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8=
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=
github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
github.com/Microsoft/go-winio v0.5.2 h1:a9IhgEQBCUEk6QCdml9CiJGhAws+YwffDHEMp1VMrpA=
github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
github.com/Microsoft/hcsshim v0.9.8 h1:lf7xxK2+Ikbj9sVf2QZsouGjRjEp2STj1yDHgoVtU5k= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=
github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
github.com/Microsoft/hcsshim v0.10.0-rc.8 h1:YSZVvlIIDD1UxQpJp0h+dnpLUw+TrY0cx8obKsp3bek=
github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2 h1:+vx7roKuyA63nhn5WAunQHLTznkw5W8b1Xc0dNjp83s= github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2 h1:+vx7roKuyA63nhn5WAunQHLTznkw5W8b1Xc0dNjp83s=
github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2/go.mod h1:HBCaDeC1lPdgDeDbhX8XFpy1jqjK0IBG8W5K+xYqA0w= github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2/go.mod h1:HBCaDeC1lPdgDeDbhX8XFpy1jqjK0IBG8W5K+xYqA0w=
github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8 h1:wPbRQzjjwFc0ih8puEVAOFGELsn1zoIIYdxvML7mDxA= github.com/ProtonMail/go-crypto v0.0.0-20230717121422-5aa5874ade95 h1:KLq8BE0KwCL+mmXnjLWEAOYO+2l2AE4YMmqG1ZpZHBs=
github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8/go.mod h1:I0gYDMZ6Z5GRU7l58bNFSkPTFN6Yl12dsUlAZ8xy98g= github.com/ProtonMail/go-crypto v0.0.0-20230717121422-5aa5874ade95/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0=
github.com/acomagu/bufpipe v1.0.4 h1:e3H4WUzM3npvo5uv95QuJM3cQspFNtFBzvJ2oNjKIDQ= github.com/acomagu/bufpipe v1.0.4 h1:e3H4WUzM3npvo5uv95QuJM3cQspFNtFBzvJ2oNjKIDQ=
github.com/acomagu/bufpipe v1.0.4/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4= github.com/acomagu/bufpipe v1.0.4/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4=
github.com/adrg/xdg v0.4.0 h1:RzRqFcjH4nE5C6oTAxhBtoE2IRyjBSa62SCbyPidvls= github.com/adrg/xdg v0.4.0 h1:RzRqFcjH4nE5C6oTAxhBtoE2IRyjBSa62SCbyPidvls=
@@ -19,81 +22,66 @@ github.com/adrg/xdg v0.4.0/go.mod h1:N6ag73EX4wyxeaoeHctc1mas01KZgsj5tYiAIwqJE/E
github.com/andreaskoch/go-fswatch v1.0.0 h1:la8nP/HiaFCxP2IM6NZNUCoxgLWuyNFgH0RligBbnJU= github.com/andreaskoch/go-fswatch v1.0.0 h1:la8nP/HiaFCxP2IM6NZNUCoxgLWuyNFgH0RligBbnJU=
github.com/andreaskoch/go-fswatch v1.0.0/go.mod h1:r5/iV+4jfwoY2sYqBkg8vpF04ehOvEl4qPptVGdxmqo= github.com/andreaskoch/go-fswatch v1.0.0/go.mod h1:r5/iV+4jfwoY2sYqBkg8vpF04ehOvEl4qPptVGdxmqo=
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8=
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= github.com/cloudflare/circl v1.3.3 h1:fE/Qz0QdIGqeWfnwq0RE0R7MI51s0M2E4Ga9kq5AEMs=
github.com/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAcn+zUUwWxqcaKZlF54wK8E= github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA=
github.com/cilium/ebpf v0.7.0/go.mod h1:/oI2+1shJiTGAMgl6/RgJr36Eo1jzrRcAWbcXO2usCA= github.com/containerd/containerd v1.7.2 h1:UF2gdONnxO8I6byZXDi5sXWiWvlW3D/sci7dTQimEJo=
github.com/cloudflare/circl v1.1.0 h1:bZgT/A+cikZnKIwn7xL2OBj012Bmvho/o6RpRvv3GKY= github.com/containerd/containerd v1.7.2/go.mod h1:afcz74+K10M/+cjGHIVQrCt3RAQhUSCAjJ9iMYhhkuI=
github.com/cloudflare/circl v1.1.0/go.mod h1:prBCrKB9DV4poKZY1l9zBXg2QJY7mvgRvtMxxK7fi4I=
github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U=
github.com/containerd/containerd v1.6.20 h1:+itjwpdqXpzHB/QAiWc/BZCjjVfcNgw69w/oIeF4Oy0=
github.com/containerd/containerd v1.6.20/go.mod h1:apei1/i5Ux2FzrK6+DM/suEsGuK/MeVOfy8tR2q7Wnw=
github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg=
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/creack/pty v1.1.17/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= github.com/creack/pty v1.1.17/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= github.com/cyphar/filepath-securejoin v0.2.3 h1:YX6ebbZCZP7VkM3scTTokDgBL2TY741X51MTk3ycuNI=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 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/docker/cli v23.0.4+incompatible h1:xClB7PsiATttDHj8ce5qvJcikiApNy7teRR1XkoBZGs= github.com/docker/cli v24.0.5+incompatible h1:WeBimjvS0eKdH4Ygx+ihVq1Q++xg36M/rMi4aXAvodc=
github.com/docker/cli v23.0.4+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/cli v24.0.5+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/distribution v2.8.1+incompatible h1:Q50tZOPR6T/hjNsyc9g8/syEs6bk8XXApsHjKukMl68= github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8=
github.com/docker/distribution v2.8.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/docker v23.0.4+incompatible h1:Kd3Bh9V/rO+XpTP/BLqM+gx8z7+Yb0AA2Ibj+nNo4ek= github.com/docker/docker v24.0.5+incompatible h1:WmgcE4fxyI6EEXxBRxsHnZXrO1pQ3smi0k/jho4HLeY=
github.com/docker/docker v23.0.4+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v24.0.5+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker-credential-helpers v0.7.0 h1:xtCHsjxogADNZcdv1pKUHXryefjlVRqWqIhk/uXJp0A= github.com/docker/docker-credential-helpers v0.7.0 h1:xtCHsjxogADNZcdv1pKUHXryefjlVRqWqIhk/uXJp0A=
github.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0= github.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0=
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/elazarl/goproxy v0.0.0-20221015165544-a0805db90819 h1:RIB4cRk+lBqKK3Oy0r2gRX4ui7tuhiZq2SuTtTCi0/0=
github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=
github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ=
github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs=
github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw=
github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k=
github.com/gliderlabs/ssh v0.3.5 h1:OcaySEmAQJgyYcArR+gGGTHCyE7nvhEMTlYY+Dp8CpY= github.com/gliderlabs/ssh v0.3.5 h1:OcaySEmAQJgyYcArR+gGGTHCyE7nvhEMTlYY+Dp8CpY=
github.com/gliderlabs/ssh v0.3.5/go.mod h1:8XB4KraRrX39qHhT6yxPsHedjA08I/uBVwj4xC+/+z4= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI=
github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic=
github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E=
github.com/go-git/go-billy/v5 v5.3.1/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0=
github.com/go-git/go-billy/v5 v5.4.1 h1:Uwp5tDRkPr+l/TnbHOQzp+tmJfLceOlbVucgpTz8ix4= github.com/go-git/go-billy/v5 v5.4.1 h1:Uwp5tDRkPr+l/TnbHOQzp+tmJfLceOlbVucgpTz8ix4=
github.com/go-git/go-billy/v5 v5.4.1/go.mod h1:vjbugF6Fz7JIflbVpl1hJsGjSHNltrSw45YK/ukIvQg= github.com/go-git/go-billy/v5 v5.4.1/go.mod h1:vjbugF6Fz7JIflbVpl1hJsGjSHNltrSw45YK/ukIvQg=
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20230305113008-0c11038e723f h1:Pz0DHeFij3XFhoBRGUDPzSJ+w2UcK5/0JvF8DRI58r8= github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20230305113008-0c11038e723f h1:Pz0DHeFij3XFhoBRGUDPzSJ+w2UcK5/0JvF8DRI58r8=
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20230305113008-0c11038e723f/go.mod h1:8LHG1a3SRW71ettAD/jW13h8c6AqjVSeL11RAdgaqpo= github.com/go-git/go-git/v5 v5.8.1 h1:Zo79E4p7TRk0xoRgMq0RShiTHGKcKI4+DI6BfJc/Q+A=
github.com/go-git/go-git/v5 v5.6.2-0.20230411180853-ce62f3e9ff86 h1:vbnwVQwGOr4xwrtcZ1lrhWHPMIgWkhNv+2+smiA2HHk= github.com/go-git/go-git/v5 v5.8.1/go.mod h1:FHFuoD6yGz5OSKEBK+aWN9Oah0q54Jxl0abmj6GnqAo=
github.com/go-git/go-git/v5 v5.6.2-0.20230411180853-ce62f3e9ff86/go.mod h1:Q3/DKr39xeJ3oEAVC8Q1+BlJK3OMsOQsksNb3s+9M1A= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
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/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec h1:qv2VnGeEQHchGaZ/u7lxST/RaJw+cv273q79D81Xbog= github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec h1:qv2VnGeEQHchGaZ/u7lxST/RaJw+cv273q79D81Xbog=
github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec/go.mod h1:Q48J4R4DvxnHolD5P8pOtXigYlRuPLGl6moFx3ulM68= github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec/go.mod h1:Q48J4R4DvxnHolD5P8pOtXigYlRuPLGl6moFx3ulM68=
github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg= github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4=
github.com/imdario/mergo v0.3.15 h1:M8XP7IuFNsqUx6VPK2P9OSmsYsI/YFaGil0uD21V3dM= github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=
github.com/imdario/mergo v0.3.15/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4=
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U= github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U=
@@ -104,12 +92,12 @@ github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4
github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.15.12 h1:YClS/PImqYbn+UILDnqxQCZ3RehC9N318SU3kElDUEM= github.com/klauspost/compress v1.16.3 h1:XuJt9zzcnaz6a16/OU53ZjWp/v7/42WcR5t2a0PcNQY=
github.com/klauspost/compress v1.15.12/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= github.com/klauspost/compress v1.16.3/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
@@ -121,35 +109,30 @@ github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxec
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.18 h1:DOKFKCQ7FNG2L1rbrmstDN4QVRdS89Nkh85u68Uwp98= github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
github.com/mattn/go-isatty v0.0.18/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU=
github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4= github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4=
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mmcloughlin/avo v0.5.0/go.mod h1:ChHFdoV7ql95Wi7vuq2YT1bwCJqiWdZrQ1im3VujLYM= github.com/moby/buildkit v0.12.0 h1:hgPDVSeondFLb28cBtRR5O0N4t8uWGJ4YNukT2aICIs=
github.com/moby/buildkit v0.11.6 h1:VYNdoKk5TVxN7k4RvZgdeM4GOyRvIi4Z8MXOY7xvyUs= github.com/moby/buildkit v0.12.0/go.mod h1:+n9GmkxwBCjVz4u7wmiyh+oqvjIjQM+1zk3iJrWfdos=
github.com/moby/buildkit v0.11.6/go.mod h1:GCqKfHhz+pddzfgaR7WmHVEE3nKKZMMDPpK8mh3ZLv4=
github.com/moby/patternmatcher v0.5.0 h1:YCZgJOeULcxLw1Q+sVR636pmS7sPEn1Qo2iAN6M7DBo= github.com/moby/patternmatcher v0.5.0 h1:YCZgJOeULcxLw1Q+sVR636pmS7sPEn1Qo2iAN6M7DBo=
github.com/moby/patternmatcher v0.5.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc= github.com/moby/patternmatcher v0.5.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc=
github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU=
github.com/moby/sys/sequential v0.5.0 h1:OPvI35Lzn9K04PBbCLW0g4LcFAJgHsvXsRyewg5lXtc= github.com/moby/sys/sequential v0.5.0 h1:OPvI35Lzn9K04PBbCLW0g4LcFAJgHsvXsRyewg5lXtc=
github.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWKGRYaaV5ZZlo= github.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWKGRYaaV5ZZlo=
github.com/moby/term v0.0.0-20200312100748-672ec06f55cd h1:aY7OQNf2XqY/JQ6qREWamhI/81os/agb2BAGpcx5yWI= github.com/moby/term v0.0.0-20200312100748-672ec06f55cd h1:aY7OQNf2XqY/JQ6qREWamhI/81os/agb2BAGpcx5yWI=
github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo= github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo=
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b h1:YWuSjZCQAPM8UUBLkYUk1e+rZcvWHJmFb6i6rM44Xs8= github.com/opencontainers/image-spec v1.1.0-rc4 h1:oOxKUJWnFC4YGHCCMNql1x4YaDfYBTS5Y4x/Cgeo1E0=
github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b/go.mod h1:3OVijpioIKYWTqjiG0zfF6wvoJ4fAXGbjdZuI2NgsRQ= github.com/opencontainers/image-spec v1.1.0-rc4/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8=
github.com/opencontainers/runc v1.1.5 h1:L44KXEpKmfWDcS02aeGm8QNTFXTo2D+8MYGDIJ/GDEs= github.com/opencontainers/runc v1.1.7 h1:y2EZDS8sNng4Ksf0GUYNhKbTShZJPJg1FiXJNH/uoCk=
github.com/opencontainers/runc v1.1.5/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg= github.com/opencontainers/runc v1.1.7/go.mod h1:CbUumNnWCuTGFukNXahoo/RFBZvDAgRh/smNYNOhA50=
github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/opencontainers/selinux v1.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI=
github.com/opencontainers/selinux v1.11.0 h1:+5Zbo97w3Lbmb3PeqQtpmTkMwsW5nRI3YaLpt7tQ7oU= github.com/opencontainers/selinux v1.11.0 h1:+5Zbo97w3Lbmb3PeqQtpmTkMwsW5nRI3YaLpt7tQ7oU=
github.com/opencontainers/selinux v1.11.0/go.mod h1:E5dMC3VPuVvVHDYmi78qvhJp8+M586T4DlDRYpFkyec= github.com/opencontainers/selinux v1.11.0/go.mod h1:E5dMC3VPuVvVHDYmi78qvhJp8+M586T4DlDRYpFkyec=
github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4= github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4=
@@ -159,29 +142,25 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rhysd/actionlint v1.6.24 h1:5f61cF5ssP2pzG0jws5bEsfZBNhbBcO9nl7vTzVKjzs= github.com/rhysd/actionlint v1.6.25 h1:0Is99a51w1iocdxKUzNYiBNwjoSlO2Klqzll98joVj4=
github.com/rhysd/actionlint v1.6.24/go.mod h1:gQmz9r2wlcpLy+VdbzK0GINJQnAK5/sNH3BpwW4Mt5I= github.com/rhysd/actionlint v1.6.25/go.mod h1:Q+MtZKm1MdmJ9woOSKxLscMW7kU44/PShvjNy5ZKHA8=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis=
github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/robfig/cron v1.2.0 h1:ZjScXvvxeQ63Dbyxy76Fj3AT3Ut0aKsyd2/tl3DTMuQ= github.com/robfig/cron v1.2.0 h1:ZjScXvvxeQ63Dbyxy76Fj3AT3Ut0aKsyd2/tl3DTMuQ=
github.com/robfig/cron v1.2.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k= github.com/robfig/cron v1.2.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06 h1:OkMGxebDjyw0ULyrTYWeN0UNCCkmCWfjPnIA2W6oviI= github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06 h1:OkMGxebDjyw0ULyrTYWeN0UNCCkmCWfjPnIA2W6oviI=
github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06/go.mod h1:+ePHsJ1keEjQtpvf9HHw0f4ZeJ0TLRsxhunSI2hYJSs= github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06/go.mod h1:+ePHsJ1keEjQtpvf9HHw0f4ZeJ0TLRsxhunSI2hYJSs=
github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg=
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ=
github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/skeema/knownhosts v1.2.0 h1:h9r9cf0+u7wSE+M183ZtMGgOJKiL96brpaz5ekfJCpM=
github.com/skeema/knownhosts v1.1.0 h1:Wvr9V0MxhjRbl3f9nMnKnFfiWTJmtECJ9Njkea3ysW0= github.com/skeema/knownhosts v1.2.0/go.mod h1:g4fPeYpque7P0xefxtGzV81ihjC8sX2IqpAoNkjxbMo=
github.com/skeema/knownhosts v1.1.0/go.mod h1:sKFq3RD6/TKZkSWn8boUbDC7Qkgcv+8XXijpFO6roag=
github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I=
github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
@@ -199,14 +178,10 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
github.com/timshannon/bolthold v0.0.0-20210913165410-232392fc8a6a h1:oIi7H/bwFUYKYhzKbHc+3MvHRWqhQwXVB4LweLMiVy0= github.com/timshannon/bolthold v0.0.0-20210913165410-232392fc8a6a h1:oIi7H/bwFUYKYhzKbHc+3MvHRWqhQwXVB4LweLMiVy0=
github.com/timshannon/bolthold v0.0.0-20210913165410-232392fc8a6a/go.mod h1:iSvujNDmpZ6eQX+bg/0X3lF7LEmZ8N77g2a/J/+Zt2U= github.com/timshannon/bolthold v0.0.0-20210913165410-232392fc8a6a/go.mod h1:iSvujNDmpZ6eQX+bg/0X3lF7LEmZ8N77g2a/J/+Zt2U=
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU=
github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c=
@@ -221,107 +196,96 @@ github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5t
go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4=
go.etcd.io/bbolt v1.3.7 h1:j+zJOnnEjF/kyHlDDgGnVL/AIqIJPq8UoB2GSNfkUfQ= go.etcd.io/bbolt v1.3.7 h1:j+zJOnnEjF/kyHlDDgGnVL/AIqIJPq8UoB2GSNfkUfQ=
go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw=
golang.org/x/arch v0.1.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc= golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA=
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs=
golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50=
golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI=
golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.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.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU= golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
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-20210503060354-a79de5458b56/go.mod h1:tfny5GFUkzUvx4ps4ajbZsCe5lw1metzhBm9T3x7oIY=
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.0.0-20220722155259-a9ba230a4035/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.7.0 h1:BEvjmm5fURWqcfbSKTdpkDXYBrUS1c0m8agp14W48vQ= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= golang.org/x/term v0.10.0 h1:3R7pNqamzBraeqj/Tj8qt1aQ2HpmlC+Cx/qL/7hn4/c=
golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o=
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=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/time v0.1.0 h1:xYY+Bajn2a7VBmTM5GikTmnK8ZuX8YgnQCqZpbBNtmA= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4=
golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4=
golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
@@ -331,11 +295,9 @@ gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
gotest.tools/v3 v3.4.0 h1:ZazjZUfuVeZGLAmlKKuyv3IKP5orXcwtOwDQH6YVr6o= gotest.tools/v3 v3.5.0 h1:Ljk6PdHdOhAb5aDMWXjDLMMhph+BpztA4v1QdqEW2eY=
gotest.tools/v3 v3.4.0/go.mod h1:CtbdzLSsqVhDgMtKsx03ird5YTGB3ar27v0u/yKBW5g= gotest.tools/v3 v3.5.0/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU=
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=

View File

@@ -27,7 +27,7 @@ const (
) )
type Handler struct { type Handler struct {
db *bolthold.Store dir string
storage *Storage storage *Storage
router *httprouter.Router router *httprouter.Router
listener net.Listener listener net.Listener
@@ -62,19 +62,7 @@ func StartHandler(dir, outboundIP string, port uint16, logger logrus.FieldLogger
return nil, err return nil, err
} }
db, err := bolthold.Open(filepath.Join(dir, "bolt.db"), 0o644, &bolthold.Options{ h.dir = dir
Encoder: json.Marshal,
Decoder: json.Unmarshal,
Options: &bbolt.Options{
Timeout: 5 * time.Second,
NoGrowSync: bbolt.DefaultOptions.NoGrowSync,
FreelistType: bbolt.DefaultOptions.FreelistType,
},
})
if err != nil {
return nil, err
}
h.db = db
storage, err := NewStorage(filepath.Join(dir, "cache")) storage, err := NewStorage(filepath.Join(dir, "cache"))
if err != nil { if err != nil {
@@ -150,16 +138,21 @@ func (h *Handler) Close() error {
} }
h.listener = nil h.listener = nil
} }
if h.db != nil {
err := h.db.Close()
if err != nil {
retErr = err
}
h.db = nil
}
return retErr return retErr
} }
func (h *Handler) openDB() (*bolthold.Store, error) {
return bolthold.Open(filepath.Join(h.dir, "bolt.db"), 0o644, &bolthold.Options{
Encoder: json.Marshal,
Decoder: json.Unmarshal,
Options: &bbolt.Options{
Timeout: 5 * time.Second,
NoGrowSync: bbolt.DefaultOptions.NoGrowSync,
FreelistType: bbolt.DefaultOptions.FreelistType,
},
})
}
// GET /_apis/artifactcache/cache // GET /_apis/artifactcache/cache
func (h *Handler) find(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { func (h *Handler) find(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
keys := strings.Split(r.URL.Query().Get("keys"), ",") keys := strings.Split(r.URL.Query().Get("keys"), ",")
@@ -169,7 +162,14 @@ func (h *Handler) find(w http.ResponseWriter, r *http.Request, _ httprouter.Para
} }
version := r.URL.Query().Get("version") version := r.URL.Query().Get("version")
cache, err := h.findCache(keys, version) db, err := h.openDB()
if err != nil {
h.responseJSON(w, r, 500, err)
return
}
defer db.Close()
cache, err := h.findCache(db, keys, version)
if err != nil { if err != nil {
h.responseJSON(w, r, 500, err) h.responseJSON(w, r, 500, err)
return return
@@ -183,7 +183,7 @@ func (h *Handler) find(w http.ResponseWriter, r *http.Request, _ httprouter.Para
h.responseJSON(w, r, 500, err) h.responseJSON(w, r, 500, err)
return return
} else if !ok { } else if !ok {
_ = h.db.Delete(cache.ID, cache) _ = db.Delete(cache.ID, cache)
h.responseJSON(w, r, 204) h.responseJSON(w, r, 204)
return return
} }
@@ -206,7 +206,13 @@ func (h *Handler) reserve(w http.ResponseWriter, r *http.Request, _ httprouter.P
cache := api.ToCache() cache := api.ToCache()
cache.FillKeyVersionHash() cache.FillKeyVersionHash()
if err := h.db.FindOne(cache, bolthold.Where("KeyVersionHash").Eq(cache.KeyVersionHash)); err != nil { db, err := h.openDB()
if err != nil {
h.responseJSON(w, r, 500, err)
return
}
defer db.Close()
if err := db.FindOne(cache, bolthold.Where("KeyVersionHash").Eq(cache.KeyVersionHash)); err != nil {
if !errors.Is(err, bolthold.ErrNotFound) { if !errors.Is(err, bolthold.ErrNotFound) {
h.responseJSON(w, r, 500, err) h.responseJSON(w, r, 500, err)
return return
@@ -219,12 +225,12 @@ func (h *Handler) reserve(w http.ResponseWriter, r *http.Request, _ httprouter.P
now := time.Now().Unix() now := time.Now().Unix()
cache.CreatedAt = now cache.CreatedAt = now
cache.UsedAt = now cache.UsedAt = now
if err := h.db.Insert(bolthold.NextSequence(), cache); err != nil { if err := db.Insert(bolthold.NextSequence(), cache); err != nil {
h.responseJSON(w, r, 500, err) h.responseJSON(w, r, 500, err)
return return
} }
// write back id to db // write back id to db
if err := h.db.Update(cache.ID, cache); err != nil { if err := db.Update(cache.ID, cache); err != nil {
h.responseJSON(w, r, 500, err) h.responseJSON(w, r, 500, err)
return return
} }
@@ -242,7 +248,13 @@ func (h *Handler) upload(w http.ResponseWriter, r *http.Request, params httprout
} }
cache := &Cache{} cache := &Cache{}
if err := h.db.Get(id, cache); err != nil { db, err := h.openDB()
if err != nil {
h.responseJSON(w, r, 500, err)
return
}
defer db.Close()
if err := db.Get(id, cache); err != nil {
if errors.Is(err, bolthold.ErrNotFound) { if errors.Is(err, bolthold.ErrNotFound) {
h.responseJSON(w, r, 400, fmt.Errorf("cache %d: not reserved", id)) h.responseJSON(w, r, 400, fmt.Errorf("cache %d: not reserved", id))
return return
@@ -255,6 +267,7 @@ func (h *Handler) upload(w http.ResponseWriter, r *http.Request, params httprout
h.responseJSON(w, r, 400, fmt.Errorf("cache %v %q: already complete", cache.ID, cache.Key)) h.responseJSON(w, r, 400, fmt.Errorf("cache %v %q: already complete", cache.ID, cache.Key))
return return
} }
db.Close()
start, _, err := parseContentRange(r.Header.Get("Content-Range")) start, _, err := parseContentRange(r.Header.Get("Content-Range"))
if err != nil { if err != nil {
h.responseJSON(w, r, 400, err) h.responseJSON(w, r, 400, err)
@@ -276,7 +289,13 @@ func (h *Handler) commit(w http.ResponseWriter, r *http.Request, params httprout
} }
cache := &Cache{} cache := &Cache{}
if err := h.db.Get(id, cache); err != nil { db, err := h.openDB()
if err != nil {
h.responseJSON(w, r, 500, err)
return
}
defer db.Close()
if err := db.Get(id, cache); err != nil {
if errors.Is(err, bolthold.ErrNotFound) { if errors.Is(err, bolthold.ErrNotFound) {
h.responseJSON(w, r, 400, fmt.Errorf("cache %d: not reserved", id)) h.responseJSON(w, r, 400, fmt.Errorf("cache %d: not reserved", id))
return return
@@ -290,13 +309,25 @@ func (h *Handler) commit(w http.ResponseWriter, r *http.Request, params httprout
return return
} }
if err := h.storage.Commit(cache.ID, cache.Size); err != nil { db.Close()
size, err := h.storage.Commit(cache.ID, cache.Size)
if err != nil {
h.responseJSON(w, r, 500, err) h.responseJSON(w, r, 500, err)
return return
} }
// write real size back to cache, it may be different from the current value when the request doesn't specify it.
cache.Size = size
db, err = h.openDB()
if err != nil {
h.responseJSON(w, r, 500, err)
return
}
defer db.Close()
cache.Complete = true cache.Complete = true
if err := h.db.Update(cache.ID, cache); err != nil { if err := db.Update(cache.ID, cache); err != nil {
h.responseJSON(w, r, 500, err) h.responseJSON(w, r, 500, err)
return return
} }
@@ -332,7 +363,7 @@ func (h *Handler) middleware(handler httprouter.Handle) httprouter.Handle {
} }
// if not found, return (nil, nil) instead of an error. // if not found, return (nil, nil) instead of an error.
func (h *Handler) findCache(keys []string, version string) (*Cache, error) { func (h *Handler) findCache(db *bolthold.Store, keys []string, version string) (*Cache, error) {
if len(keys) == 0 { if len(keys) == 0 {
return nil, nil return nil, nil
} }
@@ -344,7 +375,7 @@ func (h *Handler) findCache(keys []string, version string) (*Cache, error) {
} }
cache.FillKeyVersionHash() cache.FillKeyVersionHash()
if err := h.db.FindOne(cache, bolthold.Where("KeyVersionHash").Eq(cache.KeyVersionHash)); err != nil { if err := db.FindOne(cache, bolthold.Where("KeyVersionHash").Eq(cache.KeyVersionHash)); err != nil {
if !errors.Is(err, bolthold.ErrNotFound) { if !errors.Is(err, bolthold.ErrNotFound) {
return nil, err return nil, err
} }
@@ -355,7 +386,7 @@ func (h *Handler) findCache(keys []string, version string) (*Cache, error) {
for _, prefix := range keys[1:] { for _, prefix := range keys[1:] {
found := false found := false
if err := h.db.ForEach(bolthold.Where("Key").Ge(prefix).And("Version").Eq(version).SortBy("Key"), func(v *Cache) error { if err := db.ForEach(bolthold.Where("Key").Ge(prefix).And("Version").Eq(version).SortBy("Key"), func(v *Cache) error {
if !strings.HasPrefix(v.Key, prefix) { if !strings.HasPrefix(v.Key, prefix) {
return stop return stop
} }
@@ -378,12 +409,17 @@ func (h *Handler) findCache(keys []string, version string) (*Cache, error) {
} }
func (h *Handler) useCache(id int64) { func (h *Handler) useCache(id int64) {
db, err := h.openDB()
if err != nil {
return
}
defer db.Close()
cache := &Cache{} cache := &Cache{}
if err := h.db.Get(id, cache); err != nil { if err := db.Get(id, cache); err != nil {
return return
} }
cache.UsedAt = time.Now().Unix() cache.UsedAt = time.Now().Unix()
_ = h.db.Update(cache.ID, cache) _ = db.Update(cache.ID, cache)
} }
func (h *Handler) gcCache() { func (h *Handler) gcCache() {
@@ -408,8 +444,14 @@ func (h *Handler) gcCache() {
keepTemp = 5 * time.Minute keepTemp = 5 * time.Minute
) )
db, err := h.openDB()
if err != nil {
return
}
defer db.Close()
var caches []*Cache var caches []*Cache
if err := h.db.Find(&caches, bolthold.Where("UsedAt").Lt(time.Now().Add(-keepTemp).Unix())); err != nil { if err := db.Find(&caches, bolthold.Where("UsedAt").Lt(time.Now().Add(-keepTemp).Unix())); err != nil {
h.logger.Warnf("find caches: %v", err) h.logger.Warnf("find caches: %v", err)
} else { } else {
for _, cache := range caches { for _, cache := range caches {
@@ -417,7 +459,7 @@ func (h *Handler) gcCache() {
continue continue
} }
h.storage.Remove(cache.ID) h.storage.Remove(cache.ID)
if err := h.db.Delete(cache.ID, cache); err != nil { if err := db.Delete(cache.ID, cache); err != nil {
h.logger.Warnf("delete cache: %v", err) h.logger.Warnf("delete cache: %v", err)
continue continue
} }
@@ -426,12 +468,12 @@ func (h *Handler) gcCache() {
} }
caches = caches[:0] caches = caches[:0]
if err := h.db.Find(&caches, bolthold.Where("UsedAt").Lt(time.Now().Add(-keepUnused).Unix())); err != nil { if err := db.Find(&caches, bolthold.Where("UsedAt").Lt(time.Now().Add(-keepUnused).Unix())); err != nil {
h.logger.Warnf("find caches: %v", err) h.logger.Warnf("find caches: %v", err)
} else { } else {
for _, cache := range caches { for _, cache := range caches {
h.storage.Remove(cache.ID) h.storage.Remove(cache.ID)
if err := h.db.Delete(cache.ID, cache); err != nil { if err := db.Delete(cache.ID, cache); err != nil {
h.logger.Warnf("delete cache: %v", err) h.logger.Warnf("delete cache: %v", err)
continue continue
} }
@@ -440,12 +482,12 @@ func (h *Handler) gcCache() {
} }
caches = caches[:0] caches = caches[:0]
if err := h.db.Find(&caches, bolthold.Where("CreatedAt").Lt(time.Now().Add(-keepUsed).Unix())); err != nil { if err := db.Find(&caches, bolthold.Where("CreatedAt").Lt(time.Now().Add(-keepUsed).Unix())); err != nil {
h.logger.Warnf("find caches: %v", err) h.logger.Warnf("find caches: %v", err)
} else { } else {
for _, cache := range caches { for _, cache := range caches {
h.storage.Remove(cache.ID) h.storage.Remove(cache.ID)
if err := h.db.Delete(cache.ID, cache); err != nil { if err := db.Delete(cache.ID, cache); err != nil {
h.logger.Warnf("delete cache: %v", err) h.logger.Warnf("delete cache: %v", err)
continue continue
} }

View File

@@ -25,7 +25,10 @@ func TestHandler(t *testing.T) {
defer func() { defer func() {
t.Run("inpect db", func(t *testing.T) { t.Run("inpect db", func(t *testing.T) {
require.NoError(t, handler.db.Bolt().View(func(tx *bbolt.Tx) error { db, err := handler.openDB()
require.NoError(t, err)
defer db.Close()
require.NoError(t, db.Bolt().View(func(tx *bbolt.Tx) error {
return tx.Bucket([]byte("Cache")).ForEach(func(k, v []byte) error { return tx.Bucket([]byte("Cache")).ForEach(func(k, v []byte) error {
t.Logf("%s: %s", k, v) t.Logf("%s: %s", k, v)
return nil return nil
@@ -36,7 +39,6 @@ func TestHandler(t *testing.T) {
require.NoError(t, handler.Close()) require.NoError(t, handler.Close())
assert.Nil(t, handler.server) assert.Nil(t, handler.server)
assert.Nil(t, handler.listener) assert.Nil(t, handler.listener)
assert.Nil(t, handler.db)
_, err := http.Post(fmt.Sprintf("%s/caches/%d", base, 1), "", nil) _, err := http.Post(fmt.Sprintf("%s/caches/%d", base, 1), "", nil)
assert.Error(t, err) assert.Error(t, err)
}) })

View File

@@ -15,11 +15,17 @@ func (c *Request) ToCache() *Cache {
if c == nil { if c == nil {
return nil return nil
} }
return &Cache{ ret := &Cache{
Key: c.Key, Key: c.Key,
Version: c.Version, Version: c.Version,
Size: c.Size, Size: c.Size,
} }
if c.Size == 0 {
// So the request comes from old versions of actions, like `actions/cache@v2`.
// It doesn't send cache size. Set it to -1 to indicate that.
ret.Size = -1
}
return ret
} }
type Cache struct { type Cache struct {

View File

@@ -46,7 +46,7 @@ func (s *Storage) Write(id uint64, offset int64, reader io.Reader) error {
return err return err
} }
func (s *Storage) Commit(id uint64, size int64) error { func (s *Storage) Commit(id uint64, size int64) (int64, error) {
defer func() { defer func() {
_ = os.RemoveAll(s.tempDir(id)) _ = os.RemoveAll(s.tempDir(id))
}() }()
@@ -54,15 +54,15 @@ func (s *Storage) Commit(id uint64, size int64) error {
name := s.filename(id) name := s.filename(id)
tempNames, err := s.tempNames(id) tempNames, err := s.tempNames(id)
if err != nil { if err != nil {
return err return 0, err
} }
if err := os.MkdirAll(filepath.Dir(name), 0o755); err != nil { if err := os.MkdirAll(filepath.Dir(name), 0o755); err != nil {
return err return 0, err
} }
file, err := os.Create(name) file, err := os.Create(name)
if err != nil { if err != nil {
return err return 0, err
} }
defer file.Close() defer file.Close()
@@ -70,22 +70,26 @@ func (s *Storage) Commit(id uint64, size int64) error {
for _, v := range tempNames { for _, v := range tempNames {
f, err := os.Open(v) f, err := os.Open(v)
if err != nil { if err != nil {
return err return 0, err
} }
n, err := io.Copy(file, f) n, err := io.Copy(file, f)
_ = f.Close() _ = f.Close()
if err != nil { if err != nil {
return err return 0, err
} }
written += n written += n
} }
if written != size { // If size is less than 0, it means the size is unknown.
// We can't check the size of the file, just skip the check.
// It happens when the request comes from old versions of actions, like `actions/cache@v2`.
if size >= 0 && written != size {
_ = file.Close() _ = file.Close()
_ = os.Remove(name) _ = os.Remove(name)
return fmt.Errorf("broken file: %v != %v", written, size) return 0, fmt.Errorf("broken file: %v != %v", written, size)
} }
return nil
return written, nil
} }
func (s *Storage) Serve(w http.ResponseWriter, r *http.Request, id uint64) { func (s *Storage) Serve(w http.ResponseWriter, r *http.Request, id uint64) {

View File

@@ -79,7 +79,7 @@ func (fwfs readWriteFSImpl) OpenAppendable(name string) (WritableFile, error) {
return nil, err return nil, err
} }
_, err = file.Seek(0, os.SEEK_END) _, err = file.Seek(0, io.SeekEnd)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -223,9 +223,13 @@ func downloads(router *httprouter.Router, baseDir string, fsys fs.FS) {
// if it was upload as gzip // if it was upload as gzip
rel = strings.TrimSuffix(rel, gzipExtension) rel = strings.TrimSuffix(rel, gzipExtension)
path := filepath.Join(itemPath, rel)
rel = filepath.ToSlash(rel)
path = filepath.ToSlash(path)
files = append(files, ContainerItem{ files = append(files, ContainerItem{
Path: filepath.Join(itemPath, rel), Path: path,
ItemType: "file", ItemType: "file",
ContentLocation: fmt.Sprintf("http://%s/artifact/%s/%s/%s", req.Host, container, itemPath, rel), ContentLocation: fmt.Sprintf("http://%s/artifact/%s/%s/%s", req.Host, container, itemPath, rel),
}) })

View File

@@ -14,10 +14,11 @@ import (
"testing/fstest" "testing/fstest"
"github.com/julienschmidt/httprouter" "github.com/julienschmidt/httprouter"
"github.com/nektos/act/pkg/model"
"github.com/nektos/act/pkg/runner"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/nektos/act/pkg/model"
"github.com/nektos/act/pkg/runner"
) )
type writableMapFile struct { type writableMapFile struct {
@@ -238,9 +239,11 @@ type TestJobFileInfo struct {
containerArchitecture string containerArchitecture string
} }
var artifactsPath = path.Join(os.TempDir(), "test-artifacts") var (
var artifactsAddr = "127.0.0.1" artifactsPath = path.Join(os.TempDir(), "test-artifacts")
var artifactsPort = "12345" artifactsAddr = "127.0.0.1"
artifactsPort = "12345"
)
func TestArtifactFlow(t *testing.T) { func TestArtifactFlow(t *testing.T) {
if testing.Short() { if testing.Short() {
@@ -253,7 +256,7 @@ func TestArtifactFlow(t *testing.T) {
defer cancel() defer cancel()
platforms := map[string]string{ platforms := map[string]string{
"ubuntu-latest": "node:16-buster-slim", "ubuntu-latest": "node:16-buster", // Don't use node:16-buster-slim because it doesn't have curl command, which is used in the tests
} }
tables := []TestJobFileInfo{ tables := []TestJobFileInfo{

View File

@@ -8,9 +8,7 @@ jobs:
steps: steps:
- run: echo "hello world" > test.txt - run: echo "hello world" > test.txt
- name: curl upload - name: curl upload
uses: wei/curl@v1 run: curl --silent --show-error --fail ${ACTIONS_RUNTIME_URL}upload/1?itemPath=../../my-artifact/secret.txt --upload-file test.txt
with:
args: -s --fail ${ACTIONS_RUNTIME_URL}upload/1?itemPath=../../my-artifact/secret.txt --upload-file test.txt
- uses: actions/download-artifact@v2 - uses: actions/download-artifact@v2
with: with:
name: my-artifact name: my-artifact
@@ -27,9 +25,7 @@ jobs:
exit 1 exit 1
fi fi
- name: Verify download should work by clean extra dots - name: Verify download should work by clean extra dots
uses: wei/curl@v1 run: curl --silent --show-error --fail --path-as-is -o out.txt ${ACTIONS_RUNTIME_URL}artifact/1/../../../1/my-artifact/secret.txt
with:
args: --path-as-is -s -o out.txt --fail ${ACTIONS_RUNTIME_URL}artifact/1/../../../1/my-artifact/secret.txt
- name: 'Verify download content' - name: 'Verify download content'
run: | run: |
file="out.txt" file="out.txt"

View File

@@ -3,6 +3,8 @@ package common
import ( import (
"context" "context"
"fmt" "fmt"
log "github.com/sirupsen/logrus"
) )
// Warning that implements `error` but safe to ignore // Warning that implements `error` but safe to ignore
@@ -94,6 +96,11 @@ func NewParallelExecutor(parallel int, executors ...Executor) Executor {
work := make(chan Executor, len(executors)) work := make(chan Executor, len(executors))
errs := make(chan error, len(executors)) errs := make(chan error, len(executors))
if 1 > parallel {
log.Infof("Parallel tasks (%d) below minimum, setting to 1", parallel)
parallel = 1
}
for i := 0; i < parallel; i++ { for i := 0; i < parallel; i++ {
go func(work <-chan Executor, errs chan<- error) { go func(work <-chan Executor, errs chan<- error) {
for executor := range work { for executor := range work {

View File

@@ -100,6 +100,17 @@ func TestNewParallelExecutor(t *testing.T) {
assert.Equal(3, count, "should run all 3 executors") assert.Equal(3, count, "should run all 3 executors")
assert.Equal(2, maxCount, "should run at most 2 executors in parallel") assert.Equal(2, maxCount, "should run at most 2 executors in parallel")
assert.Nil(err) assert.Nil(err)
// Reset to test running the executor with 0 parallelism
count = 0
activeCount = 0
maxCount = 0
errSingle := NewParallelExecutor(0, emptyWorkflow, emptyWorkflow, emptyWorkflow)(ctx)
assert.Equal(3, count, "should run all 3 executors")
assert.Equal(1, maxCount, "should run at most 1 executors in parallel")
assert.Nil(errSingle)
} }
func TestNewParallelExecutorFailed(t *testing.T) { func TestNewParallelExecutorFailed(t *testing.T) {

View File

@@ -174,7 +174,7 @@ func FindGithubRepo(ctx context.Context, file, githubInstance, remoteName string
return slug, err return slug, err
} }
func findGitRemoteURL(ctx context.Context, file, remoteName string) (string, error) { func findGitRemoteURL(_ context.Context, file, remoteName string) (string, error) {
repo, err := git.PlainOpenWithOptions( repo, err := git.PlainOpenWithOptions(
file, file,
&git.PlainOpenOptions{ &git.PlainOpenOptions{

View File

@@ -8,16 +8,16 @@ import (
"github.com/docker/cli/cli/config" "github.com/docker/cli/cli/config"
"github.com/docker/cli/cli/config/credentials" "github.com/docker/cli/cli/config/credentials"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types/registry"
"github.com/nektos/act/pkg/common" "github.com/nektos/act/pkg/common"
) )
func LoadDockerAuthConfig(ctx context.Context, image string) (types.AuthConfig, error) { func LoadDockerAuthConfig(ctx context.Context, image string) (registry.AuthConfig, error) {
logger := common.Logger(ctx) logger := common.Logger(ctx)
config, err := config.Load(config.Dir()) config, err := config.Load(config.Dir())
if err != nil { if err != nil {
logger.Warnf("Could not load docker config: %v", err) logger.Warnf("Could not load docker config: %v", err)
return types.AuthConfig{}, err return registry.AuthConfig{}, err
} }
if !config.ContainsAuth() { if !config.ContainsAuth() {
@@ -33,13 +33,13 @@ func LoadDockerAuthConfig(ctx context.Context, image string) (types.AuthConfig,
authConfig, err := config.GetAuthConfig(hostName) authConfig, err := config.GetAuthConfig(hostName)
if err != nil { if err != nil {
logger.Warnf("Could not get auth config from docker config: %v", err) logger.Warnf("Could not get auth config from docker config: %v", err)
return types.AuthConfig{}, err return registry.AuthConfig{}, err
} }
return types.AuthConfig(authConfig), nil return registry.AuthConfig(authConfig), nil
} }
func LoadDockerAuthConfigs(ctx context.Context) map[string]types.AuthConfig { func LoadDockerAuthConfigs(ctx context.Context) map[string]registry.AuthConfig {
logger := common.Logger(ctx) logger := common.Logger(ctx)
config, err := config.Load(config.Dir()) config, err := config.Load(config.Dir())
if err != nil { if err != nil {
@@ -52,9 +52,9 @@ func LoadDockerAuthConfigs(ctx context.Context) map[string]types.AuthConfig {
} }
creds, _ := config.GetAllCredentials() creds, _ := config.GetAllCredentials()
authConfigs := make(map[string]types.AuthConfig, len(creds)) authConfigs := make(map[string]registry.AuthConfig, len(creds))
for k, v := range creds { for k, v := range creds {
authConfigs[k] = types.AuthConfig(v) authConfigs[k] = registry.AuthConfig(v)
} }
return authConfigs return authConfigs

View File

@@ -7,9 +7,11 @@ import (
"encoding/base64" "encoding/base64"
"encoding/json" "encoding/json"
"fmt" "fmt"
"strings"
"github.com/docker/distribution/reference" "github.com/docker/distribution/reference"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/registry"
"github.com/nektos/act/pkg/common" "github.com/nektos/act/pkg/common"
) )
@@ -59,6 +61,13 @@ func NewDockerPullExecutor(input NewDockerPullExecutorInput) common.Executor {
_ = logDockerResponse(logger, reader, err != nil) _ = logDockerResponse(logger, reader, err != nil)
if err != nil { if err != nil {
if imagePullOptions.RegistryAuth != "" && strings.Contains(err.Error(), "unauthorized") {
logger.Errorf("pulling image '%v' (%s) failed with credentials %s retrying without them, please check for stale docker config files", imageRef, input.Platform, err.Error())
imagePullOptions.RegistryAuth = ""
reader, err = cli.ImagePull(ctx, imageRef, imagePullOptions)
_ = logDockerResponse(logger, reader, err != nil)
}
return err return err
} }
return nil return nil
@@ -69,12 +78,12 @@ func getImagePullOptions(ctx context.Context, input NewDockerPullExecutorInput)
imagePullOptions := types.ImagePullOptions{ imagePullOptions := types.ImagePullOptions{
Platform: input.Platform, Platform: input.Platform,
} }
logger := common.Logger(ctx)
if input.Username != "" && input.Password != "" { if input.Username != "" && input.Password != "" {
logger := common.Logger(ctx)
logger.Debugf("using authentication for docker pull") logger.Debugf("using authentication for docker pull")
authConfig := types.AuthConfig{ authConfig := registry.AuthConfig{
Username: input.Username, Username: input.Username,
Password: input.Password, Password: input.Password,
} }
@@ -93,6 +102,7 @@ func getImagePullOptions(ctx context.Context, input NewDockerPullExecutorInput)
if authConfig.Username == "" && authConfig.Password == "" { if authConfig.Username == "" && authConfig.Password == "" {
return imagePullOptions, nil return imagePullOptions, nil
} }
logger.Info("using DockerAuthConfig authentication for docker pull")
encodedJSON, err := json.Marshal(authConfig) encodedJSON, err := json.Marshal(authConfig)
if err != nil { if err != nil {

View File

@@ -18,6 +18,7 @@ import (
"github.com/docker/docker/api/types/network" "github.com/docker/docker/api/types/network"
networktypes "github.com/docker/docker/api/types/network" networktypes "github.com/docker/docker/api/types/network"
"github.com/gobwas/glob"
"github.com/go-git/go-billy/v5/helper/polyfill" "github.com/go-git/go-billy/v5/helper/polyfill"
"github.com/go-git/go-billy/v5/osfs" "github.com/go-git/go-billy/v5/osfs"
@@ -263,8 +264,8 @@ func RunnerArch(ctx context.Context) string {
archMapper := map[string]string{ archMapper := map[string]string{
"x86_64": "X64", "x86_64": "X64",
"386": "x86", "386": "X86",
"aarch64": "arm64", "aarch64": "ARM64",
} }
if arch, ok := archMapper[info.Architecture]; ok { if arch, ok := archMapper[info.Architecture]; ok {
return arch return arch
@@ -660,7 +661,7 @@ func (cr *containerReference) tryReadGID() common.Executor {
return cr.tryReadID("-g", func(id int) { cr.GID = id }) return cr.tryReadID("-g", func(id int) { cr.GID = id })
} }
func (cr *containerReference) waitForCommand(ctx context.Context, isTerminal bool, resp types.HijackedResponse, idResp types.IDResponse, user string, workdir string) error { func (cr *containerReference) waitForCommand(ctx context.Context, isTerminal bool, resp types.HijackedResponse, _ types.IDResponse, _ string, _ string) error {
logger := common.Logger(ctx) logger := common.Logger(ctx)
cmdResponse := make(chan error) cmdResponse := make(chan error)
@@ -883,13 +884,27 @@ func (cr *containerReference) wait() common.Executor {
} }
} }
// For Gitea
// sanitizeConfig remove the invalid configurations from `config` and `hostConfig`
func (cr *containerReference) sanitizeConfig(ctx context.Context, config *container.Config, hostConfig *container.HostConfig) (*container.Config, *container.HostConfig) { func (cr *containerReference) sanitizeConfig(ctx context.Context, config *container.Config, hostConfig *container.HostConfig) (*container.Config, *container.HostConfig) {
logger := common.Logger(ctx) logger := common.Logger(ctx)
if len(cr.input.ValidVolumes) > 0 { if len(cr.input.ValidVolumes) > 0 {
vv := make(map[string]struct{}, len(cr.input.ValidVolumes)) globs := make([]glob.Glob, 0, len(cr.input.ValidVolumes))
for _, volume := range cr.input.ValidVolumes { for _, v := range cr.input.ValidVolumes {
vv[volume] = struct{}{} if g, err := glob.Compile(v); err != nil {
logger.Errorf("create glob from %s error: %v", v, err)
} else {
globs = append(globs, g)
}
}
isValid := func(v string) bool {
for _, g := range globs {
if g.Match(v) {
return true
}
}
return false
} }
// sanitize binds // sanitize binds
sanitizedBinds := make([]string, 0, len(hostConfig.Binds)) sanitizedBinds := make([]string, 0, len(hostConfig.Binds))
@@ -904,23 +919,26 @@ func (cr *containerReference) sanitizeConfig(ctx context.Context, config *contai
sanitizedBinds = append(sanitizedBinds, bind) sanitizedBinds = append(sanitizedBinds, bind)
continue continue
} }
if _, ok := vv[parsed.Source]; ok { if isValid(parsed.Source) {
sanitizedBinds = append(sanitizedBinds, bind) sanitizedBinds = append(sanitizedBinds, bind)
} else { } else {
logger.Warnf("[%s] is not a valid volume, will be ignored", bind) logger.Warnf("[%s] is not a valid volume, will be ignored", parsed.Source)
} }
} }
hostConfig.Binds = sanitizedBinds hostConfig.Binds = sanitizedBinds
// sanitize mounts // sanitize mounts
sanitizedMounts := make([]mount.Mount, 0, len(hostConfig.Mounts)) sanitizedMounts := make([]mount.Mount, 0, len(hostConfig.Mounts))
for _, mt := range hostConfig.Mounts { for _, mt := range hostConfig.Mounts {
if _, ok := vv[mt.Source]; ok { if isValid(mt.Source) {
sanitizedMounts = append(sanitizedMounts, mt) sanitizedMounts = append(sanitizedMounts, mt)
} else { } else {
logger.Warnf("[%s] is not a valid volume, will be ignored", mt.Source) logger.Warnf("[%s] is not a valid volume, will be ignored", mt.Source)
} }
} }
hostConfig.Mounts = sanitizedMounts hostConfig.Mounts = sanitizedMounts
} else {
hostConfig.Binds = []string{}
hostConfig.Mounts = []mount.Mount{}
} }
return config, hostConfig return config, hostConfig

View File

@@ -9,8 +9,12 @@ import (
"testing" "testing"
"time" "time"
"github.com/nektos/act/pkg/common"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/client" "github.com/docker/docker/client"
"github.com/sirupsen/logrus/hooks/test"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock" "github.com/stretchr/testify/mock"
) )
@@ -78,7 +82,7 @@ type endlessReader struct {
io.Reader io.Reader
} }
func (r endlessReader) Read(p []byte) (n int, err error) { func (r endlessReader) Read(_ []byte) (n int, err error) {
return 1, nil return 1, nil
} }
@@ -166,3 +170,76 @@ func TestDockerExecFailure(t *testing.T) {
// Type assert containerReference implements ExecutionsEnvironment // Type assert containerReference implements ExecutionsEnvironment
var _ ExecutionsEnvironment = &containerReference{} var _ ExecutionsEnvironment = &containerReference{}
func TestCheckVolumes(t *testing.T) {
testCases := []struct {
desc string
validVolumes []string
binds []string
expectedBinds []string
}{
{
desc: "match all volumes",
validVolumes: []string{"**"},
binds: []string{
"shared_volume:/shared_volume",
"/home/test/data:/test_data",
"/etc/conf.d/base.json:/config/base.json",
"sql_data:/sql_data",
"/secrets/keys:/keys",
},
expectedBinds: []string{
"shared_volume:/shared_volume",
"/home/test/data:/test_data",
"/etc/conf.d/base.json:/config/base.json",
"sql_data:/sql_data",
"/secrets/keys:/keys",
},
},
{
desc: "no volumes can be matched",
validVolumes: []string{},
binds: []string{
"shared_volume:/shared_volume",
"/home/test/data:/test_data",
"/etc/conf.d/base.json:/config/base.json",
"sql_data:/sql_data",
"/secrets/keys:/keys",
},
expectedBinds: []string{},
},
{
desc: "only allowed volumes can be matched",
validVolumes: []string{
"shared_volume",
"/home/test/data",
"/etc/conf.d/*.json",
},
binds: []string{
"shared_volume:/shared_volume",
"/home/test/data:/test_data",
"/etc/conf.d/base.json:/config/base.json",
"sql_data:/sql_data",
"/secrets/keys:/keys",
},
expectedBinds: []string{
"shared_volume:/shared_volume",
"/home/test/data:/test_data",
"/etc/conf.d/base.json:/config/base.json",
},
},
}
for _, tc := range testCases {
t.Run(tc.desc, func(t *testing.T) {
logger, _ := test.NewNullLogger()
ctx := common.WithLogger(context.Background(), logger)
cr := &containerReference{
input: &NewContainerInput{
ValidVolumes: tc.validVolumes,
},
}
_, hostConf := cr.sanitizeConfig(ctx, &container.Config{}, &container.HostConfig{Binds: tc.binds})
assert.Equal(t, tc.expectedBinds, hostConf.Binds)
})
}
}

View File

@@ -6,10 +6,11 @@ import (
"context" "context"
"github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/volume"
"github.com/nektos/act/pkg/common" "github.com/nektos/act/pkg/common"
) )
func NewDockerVolumeRemoveExecutor(volume string, force bool) common.Executor { func NewDockerVolumeRemoveExecutor(volumeName string, force bool) common.Executor {
return func(ctx context.Context) error { return func(ctx context.Context) error {
cli, err := GetDockerClient(ctx) cli, err := GetDockerClient(ctx)
if err != nil { if err != nil {
@@ -17,14 +18,14 @@ func NewDockerVolumeRemoveExecutor(volume string, force bool) common.Executor {
} }
defer cli.Close() defer cli.Close()
list, err := cli.VolumeList(ctx, filters.NewArgs()) list, err := cli.VolumeList(ctx, volume.ListOptions{Filters: filters.NewArgs()})
if err != nil { if err != nil {
return err return err
} }
for _, vol := range list.Volumes { for _, vol := range list.Volumes {
if vol.Name == volume { if vol.Name == volumeName {
return removeExecutor(volume, force)(ctx) return removeExecutor(volumeName, force)(ctx)
} }
} }

View File

@@ -34,7 +34,7 @@ type HostEnvironment struct {
StdOut io.Writer StdOut io.Writer
} }
func (e *HostEnvironment) Create(capAdd []string, capDrop []string) common.Executor { func (e *HostEnvironment) Create(_ []string, _ []string) common.Executor {
return func(ctx context.Context) error { return func(ctx context.Context) error {
return nil return nil
} }
@@ -146,13 +146,13 @@ func (e *HostEnvironment) GetContainerArchive(ctx context.Context, srcPath strin
return io.NopCloser(buf), nil return io.NopCloser(buf), nil
} }
func (e *HostEnvironment) Pull(forcePull bool) common.Executor { func (e *HostEnvironment) Pull(_ bool) common.Executor {
return func(ctx context.Context) error { return func(ctx context.Context) error {
return nil return nil
} }
} }
func (e *HostEnvironment) Start(attach bool) common.Executor { func (e *HostEnvironment) Start(_ bool) common.Executor {
return func(ctx context.Context) error { return func(ctx context.Context) error {
return nil return nil
} }
@@ -246,7 +246,7 @@ func copyPtyOutput(writer io.Writer, ppty io.Reader, finishLog context.CancelFun
} }
} }
func (e *HostEnvironment) UpdateFromImageEnv(env *map[string]string) common.Executor { func (e *HostEnvironment) UpdateFromImageEnv(_ *map[string]string) common.Executor {
return func(ctx context.Context) error { return func(ctx context.Context) error {
return nil return nil
} }
@@ -260,7 +260,7 @@ func getEnvListFromMap(env map[string]string) []string {
return envList return envList
} }
func (e *HostEnvironment) exec(ctx context.Context, command []string, cmdline string, env map[string]string, user, workdir string) error { func (e *HostEnvironment) exec(ctx context.Context, command []string, cmdline string, env map[string]string, _, workdir string) error {
envList := getEnvListFromMap(env) envList := getEnvListFromMap(env)
var wd string var wd string
if workdir != "" { if workdir != "" {
@@ -368,7 +368,11 @@ func (e *HostEnvironment) ToContainerPath(path string) string {
} }
func (e *HostEnvironment) GetActPath() string { func (e *HostEnvironment) GetActPath() string {
return e.ActPath actPath := e.ActPath
if runtime.GOOS == "windows" {
actPath = strings.ReplaceAll(actPath, "\\", "/")
}
return actPath
} }
func (*HostEnvironment) GetPathVariableName() string { func (*HostEnvironment) GetPathVariableName() string {
@@ -389,11 +393,13 @@ func (*HostEnvironment) JoinPathVariable(paths ...string) string {
return strings.Join(paths, string(filepath.ListSeparator)) return strings.Join(paths, string(filepath.ListSeparator))
} }
// Reference for Arch values for runner.arch
// https://docs.github.com/en/actions/learn-github-actions/contexts#runner-context
func goArchToActionArch(arch string) string { func goArchToActionArch(arch string) string {
archMapper := map[string]string{ archMapper := map[string]string{
"x86_64": "X64", "x86_64": "X64",
"386": "x86", "386": "X86",
"aarch64": "arm64", "aarch64": "ARM64",
} }
if arch, ok := archMapper[arch]; ok { if arch, ok := archMapper[arch]; ok {
return arch return arch
@@ -411,7 +417,7 @@ func goOsToActionOs(os string) string {
return os return os
} }
func (e *HostEnvironment) GetRunnerContext(ctx context.Context) map[string]interface{} { func (e *HostEnvironment) GetRunnerContext(_ context.Context) map[string]interface{} {
return map[string]interface{}{ return map[string]interface{}{
"os": goOsToActionOs(runtime.GOOS), "os": goOsToActionOs(runtime.GOOS),
"arch": goArchToActionArch(runtime.GOARCH), "arch": goArchToActionArch(runtime.GOARCH),
@@ -420,7 +426,7 @@ func (e *HostEnvironment) GetRunnerContext(ctx context.Context) map[string]inter
} }
} }
func (e *HostEnvironment) ReplaceLogWriter(stdout io.Writer, stderr io.Writer) (io.Writer, io.Writer) { func (e *HostEnvironment) ReplaceLogWriter(stdout io.Writer, _ io.Writer) (io.Writer, io.Writer) {
org := e.StdOut org := e.StdOut
e.StdOut = stdout e.StdOut = stdout
return org, org return org, org

View File

@@ -9,7 +9,7 @@ import (
"github.com/creack/pty" "github.com/creack/pty"
) )
func getSysProcAttr(cmdLine string, tty bool) *syscall.SysProcAttr { func getSysProcAttr(_ string, tty bool) *syscall.SysProcAttr {
if tty { if tty {
return &syscall.SysProcAttr{ return &syscall.SysProcAttr{
Setsid: true, Setsid: true,

View File

@@ -149,7 +149,7 @@ func (impl *interperterImpl) evaluateNode(exprNode actionlint.ExprNode) (interfa
} }
} }
// nolint:gocyclo //nolint:gocyclo
func (impl *interperterImpl) evaluateVariable(variableNode *actionlint.VariableNode) (interface{}, error) { func (impl *interperterImpl) evaluateVariable(variableNode *actionlint.VariableNode) (interface{}, error) {
switch strings.ToLower(variableNode.Name) { switch strings.ToLower(variableNode.Name) {
case "github": case "github":

View File

@@ -441,6 +441,7 @@ func (j *Job) GetMatrixes() ([]map[string]interface{}, error) {
} }
} else { } else {
matrixes = append(matrixes, make(map[string]interface{})) matrixes = append(matrixes, make(map[string]interface{}))
log.Debugf("Empty Strategy, matrixes=%v", matrixes)
} }
return matrixes, nil return matrixes, nil
} }
@@ -468,14 +469,17 @@ func commonKeysMatch2(a map[string]interface{}, b map[string]interface{}, m map[
type JobType int type JobType int
const ( const (
// StepTypeRun is all steps that have a `run` attribute // JobTypeDefault is all jobs that have a `run` attribute
JobTypeDefault JobType = iota JobTypeDefault JobType = iota
// StepTypeReusableWorkflowLocal is all steps that have a `uses` that is a local workflow in the .github/workflows directory // JobTypeReusableWorkflowLocal is all jobs that have a `uses` that is a local workflow in the .github/workflows directory
JobTypeReusableWorkflowLocal JobTypeReusableWorkflowLocal
// JobTypeReusableWorkflowRemote is all steps that have a `uses` that references a workflow file in a github repo // JobTypeReusableWorkflowRemote is all jobs that have a `uses` that references a workflow file in a github repo
JobTypeReusableWorkflowRemote JobTypeReusableWorkflowRemote
// JobTypeInvalid represents a job which is not configured correctly
JobTypeInvalid
) )
func (j JobType) String() string { func (j JobType) String() string {
@@ -491,17 +495,28 @@ func (j JobType) String() string {
} }
// Type returns the type of the job // Type returns the type of the job
func (j *Job) Type() JobType { func (j *Job) Type() (JobType, error) {
if strings.HasPrefix(j.Uses, "./.github/workflows") && (strings.HasSuffix(j.Uses, ".yml") || strings.HasSuffix(j.Uses, ".yaml")) { isReusable := j.Uses != ""
return JobTypeReusableWorkflowLocal
} else if strings.HasPrefix(j.Uses, "./.gitea/workflows") && (strings.HasSuffix(j.Uses, ".yml") || strings.HasSuffix(j.Uses, ".yaml")) { if isReusable {
return JobTypeReusableWorkflowLocal isYaml, _ := regexp.MatchString(`\.(ya?ml)(?:$|@)`, j.Uses)
} else if !strings.HasPrefix(j.Uses, "./") && strings.Contains(j.Uses, ".github/workflows") && (strings.Contains(j.Uses, ".yml@") || strings.Contains(j.Uses, ".yaml@")) {
return JobTypeReusableWorkflowRemote if isYaml {
} else if !strings.HasPrefix(j.Uses, "./") && strings.Contains(j.Uses, ".gitea/workflows") && (strings.Contains(j.Uses, ".yml@") || strings.Contains(j.Uses, ".yaml@")) { isLocalPath := strings.HasPrefix(j.Uses, "./")
return JobTypeReusableWorkflowRemote isRemotePath, _ := regexp.MatchString(`^[^.](.+?/){2,}.+\.ya?ml@`, j.Uses)
hasVersion, _ := regexp.MatchString(`\.ya?ml@`, j.Uses)
if isLocalPath {
return JobTypeReusableWorkflowLocal, nil
} else if isRemotePath && hasVersion {
return JobTypeReusableWorkflowRemote, nil
}
}
return JobTypeInvalid, fmt.Errorf("`uses` key references invalid workflow path '%s'. Must start with './' if it's a local workflow, or must start with '<org>/<repo>/' and include an '@' if it's a remote workflow", j.Uses)
} }
return JobTypeDefault
return JobTypeDefault, nil
} }
// ContainerSpec is the specification of the container to use for the job // ContainerSpec is the specification of the container to use for the job

View File

@@ -229,20 +229,81 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- run: echo - run: echo
remote-reusable-workflow: remote-reusable-workflow-yml:
runs-on: ubuntu-latest uses: remote/repo/some/path/to/workflow.yml@main
uses: remote/repo/.github/workflows/workflow.yml@main remote-reusable-workflow-yaml:
local-reusable-workflow: uses: remote/repo/some/path/to/workflow.yaml@main
runs-on: ubuntu-latest remote-reusable-workflow-custom-path:
uses: ./.github/workflows/workflow.yml uses: remote/repo/path/to/workflow.yml@main
local-reusable-workflow-yml:
uses: ./some/path/to/workflow.yml
local-reusable-workflow-yaml:
uses: ./some/path/to/workflow.yaml
` `
workflow, err := ReadWorkflow(strings.NewReader(yaml)) workflow, err := ReadWorkflow(strings.NewReader(yaml))
assert.NoError(t, err, "read workflow should succeed") assert.NoError(t, err, "read workflow should succeed")
assert.Len(t, workflow.Jobs, 3) assert.Len(t, workflow.Jobs, 6)
assert.Equal(t, workflow.Jobs["default-job"].Type(), JobTypeDefault)
assert.Equal(t, workflow.Jobs["remote-reusable-workflow"].Type(), JobTypeReusableWorkflowRemote) jobType, err := workflow.Jobs["default-job"].Type()
assert.Equal(t, workflow.Jobs["local-reusable-workflow"].Type(), JobTypeReusableWorkflowLocal) assert.Equal(t, nil, err)
assert.Equal(t, JobTypeDefault, jobType)
jobType, err = workflow.Jobs["remote-reusable-workflow-yml"].Type()
assert.Equal(t, nil, err)
assert.Equal(t, JobTypeReusableWorkflowRemote, jobType)
jobType, err = workflow.Jobs["remote-reusable-workflow-yaml"].Type()
assert.Equal(t, nil, err)
assert.Equal(t, JobTypeReusableWorkflowRemote, jobType)
jobType, err = workflow.Jobs["remote-reusable-workflow-custom-path"].Type()
assert.Equal(t, nil, err)
assert.Equal(t, JobTypeReusableWorkflowRemote, jobType)
jobType, err = workflow.Jobs["local-reusable-workflow-yml"].Type()
assert.Equal(t, nil, err)
assert.Equal(t, JobTypeReusableWorkflowLocal, jobType)
jobType, err = workflow.Jobs["local-reusable-workflow-yaml"].Type()
assert.Equal(t, nil, err)
assert.Equal(t, JobTypeReusableWorkflowLocal, jobType)
}
func TestReadWorkflow_JobTypes_InvalidPath(t *testing.T) {
yaml := `
name: invalid job definition
jobs:
remote-reusable-workflow-missing-version:
uses: remote/repo/some/path/to/workflow.yml
remote-reusable-workflow-bad-extension:
uses: remote/repo/some/path/to/workflow.json
local-reusable-workflow-bad-extension:
uses: ./some/path/to/workflow.json
local-reusable-workflow-bad-path:
uses: some/path/to/workflow.yaml
`
workflow, err := ReadWorkflow(strings.NewReader(yaml))
assert.NoError(t, err, "read workflow should succeed")
assert.Len(t, workflow.Jobs, 4)
jobType, err := workflow.Jobs["remote-reusable-workflow-missing-version"].Type()
assert.Equal(t, JobTypeInvalid, jobType)
assert.NotEqual(t, nil, err)
jobType, err = workflow.Jobs["remote-reusable-workflow-bad-extension"].Type()
assert.Equal(t, JobTypeInvalid, jobType)
assert.NotEqual(t, nil, err)
jobType, err = workflow.Jobs["local-reusable-workflow-bad-extension"].Type()
assert.Equal(t, JobTypeInvalid, jobType)
assert.NotEqual(t, nil, err)
jobType, err = workflow.Jobs["local-reusable-workflow-bad-path"].Type()
assert.Equal(t, JobTypeInvalid, jobType)
assert.NotEqual(t, nil, err)
} }
func TestReadWorkflow_StepsTypes(t *testing.T) { func TestReadWorkflow_StepsTypes(t *testing.T) {

View File

@@ -198,7 +198,7 @@ func runActionImpl(step actionStep, actionDir string, remoteAction *remoteAction
} }
} }
func setupActionEnv(ctx context.Context, step actionStep, remoteAction *remoteAction) error { func setupActionEnv(ctx context.Context, step actionStep, _ *remoteAction) error {
rc := step.getRunContext() rc := step.getRunContext()
// A few fields in the environment (e.g. GITHUB_ACTION_REPOSITORY) // A few fields in the environment (e.g. GITHUB_ACTION_REPOSITORY)
@@ -377,24 +377,25 @@ func newStepContainer(ctx context.Context, step step, image string, cmd []string
networkMode = "default" networkMode = "default"
} }
stepContainer := container.NewContainer(&container.NewContainerInput{ stepContainer := container.NewContainer(&container.NewContainerInput{
Cmd: cmd, Cmd: cmd,
Entrypoint: entrypoint, Entrypoint: entrypoint,
WorkingDir: rc.JobContainer.ToContainerPath(rc.Config.Workdir), WorkingDir: rc.JobContainer.ToContainerPath(rc.Config.Workdir),
Image: image, Image: image,
Username: rc.Config.Secrets["DOCKER_USERNAME"], Username: rc.Config.Secrets["DOCKER_USERNAME"],
Password: rc.Config.Secrets["DOCKER_PASSWORD"], Password: rc.Config.Secrets["DOCKER_PASSWORD"],
Name: createSimpleContainerName(rc.jobContainerName(), "STEP-"+stepModel.ID), Name: createSimpleContainerName(rc.jobContainerName(), "STEP-"+stepModel.ID),
Env: envList, Env: envList,
Mounts: mounts, Mounts: mounts,
NetworkMode: networkMode, NetworkMode: networkMode,
Binds: binds, Binds: binds,
Stdout: logWriter, Stdout: logWriter,
Stderr: logWriter, Stderr: logWriter,
Privileged: rc.Config.Privileged, Privileged: rc.Config.Privileged,
UsernsMode: rc.Config.UsernsMode, UsernsMode: rc.Config.UsernsMode,
Platform: rc.Config.ContainerArchitecture, Platform: rc.Config.ContainerArchitecture,
Options: rc.Config.ContainerOptions, Options: rc.Config.ContainerOptions,
AutoRemove: rc.Config.AutoRemove, AutoRemove: rc.Config.AutoRemove,
ValidVolumes: rc.Config.ValidVolumes,
}) })
return stepContainer return stepContainer
} }

View File

@@ -172,7 +172,7 @@ func unescapeKvPairs(kvPairs map[string]string) map[string]string {
return kvPairs return kvPairs
} }
func (rc *RunContext) saveState(ctx context.Context, kvPairs map[string]string, arg string) { func (rc *RunContext) saveState(_ context.Context, kvPairs map[string]string, arg string) {
stepID := rc.CurrentStep stepID := rc.CurrentStep
if stepID != "" { if stepID != "" {
if rc.IntraActionState == nil { if rc.IntraActionState == nil {

View File

@@ -160,67 +160,117 @@ func (ee expressionEvaluator) evaluate(ctx context.Context, in string, defaultSt
return evaluated, err return evaluated, err
} }
func (ee expressionEvaluator) evaluateScalarYamlNode(ctx context.Context, node *yaml.Node) error { func (ee expressionEvaluator) evaluateScalarYamlNode(ctx context.Context, node *yaml.Node) (*yaml.Node, error) {
var in string var in string
if err := node.Decode(&in); err != nil { if err := node.Decode(&in); err != nil {
return err return nil, err
} }
if !strings.Contains(in, "${{") || !strings.Contains(in, "}}") { if !strings.Contains(in, "${{") || !strings.Contains(in, "}}") {
return nil return nil, nil
} }
expr, _ := rewriteSubExpression(ctx, in, false) expr, _ := rewriteSubExpression(ctx, in, false)
res, err := ee.evaluate(ctx, expr, exprparser.DefaultStatusCheckNone) res, err := ee.evaluate(ctx, expr, exprparser.DefaultStatusCheckNone)
if err != nil { if err != nil {
return err return nil, err
} }
return node.Encode(res) ret := &yaml.Node{}
if err := ret.Encode(res); err != nil {
return nil, err
}
return ret, err
} }
func (ee expressionEvaluator) evaluateMappingYamlNode(ctx context.Context, node *yaml.Node) error { func (ee expressionEvaluator) evaluateMappingYamlNode(ctx context.Context, node *yaml.Node) (*yaml.Node, error) {
var ret *yaml.Node
// GitHub has this undocumented feature to merge maps, called insert directive // GitHub has this undocumented feature to merge maps, called insert directive
insertDirective := regexp.MustCompile(`\${{\s*insert\s*}}`) insertDirective := regexp.MustCompile(`\${{\s*insert\s*}}`)
for i := 0; i < len(node.Content)/2; { for i := 0; i < len(node.Content)/2; i++ {
changed := func() error {
if ret == nil {
ret = &yaml.Node{}
if err := ret.Encode(node); err != nil {
return err
}
ret.Content = ret.Content[:i*2]
}
return nil
}
k := node.Content[i*2] k := node.Content[i*2]
v := node.Content[i*2+1] v := node.Content[i*2+1]
if err := ee.EvaluateYamlNode(ctx, v); err != nil { ev, err := ee.evaluateYamlNodeInternal(ctx, v)
return err if err != nil {
return nil, err
}
if ev != nil {
if err := changed(); err != nil {
return nil, err
}
} else {
ev = v
} }
var sk string var sk string
// Merge the nested map of the insert directive // Merge the nested map of the insert directive
if k.Decode(&sk) == nil && insertDirective.MatchString(sk) { if k.Decode(&sk) == nil && insertDirective.MatchString(sk) {
node.Content = append(append(node.Content[:i*2], v.Content...), node.Content[(i+1)*2:]...) if ev.Kind != yaml.MappingNode {
i += len(v.Content) / 2 return nil, fmt.Errorf("failed to insert node %v into mapping %v unexpected type %v expected MappingNode", ev, node, ev.Kind)
} else { }
if err := ee.EvaluateYamlNode(ctx, k); err != nil { if err := changed(); err != nil {
return err return nil, err
}
ret.Content = append(ret.Content, ev.Content...)
} else {
ek, err := ee.evaluateYamlNodeInternal(ctx, k)
if err != nil {
return nil, err
}
if ek != nil {
if err := changed(); err != nil {
return nil, err
}
} else {
ek = k
}
if ret != nil {
ret.Content = append(ret.Content, ek, ev)
} }
i++
} }
} }
return nil return ret, nil
} }
func (ee expressionEvaluator) evaluateSequenceYamlNode(ctx context.Context, node *yaml.Node) error { func (ee expressionEvaluator) evaluateSequenceYamlNode(ctx context.Context, node *yaml.Node) (*yaml.Node, error) {
for i := 0; i < len(node.Content); { var ret *yaml.Node
for i := 0; i < len(node.Content); i++ {
v := node.Content[i] v := node.Content[i]
// Preserve nested sequences // Preserve nested sequences
wasseq := v.Kind == yaml.SequenceNode wasseq := v.Kind == yaml.SequenceNode
if err := ee.EvaluateYamlNode(ctx, v); err != nil { ev, err := ee.evaluateYamlNodeInternal(ctx, v)
return err if err != nil {
return nil, err
} }
// GitHub has this undocumented feature to merge sequences / arrays if ev != nil {
// We have a nested sequence via evaluation, merge the arrays if ret == nil {
if v.Kind == yaml.SequenceNode && !wasseq { ret = &yaml.Node{}
node.Content = append(append(node.Content[:i], v.Content...), node.Content[i+1:]...) if err := ret.Encode(node); err != nil {
i += len(v.Content) return nil, err
} else { }
i++ ret.Content = ret.Content[:i]
}
// GitHub has this undocumented feature to merge sequences / arrays
// We have a nested sequence via evaluation, merge the arrays
if ev.Kind == yaml.SequenceNode && !wasseq {
ret.Content = append(ret.Content, ev.Content...)
} else {
ret.Content = append(ret.Content, ev)
}
} else if ret != nil {
ret.Content = append(ret.Content, v)
} }
} }
return nil return ret, nil
} }
func (ee expressionEvaluator) EvaluateYamlNode(ctx context.Context, node *yaml.Node) error { func (ee expressionEvaluator) evaluateYamlNodeInternal(ctx context.Context, node *yaml.Node) (*yaml.Node, error) {
switch node.Kind { switch node.Kind {
case yaml.ScalarNode: case yaml.ScalarNode:
return ee.evaluateScalarYamlNode(ctx, node) return ee.evaluateScalarYamlNode(ctx, node)
@@ -229,10 +279,21 @@ func (ee expressionEvaluator) EvaluateYamlNode(ctx context.Context, node *yaml.N
case yaml.SequenceNode: case yaml.SequenceNode:
return ee.evaluateSequenceYamlNode(ctx, node) return ee.evaluateSequenceYamlNode(ctx, node)
default: default:
return nil return nil, nil
} }
} }
func (ee expressionEvaluator) EvaluateYamlNode(ctx context.Context, node *yaml.Node) error {
ret, err := ee.evaluateYamlNodeInternal(ctx, node)
if err != nil {
return err
}
if ret != nil {
return ret.Decode(node)
}
return nil
}
func (ee expressionEvaluator) Interpolate(ctx context.Context, in string) string { func (ee expressionEvaluator) Interpolate(ctx context.Context, in string) string {
if !strings.Contains(in, "${{") || !strings.Contains(in, "}}") { if !strings.Contains(in, "${{") || !strings.Contains(in, "}}") {
return in return in
@@ -336,6 +397,7 @@ func rewriteSubExpression(ctx context.Context, in string, forceFormat bool) (str
return out, nil return out, nil
} }
//nolint:gocyclo
func getEvaluatorInputs(ctx context.Context, rc *RunContext, step step, ghc *model.GithubContext) map[string]interface{} { func getEvaluatorInputs(ctx context.Context, rc *RunContext, step step, ghc *model.GithubContext) map[string]interface{} {
inputs := map[string]interface{}{} inputs := map[string]interface{}{}
@@ -371,6 +433,22 @@ func getEvaluatorInputs(ctx context.Context, rc *RunContext, step step, ghc *mod
} }
} }
if ghc.EventName == "workflow_call" {
config := rc.Run.Workflow.WorkflowCallConfig()
if config != nil && config.Inputs != nil {
for k, v := range config.Inputs {
value := nestedMapLookup(ghc.Event, "inputs", k)
if value == nil {
value = v.Default
}
if v.Type == "boolean" {
inputs[k] = value == "true"
} else {
inputs[k] = value
}
}
}
}
return inputs return inputs
} }
@@ -425,6 +503,6 @@ func getWorkflowSecrets(ctx context.Context, rc *RunContext) map[string]string {
return rc.Config.Secrets return rc.Config.Secrets
} }
func getWorkflowVars(ctx context.Context, rc *RunContext) map[string]string { func getWorkflowVars(_ context.Context, rc *RunContext) map[string]string {
return rc.Config.Vars return rc.Config.Vars
} }

View File

@@ -6,6 +6,7 @@ import (
"time" "time"
"github.com/nektos/act/pkg/common" "github.com/nektos/act/pkg/common"
"github.com/nektos/act/pkg/container"
"github.com/nektos/act/pkg/model" "github.com/nektos/act/pkg/model"
) )
@@ -125,12 +126,13 @@ func newJobExecutor(info jobInfo, sf stepFactory, rc *RunContext) common.Executo
if err = info.stopContainer()(ctx); err != nil { if err = info.stopContainer()(ctx); err != nil {
logger.Errorf("Error while stop job container: %v", err) logger.Errorf("Error while stop job container: %v", err)
} }
if rc.Config.ContainerNetworkMode == "" { if !rc.IsHostEnv(ctx) && rc.Config.ContainerNetworkMode == "" {
// clean network in docker mode only
// if the value of `ContainerNetworkMode` is empty string, // if the value of `ContainerNetworkMode` is empty string,
// it means that the network to which containers are connecting is created by `act_runner`, // it means that the network to which containers are connecting is created by `act_runner`,
// so, we should remove the network at last. // so, we should remove the network at last.
logger.Infof("Cleaning up network for job %s, and network name is: %s", rc.JobName, rc.networkName()) logger.Infof("Cleaning up network for job %s, and network name is: %s", rc.JobName, rc.networkName())
if err := rc.removeNetwork(rc.networkName())(ctx); err != nil { if err := container.NewDockerNetworkRemoveExecutor(rc.networkName())(ctx); err != nil {
logger.Errorf("Error while cleaning network: %v", err) logger.Errorf("Error while cleaning network: %v", err)
} }
} }
@@ -146,7 +148,7 @@ func newJobExecutor(info jobInfo, sf stepFactory, rc *RunContext) common.Executo
pipeline = append(pipeline, steps...) pipeline = append(pipeline, steps...)
return common.NewPipelineExecutor(info.startContainer(), common.NewPipelineExecutor(pipeline...). return common.NewPipelineExecutor(info.startContainer(), common.NewPipelineExecutor(pipeline...).
Finally(func(ctx context.Context) error { Finally(func(ctx context.Context) error { //nolint:contextcheck
var cancel context.CancelFunc var cancel context.CancelFunc
if ctx.Err() == context.Canceled { if ctx.Err() == context.Canceled {
// in case of an aborted run, we still should execute the // in case of an aborted run, we still should execute the

View File

@@ -82,7 +82,7 @@ type jobContainerMock struct {
container.LinuxContainerEnvironmentExtensions container.LinuxContainerEnvironmentExtensions
} }
func (jcm *jobContainerMock) ReplaceLogWriter(stdout, stderr io.Writer) (io.Writer, io.Writer) { func (jcm *jobContainerMock) ReplaceLogWriter(_, _ io.Writer) (io.Writer, io.Writer) {
return nil, nil return nil, nil
} }

View File

@@ -85,7 +85,8 @@ func WithJobLogger(ctx context.Context, jobID string, jobName string, config *Co
defer mux.Unlock() defer mux.Unlock()
nextColor++ nextColor++
formatter = &jobLogFormatter{ formatter = &jobLogFormatter{
color: colors[nextColor%len(colors)], color: colors[nextColor%len(colors)],
logPrefixJobID: config.LogPrefixJobID,
} }
} }
@@ -188,7 +189,8 @@ func (f *maskedFormatter) Format(entry *logrus.Entry) ([]byte, error) {
} }
type jobLogFormatter struct { type jobLogFormatter struct {
color int color int
logPrefixJobID bool
} }
func (f *jobLogFormatter) Format(entry *logrus.Entry) ([]byte, error) { func (f *jobLogFormatter) Format(entry *logrus.Entry) ([]byte, error) {
@@ -206,7 +208,14 @@ func (f *jobLogFormatter) Format(entry *logrus.Entry) ([]byte, error) {
func (f *jobLogFormatter) printColored(b *bytes.Buffer, entry *logrus.Entry) { func (f *jobLogFormatter) printColored(b *bytes.Buffer, entry *logrus.Entry) {
entry.Message = strings.TrimSuffix(entry.Message, "\n") entry.Message = strings.TrimSuffix(entry.Message, "\n")
jobName := entry.Data["job"]
var job any
if f.logPrefixJobID {
job = entry.Data["jobID"]
} else {
job = entry.Data["job"]
}
debugFlag := "" debugFlag := ""
if entry.Level == logrus.DebugLevel { if entry.Level == logrus.DebugLevel {
debugFlag = "[DEBUG] " debugFlag = "[DEBUG] "
@@ -215,26 +224,33 @@ func (f *jobLogFormatter) printColored(b *bytes.Buffer, entry *logrus.Entry) {
if entry.Data["raw_output"] == true { if entry.Data["raw_output"] == true {
fmt.Fprintf(b, "\x1b[%dm|\x1b[0m %s", f.color, entry.Message) fmt.Fprintf(b, "\x1b[%dm|\x1b[0m %s", f.color, entry.Message)
} else if entry.Data["dryrun"] == true { } else if entry.Data["dryrun"] == true {
fmt.Fprintf(b, "\x1b[1m\x1b[%dm\x1b[7m*DRYRUN*\x1b[0m \x1b[%dm[%s] \x1b[0m%s%s", gray, f.color, jobName, debugFlag, entry.Message) fmt.Fprintf(b, "\x1b[1m\x1b[%dm\x1b[7m*DRYRUN*\x1b[0m \x1b[%dm[%s] \x1b[0m%s%s", gray, f.color, job, debugFlag, entry.Message)
} else { } else {
fmt.Fprintf(b, "\x1b[%dm[%s] \x1b[0m%s%s", f.color, jobName, debugFlag, entry.Message) fmt.Fprintf(b, "\x1b[%dm[%s] \x1b[0m%s%s", f.color, job, debugFlag, entry.Message)
} }
} }
func (f *jobLogFormatter) print(b *bytes.Buffer, entry *logrus.Entry) { func (f *jobLogFormatter) print(b *bytes.Buffer, entry *logrus.Entry) {
entry.Message = strings.TrimSuffix(entry.Message, "\n") entry.Message = strings.TrimSuffix(entry.Message, "\n")
jobName := entry.Data["job"]
var job any
if f.logPrefixJobID {
job = entry.Data["jobID"]
} else {
job = entry.Data["job"]
}
debugFlag := "" debugFlag := ""
if entry.Level == logrus.DebugLevel { if entry.Level == logrus.DebugLevel {
debugFlag = "[DEBUG] " debugFlag = "[DEBUG] "
} }
if entry.Data["raw_output"] == true { if entry.Data["raw_output"] == true {
fmt.Fprintf(b, "[%s] | %s", jobName, entry.Message) fmt.Fprintf(b, "[%s] | %s", job, entry.Message)
} else if entry.Data["dryrun"] == true { } else if entry.Data["dryrun"] == true {
fmt.Fprintf(b, "*DRYRUN* [%s] %s%s", jobName, debugFlag, entry.Message) fmt.Fprintf(b, "*DRYRUN* [%s] %s%s", job, debugFlag, entry.Message)
} else { } else {
fmt.Fprintf(b, "[%s] %s%s", jobName, debugFlag, entry.Message) fmt.Fprintf(b, "[%s] %s%s", job, debugFlag, entry.Message)
} }
} }

View File

@@ -34,11 +34,10 @@ func newLocalReusableWorkflowExecutor(rc *RunContext) common.Executor {
// uses string format is {owner}/{repo}/.{git_platform}/workflows/{filename}@{ref} // uses string format is {owner}/{repo}/.{git_platform}/workflows/{filename}@{ref}
uses := fmt.Sprintf("%s/%s@%s", rc.Config.PresetGitHubContext.Repository, trimmedUses, rc.Config.PresetGitHubContext.Sha) uses := fmt.Sprintf("%s/%s@%s", rc.Config.PresetGitHubContext.Repository, trimmedUses, rc.Config.PresetGitHubContext.Sha)
remoteReusableWorkflow := newRemoteReusableWorkflowWithPlat(uses) remoteReusableWorkflow := newRemoteReusableWorkflowWithPlat(rc.Config.GitHubInstance, uses)
if remoteReusableWorkflow == nil { if remoteReusableWorkflow == nil {
return common.NewErrorExecutor(fmt.Errorf("expected format {owner}/{repo}/.{git_platform}/workflows/{filename}@{ref}. Actual '%s' Input string was not in a correct format", uses)) return common.NewErrorExecutor(fmt.Errorf("expected format {owner}/{repo}/.{git_platform}/workflows/{filename}@{ref}. Actual '%s' Input string was not in a correct format", uses))
} }
remoteReusableWorkflow.URL = rc.Config.GitHubInstance
workflowDir := fmt.Sprintf("%s/%s", rc.ActionCacheDir(), safeFilename(uses)) workflowDir := fmt.Sprintf("%s/%s", rc.ActionCacheDir(), safeFilename(uses))
@@ -54,13 +53,16 @@ func newLocalReusableWorkflowExecutor(rc *RunContext) common.Executor {
func newRemoteReusableWorkflowExecutor(rc *RunContext) common.Executor { func newRemoteReusableWorkflowExecutor(rc *RunContext) common.Executor {
uses := rc.Run.Job().Uses uses := rc.Run.Job().Uses
remoteReusableWorkflow := newRemoteReusableWorkflowWithPlat(uses) remoteReusableWorkflow := newRemoteReusableWorkflowWithPlat(rc.Config.GitHubInstance, uses)
if remoteReusableWorkflow == nil { if remoteReusableWorkflow == nil {
return common.NewErrorExecutor(fmt.Errorf("expected format {owner}/{repo}/.{git_platform}/workflows/{filename}@{ref}. Actual '%s' Input string was not in a correct format", uses)) return common.NewErrorExecutor(fmt.Errorf("expected format {owner}/{repo}/.{git_platform}/workflows/{filename}@{ref}. Actual '%s' Input string was not in a correct format", uses))
} }
remoteReusableWorkflow.URL = rc.Config.GitHubInstance
workflowDir := fmt.Sprintf("%s/%s", rc.ActionCacheDir(), safeFilename(uses)) // uses with safe filename makes the target directory look something like this {owner}-{repo}-.github-workflows-{filename}@{ref}
// instead we will just use {owner}-{repo}@{ref} as our target directory. This should also improve performance when we are using
// multiple reusable workflows from the same repository and ref since for each workflow we won't have to clone it again
filename := fmt.Sprintf("%s/%s@%s", remoteReusableWorkflow.Org, remoteReusableWorkflow.Repo, remoteReusableWorkflow.Ref)
workflowDir := fmt.Sprintf("%s/%s", rc.ActionCacheDir(), safeFilename(filename))
// FIXME: if the reusable workflow is from a private repository, we need to provide a token to access the repository. // FIXME: if the reusable workflow is from a private repository, we need to provide a token to access the repository.
token := "" token := ""
@@ -91,12 +93,18 @@ func cloneIfRequired(rc *RunContext, remoteReusableWorkflow remoteReusableWorkfl
notExists := errors.Is(err, fs.ErrNotExist) notExists := errors.Is(err, fs.ErrNotExist)
return notExists return notExists
}, },
git.NewGitCloneExecutor(git.NewGitCloneExecutorInput{ func(ctx context.Context) error {
URL: remoteReusableWorkflow.CloneURL(), // Do not change the remoteReusableWorkflow.URL, because:
Ref: remoteReusableWorkflow.Ref, // 1. Gitea doesn't support specifying GithubContext.ServerURL by the GITHUB_SERVER_URL env
Dir: targetDirectory, // 2. Gitea has already full URL with rc.Config.GitHubInstance when calling newRemoteReusableWorkflowWithPlat
Token: token, // remoteReusableWorkflow.URL = rc.getGithubContext(ctx).ServerURL
}), return git.NewGitCloneExecutor(git.NewGitCloneExecutorInput{
URL: remoteReusableWorkflow.CloneURL(),
Ref: remoteReusableWorkflow.Ref,
Dir: targetDirectory,
Token: token,
})(ctx)
},
nil, nil,
) )
} }
@@ -156,7 +164,10 @@ func (r *remoteReusableWorkflow) FilePath() string {
return fmt.Sprintf("./.%s/workflows/%s", r.GitPlatform, r.Filename) return fmt.Sprintf("./.%s/workflows/%s", r.GitPlatform, r.Filename)
} }
func newRemoteReusableWorkflowWithPlat(uses string) *remoteReusableWorkflow { // For Gitea
// newRemoteReusableWorkflowWithPlat create a `remoteReusableWorkflow`
// workflows from `.gitea/workflows` and `.github/workflows` are supported
func newRemoteReusableWorkflowWithPlat(url, uses string) *remoteReusableWorkflow {
// GitHub docs: // GitHub docs:
// https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_iduses // https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_iduses
r := regexp.MustCompile(`^([^/]+)/([^/]+)/\.([^/]+)/workflows/([^@]+)@(.*)$`) r := regexp.MustCompile(`^([^/]+)/([^/]+)/\.([^/]+)/workflows/([^@]+)@(.*)$`)
@@ -170,6 +181,7 @@ func newRemoteReusableWorkflowWithPlat(uses string) *remoteReusableWorkflow {
GitPlatform: matches[3], GitPlatform: matches[3],
Filename: matches[4], Filename: matches[4],
Ref: matches[5], Ref: matches[5],
URL: url,
} }
} }
@@ -187,6 +199,6 @@ func newRemoteReusableWorkflow(uses string) *remoteReusableWorkflow {
Repo: matches[2], Repo: matches[2],
Filename: matches[3], Filename: matches[3],
Ref: matches[4], Ref: matches[4],
URL: "github.com", URL: "https://github.com",
} }
} }

View File

@@ -375,7 +375,7 @@ func (rc *RunContext) startJobContainer() common.Executor {
return common.NewPipelineExecutor( return common.NewPipelineExecutor(
rc.pullServicesImages(rc.Config.ForcePull), rc.pullServicesImages(rc.Config.ForcePull),
rc.JobContainer.Pull(rc.Config.ForcePull), rc.JobContainer.Pull(rc.Config.ForcePull),
rc.createNetwork(networkName).IfBool(rc.Config.ContainerNetworkMode == ""), // if the value of `ContainerNetworkMode` is empty string, then will create a new network for containers. container.NewDockerNetworkCreateExecutor(networkName).IfBool(!rc.IsHostEnv(ctx) && rc.Config.ContainerNetworkMode == ""), // if the value of `ContainerNetworkMode` is empty string, then will create a new network for containers.
rc.startServiceContainers(networkName), rc.startServiceContainers(networkName),
rc.JobContainer.Create(rc.Config.ContainerCapAdd, rc.Config.ContainerCapDrop), rc.JobContainer.Create(rc.Config.ContainerCapAdd, rc.Config.ContainerCapDrop),
rc.JobContainer.Start(false), rc.JobContainer.Start(false),
@@ -392,18 +392,6 @@ func (rc *RunContext) startJobContainer() common.Executor {
} }
} }
func (rc *RunContext) createNetwork(name string) common.Executor {
return func(ctx context.Context) error {
return container.NewDockerNetworkCreateExecutor(name)(ctx)
}
}
func (rc *RunContext) removeNetwork(name string) common.Executor {
return func(ctx context.Context) error {
return container.NewDockerNetworkRemoveExecutor(name)(ctx)
}
}
func (rc *RunContext) execJobContainer(cmd []string, env map[string]string, user, workdir string) common.Executor { func (rc *RunContext) execJobContainer(cmd []string, env map[string]string, user, workdir string) common.Executor {
return func(ctx context.Context) error { return func(ctx context.Context) error {
return rc.JobContainer.Exec(cmd, env, user, workdir)(ctx) return rc.JobContainer.Exec(cmd, env, user, workdir)(ctx)
@@ -512,6 +500,9 @@ func (rc *RunContext) stopServiceContainers() common.Executor {
// ActionCacheDir is for rc // ActionCacheDir is for rc
func (rc *RunContext) ActionCacheDir() string { func (rc *RunContext) ActionCacheDir() string {
if rc.Config.ActionCacheDir != "" {
return rc.Config.ActionCacheDir
}
var xdgCache string var xdgCache string
var ok bool var ok bool
if xdgCache, ok = os.LookupEnv("XDG_CACHE_HOME"); !ok || xdgCache == "" { if xdgCache, ok = os.LookupEnv("XDG_CACHE_HOME"); !ok || xdgCache == "" {
@@ -549,8 +540,9 @@ func (rc *RunContext) startContainer() common.Executor {
} }
func (rc *RunContext) IsHostEnv(ctx context.Context) bool { func (rc *RunContext) IsHostEnv(ctx context.Context) bool {
image := rc.platformImage(ctx) platform := rc.runsOnImage(ctx)
return strings.EqualFold(image, "-self-hosted") image := rc.containerImage(ctx)
return image == "" && strings.EqualFold(platform, "-self-hosted")
} }
func (rc *RunContext) stopContainer() common.Executor { func (rc *RunContext) stopContainer() common.Executor {
@@ -579,16 +571,19 @@ func (rc *RunContext) steps() []*model.Step {
} }
// Executor returns a pipeline executor for all the steps in the job // Executor returns a pipeline executor for all the steps in the job
func (rc *RunContext) Executor() common.Executor { func (rc *RunContext) Executor() (common.Executor, error) {
var executor common.Executor var executor common.Executor
var jobType, err = rc.Run.Job().Type()
switch rc.Run.Job().Type() { switch jobType {
case model.JobTypeDefault: case model.JobTypeDefault:
executor = newJobExecutor(rc, &stepFactoryImpl{}, rc) executor = newJobExecutor(rc, &stepFactoryImpl{}, rc)
case model.JobTypeReusableWorkflowLocal: case model.JobTypeReusableWorkflowLocal:
executor = newLocalReusableWorkflowExecutor(rc) executor = newLocalReusableWorkflowExecutor(rc)
case model.JobTypeReusableWorkflowRemote: case model.JobTypeReusableWorkflowRemote:
executor = newRemoteReusableWorkflowExecutor(rc) executor = newRemoteReusableWorkflowExecutor(rc)
case model.JobTypeInvalid:
return nil, err
} }
return func(ctx context.Context) error { return func(ctx context.Context) error {
@@ -600,10 +595,10 @@ func (rc *RunContext) Executor() common.Executor {
return executor(ctx) return executor(ctx)
} }
return nil return nil
} }, nil
} }
func (rc *RunContext) platformImage(ctx context.Context) string { func (rc *RunContext) containerImage(ctx context.Context) string {
job := rc.Run.Job() job := rc.Run.Job()
c := job.Container() c := job.Container()
@@ -611,6 +606,12 @@ func (rc *RunContext) platformImage(ctx context.Context) string {
return rc.ExprEval.Interpolate(ctx, c.Image) return rc.ExprEval.Interpolate(ctx, c.Image)
} }
return ""
}
func (rc *RunContext) runsOnImage(ctx context.Context) string {
job := rc.Run.Job()
if job.RunsOn() == nil { if job.RunsOn() == nil {
common.Logger(ctx).Errorf("'runs-on' key not defined in %s", rc.String()) common.Logger(ctx).Errorf("'runs-on' key not defined in %s", rc.String())
} }
@@ -636,7 +637,15 @@ func (rc *RunContext) platformImage(ctx context.Context) string {
return "" return ""
} }
func (rc *RunContext) options(ctx context.Context) string { func (rc *RunContext) platformImage(ctx context.Context) string {
if containerImage := rc.containerImage(ctx); containerImage != "" {
return containerImage
}
return rc.runsOnImage(ctx)
}
func (rc *RunContext) options(_ context.Context) string {
job := rc.Run.Job() job := rc.Run.Job()
c := job.Container() c := job.Container()
if c == nil { if c == nil {
@@ -649,19 +658,24 @@ func (rc *RunContext) options(ctx context.Context) string {
func (rc *RunContext) isEnabled(ctx context.Context) (bool, error) { func (rc *RunContext) isEnabled(ctx context.Context) (bool, error) {
job := rc.Run.Job() job := rc.Run.Job()
l := common.Logger(ctx) l := common.Logger(ctx)
runJob, err := EvalBool(ctx, rc.ExprEval, job.If.Value, exprparser.DefaultStatusCheckSuccess) runJob, runJobErr := EvalBool(ctx, rc.ExprEval, job.If.Value, exprparser.DefaultStatusCheckSuccess)
if err != nil { jobType, jobTypeErr := job.Type()
return false, fmt.Errorf(" \u274C Error in if-expression: \"if: %s\" (%s)", job.If.Value, err)
if runJobErr != nil {
return false, fmt.Errorf(" \u274C Error in if-expression: \"if: %s\" (%s)", job.If.Value, runJobErr)
} }
if jobType == model.JobTypeInvalid {
return false, jobTypeErr
} else if jobType != model.JobTypeDefault {
return true, nil
}
if !runJob { if !runJob {
l.WithField("jobResult", "skipped").Debugf("Skipping job '%s' due to '%s'", job.Name, job.If.Value) l.WithField("jobResult", "skipped").Debugf("Skipping job '%s' due to '%s'", job.Name, job.If.Value)
return false, nil return false, nil
} }
if job.Type() != model.JobTypeDefault {
return true, nil
}
img := rc.platformImage(ctx) img := rc.platformImage(ctx)
if img == "" { if img == "" {
if job.RunsOn() == nil { if job.RunsOn() == nil {
@@ -814,6 +828,15 @@ func (rc *RunContext) getGithubContext(ctx context.Context) *model.GithubContext
ghc.Token = preset.Token ghc.Token = preset.Token
ghc.RepositoryOwner = preset.RepositoryOwner ghc.RepositoryOwner = preset.RepositoryOwner
ghc.RetentionDays = preset.RetentionDays ghc.RetentionDays = preset.RetentionDays
instance := rc.Config.GitHubInstance
if !strings.HasPrefix(instance, "http://") &&
!strings.HasPrefix(instance, "https://") {
instance = "https://" + instance
}
ghc.ServerURL = instance
ghc.APIURL = instance + "/api/v1" // the version of Gitea is v1
ghc.GraphQLURL = "" // Gitea doesn't support graphql
return ghc return ghc
} }
} }
@@ -847,6 +870,18 @@ func (rc *RunContext) getGithubContext(ctx context.Context) *model.GithubContext
ghc.APIURL = fmt.Sprintf("https://%s/api/v3", rc.Config.GitHubInstance) ghc.APIURL = fmt.Sprintf("https://%s/api/v3", rc.Config.GitHubInstance)
ghc.GraphQLURL = fmt.Sprintf("https://%s/api/graphql", rc.Config.GitHubInstance) ghc.GraphQLURL = fmt.Sprintf("https://%s/api/graphql", rc.Config.GitHubInstance)
} }
{ // Adapt to Gitea
instance := rc.Config.GitHubInstance
if !strings.HasPrefix(instance, "http://") &&
!strings.HasPrefix(instance, "https://") {
instance = "https://" + instance
}
ghc.ServerURL = instance
ghc.APIURL = instance + "/api/v1" // the version of Gitea is v1
ghc.GraphQLURL = "" // Gitea doesn't support graphql
}
// allow to be overridden by user // allow to be overridden by user
if rc.Config.Env["GITHUB_SERVER_URL"] != "" { if rc.Config.Env["GITHUB_SERVER_URL"] != "" {
ghc.ServerURL = rc.Config.Env["GITHUB_SERVER_URL"] ghc.ServerURL = rc.Config.Env["GITHUB_SERVER_URL"]
@@ -983,37 +1018,37 @@ func setActionRuntimeVars(rc *RunContext, env map[string]string) {
env["ACTIONS_RUNTIME_TOKEN"] = actionsRuntimeToken env["ACTIONS_RUNTIME_TOKEN"] = actionsRuntimeToken
} }
func (rc *RunContext) handleCredentials(ctx context.Context) (username, password string, err error) { func (rc *RunContext) handleCredentials(ctx context.Context) (string, string, error) {
// TODO: remove below 2 lines when we can release act with breaking changes // TODO: remove below 2 lines when we can release act with breaking changes
username = rc.Config.Secrets["DOCKER_USERNAME"] username := rc.Config.Secrets["DOCKER_USERNAME"]
password = rc.Config.Secrets["DOCKER_PASSWORD"] password := rc.Config.Secrets["DOCKER_PASSWORD"]
container := rc.Run.Job().Container() container := rc.Run.Job().Container()
if container == nil || container.Credentials == nil { if container == nil || container.Credentials == nil {
return return username, password, nil
} }
if container.Credentials != nil && len(container.Credentials) != 2 { if container.Credentials != nil && len(container.Credentials) != 2 {
err = fmt.Errorf("invalid property count for key 'credentials:'") err := fmt.Errorf("invalid property count for key 'credentials:'")
return return "", "", err
} }
ee := rc.NewExpressionEvaluator(ctx) ee := rc.NewExpressionEvaluator(ctx)
if username = ee.Interpolate(ctx, container.Credentials["username"]); username == "" { if username = ee.Interpolate(ctx, container.Credentials["username"]); username == "" {
err = fmt.Errorf("failed to interpolate container.credentials.username") err := fmt.Errorf("failed to interpolate container.credentials.username")
return return "", "", err
} }
if password = ee.Interpolate(ctx, container.Credentials["password"]); password == "" { if password = ee.Interpolate(ctx, container.Credentials["password"]); password == "" {
err = fmt.Errorf("failed to interpolate container.credentials.password") err := fmt.Errorf("failed to interpolate container.credentials.password")
return return "", "", err
} }
if container.Credentials["username"] == "" || container.Credentials["password"] == "" { if container.Credentials["username"] == "" || container.Credentials["password"] == "" {
err = fmt.Errorf("container.credentials cannot be empty") err := fmt.Errorf("container.credentials cannot be empty")
return return "", "", err
} }
return username, password, err return username, password, nil
} }
func (rc *RunContext) handleServiceCredentials(ctx context.Context, creds map[string]string) (username, password string, err error) { func (rc *RunContext) handleServiceCredentials(ctx context.Context, creds map[string]string) (username, password string, err error) {

View File

@@ -5,13 +5,13 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"os" "os"
"runtime"
"time" "time"
docker_container "github.com/docker/docker/api/types/container"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
docker_container "github.com/docker/docker/api/types/container"
"github.com/nektos/act/pkg/common" "github.com/nektos/act/pkg/common"
"github.com/nektos/act/pkg/container"
"github.com/nektos/act/pkg/model" "github.com/nektos/act/pkg/model"
) )
@@ -24,6 +24,7 @@ type Runner interface {
type Config struct { type Config struct {
Actor string // the user that triggered the event Actor string // the user that triggered the event
Workdir string // path to working directory Workdir string // path to working directory
ActionCacheDir string // path used for caching action contents
BindWorkdir bool // bind the workdir to the job container BindWorkdir bool // bind the workdir to the job container
EventName string // name of event to run EventName string // name of event to run
EventPath string // path to JSON file to use for event.json in containers EventPath string // path to JSON file to use for event.json in containers
@@ -33,6 +34,7 @@ type Config struct {
ForceRebuild bool // force rebuilding local docker image action ForceRebuild bool // force rebuilding local docker image action
LogOutput bool // log the output from docker run LogOutput bool // log the output from docker run
JSONLogger bool // use json or text logger JSONLogger bool // use json or text logger
LogPrefixJobID bool // switches from the full job name to the job id
Env map[string]string // env for containers Env map[string]string // env for containers
Inputs map[string]string // manually passed action inputs Inputs map[string]string // manually passed action inputs
Secrets map[string]string // list of secrets Secrets map[string]string // list of secrets
@@ -64,8 +66,7 @@ type Config struct {
ContainerNamePrefix string // the prefix of container name ContainerNamePrefix string // the prefix of container name
ContainerMaxLifetime time.Duration // the max lifetime of job containers ContainerMaxLifetime time.Duration // the max lifetime of job containers
ContainerNetworkMode docker_container.NetworkMode // the network mode of job containers (the value of --network) ContainerNetworkMode docker_container.NetworkMode // the network mode of job containers (the value of --network)
DefaultActionInstance string // Deprecated: use DefaultActionsURLs instead. DefaultActionInstance string // the default actions web site
DefaultActionsURLs []string // urls from gitea's `DEFAULT_ACTIONS_URL` config
PlatformPicker func(labels []string) string // platform picker, it will take precedence over Platforms if isn't nil PlatformPicker func(labels []string) string // platform picker, it will take precedence over Platforms if isn't nil
JobLoggerLevel *log.Level // the level of job logger JobLoggerLevel *log.Level // the level of job logger
ValidVolumes []string // only volumes (and bind mounts) in this slice can be mounted on the job container or service containers ValidVolumes []string // only volumes (and bind mounts) in this slice can be mounted on the job container or service containers
@@ -128,15 +129,45 @@ func (runner *runnerImpl) NewPlanExecutor(plan *model.Plan) common.Executor {
maxJobNameLen := 0 maxJobNameLen := 0
stagePipeline := make([]common.Executor, 0) stagePipeline := make([]common.Executor, 0)
log.Debugf("Plan Stages: %v", plan.Stages)
for i := range plan.Stages { for i := range plan.Stages {
stage := plan.Stages[i] stage := plan.Stages[i]
stagePipeline = append(stagePipeline, func(ctx context.Context) error { stagePipeline = append(stagePipeline, func(ctx context.Context) error {
pipeline := make([]common.Executor, 0) pipeline := make([]common.Executor, 0)
for _, run := range stage.Runs { for _, run := range stage.Runs {
log.Debugf("Stages Runs: %v", stage.Runs)
stageExecutor := make([]common.Executor, 0) stageExecutor := make([]common.Executor, 0)
job := run.Job() job := run.Job()
log.Debugf("Job.Name: %v", job.Name)
log.Debugf("Job.RawNeeds: %v", job.RawNeeds)
log.Debugf("Job.RawRunsOn: %v", job.RawRunsOn)
log.Debugf("Job.Env: %v", job.Env)
log.Debugf("Job.If: %v", job.If)
for step := range job.Steps {
if nil != job.Steps[step] {
log.Debugf("Job.Steps: %v", job.Steps[step].String())
}
}
log.Debugf("Job.TimeoutMinutes: %v", job.TimeoutMinutes)
log.Debugf("Job.Services: %v", job.Services)
log.Debugf("Job.Strategy: %v", job.Strategy)
log.Debugf("Job.RawContainer: %v", job.RawContainer)
log.Debugf("Job.Defaults.Run.Shell: %v", job.Defaults.Run.Shell)
log.Debugf("Job.Defaults.Run.WorkingDirectory: %v", job.Defaults.Run.WorkingDirectory)
log.Debugf("Job.Outputs: %v", job.Outputs)
log.Debugf("Job.Uses: %v", job.Uses)
log.Debugf("Job.With: %v", job.With)
// log.Debugf("Job.RawSecrets: %v", job.RawSecrets)
log.Debugf("Job.Result: %v", job.Result)
if job.Strategy != nil { if job.Strategy != nil {
log.Debugf("Job.Strategy.FailFast: %v", job.Strategy.FailFast)
log.Debugf("Job.Strategy.MaxParallel: %v", job.Strategy.MaxParallel)
log.Debugf("Job.Strategy.FailFastString: %v", job.Strategy.FailFastString)
log.Debugf("Job.Strategy.MaxParallelString: %v", job.Strategy.MaxParallelString)
log.Debugf("Job.Strategy.RawMatrix: %v", job.Strategy.RawMatrix)
strategyRc := runner.newRunContext(ctx, run, nil) strategyRc := runner.newRunContext(ctx, run, nil)
if err := strategyRc.NewExpressionEvaluator(ctx).EvaluateYamlNode(ctx, &job.Strategy.RawMatrix); err != nil { if err := strategyRc.NewExpressionEvaluator(ctx).EvaluateYamlNode(ctx, &job.Strategy.RawMatrix); err != nil {
log.Errorf("Error while evaluating matrix: %v", err) log.Errorf("Error while evaluating matrix: %v", err)
@@ -147,6 +178,8 @@ func (runner *runnerImpl) NewPlanExecutor(plan *model.Plan) common.Executor {
if m, err := job.GetMatrixes(); err != nil { if m, err := job.GetMatrixes(); err != nil {
log.Errorf("Error while get job's matrix: %v", err) log.Errorf("Error while get job's matrix: %v", err)
} else { } else {
log.Debugf("Job Matrices: %v", m)
log.Debugf("Runner Matrices: %v", runner.config.Matrix)
matrixes = selectMatrixes(m, runner.config.Matrix) matrixes = selectMatrixes(m, runner.config.Matrix)
} }
log.Debugf("Final matrix after applying user inclusions '%v'", matrixes) log.Debugf("Final matrix after applying user inclusions '%v'", matrixes)
@@ -172,19 +205,22 @@ func (runner *runnerImpl) NewPlanExecutor(plan *model.Plan) common.Executor {
} }
stageExecutor = append(stageExecutor, func(ctx context.Context) error { stageExecutor = append(stageExecutor, func(ctx context.Context) error {
jobName := fmt.Sprintf("%-*s", maxJobNameLen, rc.String()) jobName := fmt.Sprintf("%-*s", maxJobNameLen, rc.String())
return rc.Executor()(common.WithJobErrorContainer(WithJobLogger(ctx, rc.Run.JobID, jobName, rc.Config, &rc.Masks, matrix))) executor, err := rc.Executor()
if err != nil {
return err
}
return executor(common.WithJobErrorContainer(WithJobLogger(ctx, rc.Run.JobID, jobName, rc.Config, &rc.Masks, matrix)))
}) })
} }
pipeline = append(pipeline, common.NewParallelExecutor(maxParallel, stageExecutor...)) pipeline = append(pipeline, common.NewParallelExecutor(maxParallel, stageExecutor...))
} }
var ncpu int ncpu := runtime.NumCPU()
info, err := container.GetHostInfo(ctx) if 1 > ncpu {
if err != nil { ncpu = 1
log.Errorf("failed to obtain container engine info: %s", err)
ncpu = 1 // sane default?
} else {
ncpu = info.NCPU
} }
log.Debugf("Detected CPUs: %d", ncpu)
return common.NewParallelExecutor(ncpu, pipeline...)(ctx) return common.NewParallelExecutor(ncpu, pipeline...)(ctx)
}) })
} }

View File

@@ -288,6 +288,7 @@ func TestRunEvent(t *testing.T) {
{workdir, "docker-action-custom-path", "push", "", platforms, secrets}, {workdir, "docker-action-custom-path", "push", "", platforms, secrets},
{workdir, "GITHUB_ENV-use-in-env-ctx", "push", "", platforms, secrets}, {workdir, "GITHUB_ENV-use-in-env-ctx", "push", "", platforms, secrets},
{workdir, "ensure-post-steps", "push", "Job 'second-post-step-should-fail' failed", platforms, secrets}, {workdir, "ensure-post-steps", "push", "Job 'second-post-step-should-fail' failed", platforms, secrets},
{workdir, "workflow_call_inputs", "workflow_call", "", platforms, secrets},
{workdir, "workflow_dispatch", "workflow_dispatch", "", platforms, secrets}, {workdir, "workflow_dispatch", "workflow_dispatch", "", platforms, secrets},
{workdir, "workflow_dispatch_no_inputs_mapping", "workflow_dispatch", "", platforms, secrets}, {workdir, "workflow_dispatch_no_inputs_mapping", "workflow_dispatch", "", platforms, secrets},
{workdir, "workflow_dispatch-scalar", "workflow_dispatch", "", platforms, secrets}, {workdir, "workflow_dispatch-scalar", "workflow_dispatch", "", platforms, secrets},

View File

@@ -4,7 +4,9 @@ import (
"context" "context"
"fmt" "fmt"
"path" "path"
"strconv"
"strings" "strings"
"time"
"github.com/nektos/act/pkg/common" "github.com/nektos/act/pkg/common"
"github.com/nektos/act/pkg/container" "github.com/nektos/act/pkg/container"
@@ -134,7 +136,9 @@ func runStepExecutor(step step, stage stepStage, executor common.Executor) commo
Mode: 0o666, Mode: 0o666,
})(ctx) })(ctx)
err = executor(ctx) timeoutctx, cancelTimeOut := evaluateStepTimeout(ctx, rc.ExprEval, stepModel)
defer cancelTimeOut()
err = executor(timeoutctx)
if err == nil { if err == nil {
logger.WithField("stepResult", stepResult.Outcome).Infof(" \u2705 Success - %s %s", stage, stepString) logger.WithField("stepResult", stepResult.Outcome).Infof(" \u2705 Success - %s %s", stage, stepString)
@@ -182,6 +186,16 @@ func runStepExecutor(step step, stage stepStage, executor common.Executor) commo
} }
} }
func evaluateStepTimeout(ctx context.Context, exprEval ExpressionEvaluator, stepModel *model.Step) (context.Context, context.CancelFunc) {
timeout := exprEval.Interpolate(ctx, stepModel.TimeoutMinutes)
if timeout != "" {
if timeOutMinutes, err := strconv.ParseInt(timeout, 10, 64); err == nil {
return context.WithTimeout(ctx, time.Duration(timeOutMinutes)*time.Minute)
}
}
return ctx, func() {}
}
func setupEnv(ctx context.Context, step step) error { func setupEnv(ctx context.Context, step step) error {
rc := step.getRunContext() rc := step.getRunContext()
@@ -242,7 +256,7 @@ func isStepEnabled(ctx context.Context, expr string, step step, stage stepStage)
return runStep, nil return runStep, nil
} }
func isContinueOnError(ctx context.Context, expr string, step step, stage stepStage) (bool, error) { func isContinueOnError(ctx context.Context, expr string, step step, _ stepStage) (bool, error) {
// https://github.com/github/docs/blob/3ae84420bd10997bb5f35f629ebb7160fe776eae/content/actions/reference/workflow-syntax-for-github-actions.md?plain=true#L962 // https://github.com/github/docs/blob/3ae84420bd10997bb5f35f629ebb7160fe776eae/content/actions/reference/workflow-syntax-for-github-actions.md?plain=true#L962
if len(strings.TrimSpace(expr)) == 0 { if len(strings.TrimSpace(expr)) == 0 {
return false, nil return false, nil

View File

@@ -85,7 +85,7 @@ func (sal *stepActionLocal) getEnv() *map[string]string {
return &sal.env return &sal.env
} }
func (sal *stepActionLocal) getIfExpression(context context.Context, stage stepStage) string { func (sal *stepActionLocal) getIfExpression(_ context.Context, stage stepStage) string {
switch stage { switch stage {
case stepStageMain: case stepStageMain:
return sal.Step.If.Value return sal.Step.If.Value

View File

@@ -24,7 +24,7 @@ func (salm *stepActionLocalMocks) runAction(step actionStep, actionDir string, r
return args.Get(0).(func(context.Context) error) return args.Get(0).(func(context.Context) error)
} }
func (salm *stepActionLocalMocks) readAction(ctx context.Context, step *model.Step, actionDir string, actionPath string, readFile actionYamlReader, writeFile fileWriter) (*model.Action, error) { func (salm *stepActionLocalMocks) readAction(_ context.Context, step *model.Step, actionDir string, actionPath string, readFile actionYamlReader, writeFile fileWriter) (*model.Action, error) {
args := salm.Called(step, actionDir, actionPath, readFile, writeFile) args := salm.Called(step, actionDir, actionPath, readFile, writeFile)
return args.Get(0).(*model.Action), args.Error(1) return args.Get(0).(*model.Action), args.Error(1)
} }

View File

@@ -5,13 +5,11 @@ import (
"errors" "errors"
"fmt" "fmt"
"io" "io"
"net/http"
"os" "os"
"path" "path"
"path/filepath" "path/filepath"
"regexp" "regexp"
"strings" "strings"
"time"
gogit "github.com/go-git/go-git/v5" gogit "github.com/go-git/go-git/v5"
@@ -20,8 +18,6 @@ import (
"github.com/nektos/act/pkg/model" "github.com/nektos/act/pkg/model"
) )
var detectActionClient = http.Client{Timeout: 5 * time.Second}
type stepActionRemote struct { type stepActionRemote struct {
Step *model.Step Step *model.Step
RunContext *RunContext RunContext *RunContext
@@ -43,6 +39,12 @@ func (sar *stepActionRemote) prepareActionExecutor() common.Executor {
return nil return nil
} }
// For gitea:
// Since actions can specify the download source via a url prefix.
// The prefix may contain some sensitive information that needs to be stored in secrets,
// so we need to interpolate the expression value for uses first.
sar.Step.Uses = sar.RunContext.NewExpressionEvaluator(ctx).Interpolate(ctx, sar.Step.Uses)
sar.remoteAction = newRemoteAction(sar.Step.Uses) sar.remoteAction = newRemoteAction(sar.Step.Uses)
if sar.remoteAction == nil { if sar.remoteAction == nil {
return fmt.Errorf("Expected format {org}/{repo}[/path]@ref. Actual '%s' Input string was not in a correct format", sar.Step.Uses) return fmt.Errorf("Expected format {org}/{repo}[/path]@ref. Actual '%s' Input string was not in a correct format", sar.Step.Uses)
@@ -56,19 +58,14 @@ func (sar *stepActionRemote) prepareActionExecutor() common.Executor {
for _, action := range sar.RunContext.Config.ReplaceGheActionWithGithubCom { for _, action := range sar.RunContext.Config.ReplaceGheActionWithGithubCom {
if strings.EqualFold(fmt.Sprintf("%s/%s", sar.remoteAction.Org, sar.remoteAction.Repo), action) { if strings.EqualFold(fmt.Sprintf("%s/%s", sar.remoteAction.Org, sar.remoteAction.Repo), action) {
sar.remoteAction.URL = "github.com" sar.remoteAction.URL = "https://github.com"
github.Token = sar.RunContext.Config.ReplaceGheActionTokenWithGithubCom github.Token = sar.RunContext.Config.ReplaceGheActionTokenWithGithubCom
} }
} }
cloneURL, err := sar.remoteAction.GetAvailableCloneURL(sar.RunContext.Config.DefaultActionsURLs)
if err != nil {
return fmt.Errorf("failed to get available clone url of [%s] action, error: %w", sar.Step.Uses, err)
}
actionDir := fmt.Sprintf("%s/%s", sar.RunContext.ActionCacheDir(), safeFilename(sar.Step.Uses)) actionDir := fmt.Sprintf("%s/%s", sar.RunContext.ActionCacheDir(), safeFilename(sar.Step.Uses))
gitClone := stepActionRemoteNewCloneExecutor(git.NewGitCloneExecutorInput{ gitClone := stepActionRemoteNewCloneExecutor(git.NewGitCloneExecutorInput{
URL: cloneURL, URL: sar.remoteAction.CloneURL(sar.RunContext.Config.DefaultActionInstance),
Ref: sar.remoteAction.Ref, Ref: sar.remoteAction.Ref,
Dir: actionDir, Dir: actionDir,
Token: "", /* Token: "", /*
@@ -223,14 +220,15 @@ type remoteAction struct {
Ref string Ref string
} }
func (ra *remoteAction) CloneURL(defaultURL string) string { func (ra *remoteAction) CloneURL(u string) string {
u := ra.URL if ra.URL == "" {
if u == "" { if !strings.HasPrefix(u, "http://") && !strings.HasPrefix(u, "https://") {
u = defaultURL u = "https://" + u
} }
if !strings.HasPrefix(u, "http://") && !strings.HasPrefix(u, "https://") { } else {
u = "https://" + u u = ra.URL
} }
return fmt.Sprintf("%s/%s/%s", u, ra.Org, ra.Repo) return fmt.Sprintf("%s/%s/%s", u, ra.Org, ra.Repo)
} }
@@ -241,29 +239,6 @@ func (ra *remoteAction) IsCheckout() bool {
return false return false
} }
func (ra *remoteAction) GetAvailableCloneURL(actionURLs []string) (string, error) {
for _, u := range actionURLs {
cloneURL := ra.CloneURL(u)
resp, err := detectActionClient.Get(cloneURL)
if err != nil {
return "", err
}
defer resp.Body.Close()
switch resp.StatusCode {
case http.StatusOK:
return cloneURL, nil
case http.StatusNotFound:
continue
default:
return "", fmt.Errorf("unexpected http status code: %d", resp.StatusCode)
}
}
return "", fmt.Errorf("no available url found")
}
func newRemoteAction(action string) *remoteAction { func newRemoteAction(action string) *remoteAction {
// support http(s)://host/owner/repo@v3 // support http(s)://host/owner/repo@v3
for _, schema := range []string{"https://", "http://"} { for _, schema := range []string{"https://", "http://"} {

View File

@@ -21,7 +21,7 @@ type stepActionRemoteMocks struct {
mock.Mock mock.Mock
} }
func (sarm *stepActionRemoteMocks) readAction(ctx context.Context, step *model.Step, actionDir string, actionPath string, readFile actionYamlReader, writeFile fileWriter) (*model.Action, error) { func (sarm *stepActionRemoteMocks) readAction(_ context.Context, step *model.Step, actionDir string, actionPath string, readFile actionYamlReader, writeFile fileWriter) (*model.Action, error) {
args := sarm.Called(step, actionDir, actionPath, readFile, writeFile) args := sarm.Called(step, actionDir, actionPath, readFile, writeFile)
return args.Get(0).(*model.Action), args.Error(1) return args.Get(0).(*model.Action), args.Error(1)
} }

View File

@@ -51,7 +51,7 @@ func (sd *stepDocker) getEnv() *map[string]string {
return &sd.env return &sd.env
} }
func (sd *stepDocker) getIfExpression(context context.Context, stage stepStage) string { func (sd *stepDocker) getIfExpression(_ context.Context, _ stepStage) string {
return sd.Step.If.Value return sd.Step.If.Value
} }
@@ -114,23 +114,24 @@ func (sd *stepDocker) newStepContainer(ctx context.Context, image string, cmd []
binds, mounts := rc.GetBindsAndMounts() binds, mounts := rc.GetBindsAndMounts()
stepContainer := ContainerNewContainer(&container.NewContainerInput{ stepContainer := ContainerNewContainer(&container.NewContainerInput{
Cmd: cmd, Cmd: cmd,
Entrypoint: entrypoint, Entrypoint: entrypoint,
WorkingDir: rc.JobContainer.ToContainerPath(rc.Config.Workdir), WorkingDir: rc.JobContainer.ToContainerPath(rc.Config.Workdir),
Image: image, Image: image,
Username: rc.Config.Secrets["DOCKER_USERNAME"], Username: rc.Config.Secrets["DOCKER_USERNAME"],
Password: rc.Config.Secrets["DOCKER_PASSWORD"], Password: rc.Config.Secrets["DOCKER_PASSWORD"],
Name: createSimpleContainerName(rc.jobContainerName(), "STEP-"+step.ID), Name: createSimpleContainerName(rc.jobContainerName(), "STEP-"+step.ID),
Env: envList, Env: envList,
Mounts: mounts, Mounts: mounts,
NetworkMode: fmt.Sprintf("container:%s", rc.jobContainerName()), NetworkMode: fmt.Sprintf("container:%s", rc.jobContainerName()),
Binds: binds, Binds: binds,
Stdout: logWriter, Stdout: logWriter,
Stderr: logWriter, Stderr: logWriter,
Privileged: rc.Config.Privileged, Privileged: rc.Config.Privileged,
UsernsMode: rc.Config.UsernsMode, UsernsMode: rc.Config.UsernsMode,
Platform: rc.Config.ContainerArchitecture, Platform: rc.Config.ContainerArchitecture,
AutoRemove: rc.Config.AutoRemove, AutoRemove: rc.Config.AutoRemove,
ValidVolumes: rc.Config.ValidVolumes,
}) })
return stepContainer return stepContainer
} }

View File

@@ -59,7 +59,7 @@ func (sr *stepRun) getEnv() *map[string]string {
return &sr.env return &sr.env
} }
func (sr *stepRun) getIfExpression(context context.Context, stage stepStage) string { func (sr *stepRun) getIfExpression(_ context.Context, _ stepStage) string {
return sr.Step.If.Value return sr.Step.If.Value
} }

View File

@@ -0,0 +1,6 @@
{
"inputs": {
"required": "required input",
"boolean": "true"
}
}

View File

@@ -0,0 +1,36 @@
name: workflow_call
on:
workflow_call:
inputs:
required:
description: a required input
required: true
with_default:
description: an input with default
required: false
default: default
boolean:
description: an input of type boolean
required: false
type: boolean
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: test required input
run: |
echo input.required=${{ inputs.required }}
[[ "${{ inputs.required }}" = "required input" ]] || exit 1
- name: test input with default
run: |
echo input.with_default=${{ inputs.with_default }}
[[ "${{ inputs.with_default }}" = "default" ]] || exit 1
- id: boolean-test
name: run on boolean input
if: ${{ inputs.boolean == true }}
run: echo "::set-output name=value::executed"
- name: has boolean test?
run: |
[[ "${{ steps.boolean-test.outputs.value }}" = "executed" ]] || exit 1