Compare commits
19 commits
main
...
2024-03-11
Author | SHA1 | Date | |
---|---|---|---|
|
d38e069064 | ||
|
d6cdcd4916 | ||
|
a996610578 | ||
|
fdc68581dd | ||
|
f79ec84c16 | ||
|
d9f81c9e04 | ||
|
9db5480aad | ||
|
bf72e67041 | ||
|
844f117f31 | ||
|
25c4ac6b73 | ||
|
0570e040a8 | ||
|
61f412a1f1 | ||
|
207dff2fe4 | ||
|
032294082f | ||
|
6769d4dbc1 | ||
|
de9ef55ef7 | ||
|
b0c5099580 | ||
|
70400ccc71 | ||
|
78981ee343 |
70 changed files with 1052 additions and 1454 deletions
|
@ -1,9 +1,7 @@
|
||||||
name: checks
|
name: checks
|
||||||
on:
|
on:
|
||||||
push:
|
- push
|
||||||
branches:
|
- pull_request
|
||||||
- 'main'
|
|
||||||
pull_request:
|
|
||||||
|
|
||||||
env:
|
env:
|
||||||
GOPROXY: https://goproxy.io,direct
|
GOPROXY: https://goproxy.io,direct
|
||||||
|
@ -35,14 +33,12 @@ jobs:
|
||||||
go_cache-
|
go_cache-
|
||||||
- uses: actions/setup-go@v3
|
- uses: actions/setup-go@v3
|
||||||
with:
|
with:
|
||||||
go-version: 1.21
|
go-version: 1.20
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- name: vet checks
|
- name: vet checks
|
||||||
run: go vet -v ./...
|
run: go vet -v ./...
|
||||||
- name: build
|
- name: build
|
||||||
run: go build -v ./...
|
run: go build -v ./...
|
||||||
- name: build without docker
|
|
||||||
run: go build -tags WITHOUT_DOCKER -v ./...
|
|
||||||
- name: test
|
- name: test
|
||||||
run: go test -v ./pkg/jobparser ./pkg/model ./pkg/exprparser
|
run: go test -v ./pkg/jobparser
|
||||||
# TODO test more packages
|
# TODO test more packages
|
||||||
|
|
44
.gitea/workflows/test.yml
Normal file
44
.gitea/workflows/test.yml
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
name: checks
|
||||||
|
on:
|
||||||
|
- push
|
||||||
|
- pull_request
|
||||||
|
|
||||||
|
env:
|
||||||
|
GOPROXY: https://goproxy.io,direct
|
||||||
|
GOPATH: /go_path
|
||||||
|
GOCACHE: /go_cache
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
lint:
|
||||||
|
name: check and test
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: cache go path
|
||||||
|
id: cache-go-path
|
||||||
|
uses: https://github.com/actions/cache@v3
|
||||||
|
with:
|
||||||
|
path: /go_path
|
||||||
|
key: go_path-${{ github.repository }}-${{ github.ref_name }}
|
||||||
|
restore-keys: |
|
||||||
|
go_path-${{ github.repository }}-
|
||||||
|
go_path-
|
||||||
|
- name: cache go cache
|
||||||
|
id: cache-go-cache
|
||||||
|
uses: https://github.com/actions/cache@v3
|
||||||
|
with:
|
||||||
|
path: /go_cache
|
||||||
|
key: go_cache-${{ github.repository }}-${{ github.ref_name }}
|
||||||
|
restore-keys: |
|
||||||
|
go_cache-${{ github.repository }}-
|
||||||
|
go_cache-
|
||||||
|
- uses: actions/setup-go@v3
|
||||||
|
with:
|
||||||
|
go-version: 1.20
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- name: vet checks
|
||||||
|
run: go vet -v ./...
|
||||||
|
- name: build
|
||||||
|
run: go build -v ./...
|
||||||
|
- name: test
|
||||||
|
run: go test -v ./pkg/jobparser
|
||||||
|
# TODO test more packages
|
1
.github/FUNDING.yml
vendored
Normal file
1
.github/FUNDING.yml
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
github: cplee
|
88
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
88
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
name: Bug report
|
||||||
|
description: Use this template for reporting bugs/issues.
|
||||||
|
labels:
|
||||||
|
- 'kind/bug'
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: |
|
||||||
|
Thanks for taking the time to fill out this bug report!
|
||||||
|
- type: textarea
|
||||||
|
id: act-debug
|
||||||
|
attributes:
|
||||||
|
label: Bug report info
|
||||||
|
render: plain text
|
||||||
|
description: |
|
||||||
|
Output of `act --bug-report`
|
||||||
|
placeholder: |
|
||||||
|
act --bug-report
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: act-command
|
||||||
|
attributes:
|
||||||
|
label: Command used with act
|
||||||
|
description: |
|
||||||
|
Please paste your whole command
|
||||||
|
placeholder: |
|
||||||
|
act -P ubuntu-latest=node:12 -v -d ...
|
||||||
|
render: sh
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: what-happened
|
||||||
|
attributes:
|
||||||
|
label: Describe issue
|
||||||
|
description: |
|
||||||
|
Also tell us what did you expect to happen?
|
||||||
|
placeholder: |
|
||||||
|
Describe issue
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: input
|
||||||
|
id: repo
|
||||||
|
attributes:
|
||||||
|
label: Link to GitHub repository
|
||||||
|
description: |
|
||||||
|
Provide link to GitHub repository, you can skip it if the repository is private or you don't have it on GitHub, otherwise please provide it as it might help us troubleshoot problem
|
||||||
|
placeholder: |
|
||||||
|
https://github.com/nektos/act
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: textarea
|
||||||
|
id: workflow
|
||||||
|
attributes:
|
||||||
|
label: Workflow content
|
||||||
|
description: |
|
||||||
|
Please paste your **whole** workflow here
|
||||||
|
placeholder: |
|
||||||
|
name: My workflow
|
||||||
|
on: ['push', 'schedule']
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
KEY: VAL
|
||||||
|
[...]
|
||||||
|
render: yml
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: logs
|
||||||
|
attributes:
|
||||||
|
label: Relevant log output
|
||||||
|
description: |
|
||||||
|
Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks. Please verify that the log output doesn't contain any sensitive data.
|
||||||
|
render: sh
|
||||||
|
placeholder: |
|
||||||
|
Use `act -v` for verbose output
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: additional-info
|
||||||
|
attributes:
|
||||||
|
label: Additional information
|
||||||
|
placeholder: |
|
||||||
|
Additional information that doesn't fit elsewhere
|
||||||
|
validations:
|
||||||
|
required: false
|
14
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
14
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
blank_issues_enabled: true
|
||||||
|
contact_links:
|
||||||
|
- name: Start a discussion
|
||||||
|
url: https://github.com/nektos/act/discussions/new
|
||||||
|
about: You can ask for help here!
|
||||||
|
- name: Ask on Gitter
|
||||||
|
url: https://gitter.im/nektos/act
|
||||||
|
about: You can ask for help here!
|
||||||
|
- name: Ask on Gitter (via Matrix)
|
||||||
|
url: https://matrix.to/#/#nektos_act:gitter.im?via=gitter.im&via=matrix.org
|
||||||
|
about: If you prefer Matrix over Gitter
|
||||||
|
- name: Want to contribute to act?
|
||||||
|
url: https://github.com/nektos/act/blob/master/CONTRIBUTING.md
|
||||||
|
about: Be sure to read contributing guidelines!
|
28
.github/ISSUE_TEMPLATE/feature_template.yml
vendored
Normal file
28
.github/ISSUE_TEMPLATE/feature_template.yml
vendored
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
name: Feature request
|
||||||
|
description: Use this template for requesting a feature/enhancement.
|
||||||
|
labels:
|
||||||
|
- 'kind/feature-request'
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: |
|
||||||
|
Please note that incompatibility with GitHub Actions should be opened as a bug report, not a new feature.
|
||||||
|
- type: input
|
||||||
|
id: act-version
|
||||||
|
attributes:
|
||||||
|
label: Act version
|
||||||
|
description: |
|
||||||
|
What version of `act` are you using? Version can be obtained via `act --version`
|
||||||
|
If you've built it from source, please provide commit hash
|
||||||
|
placeholder: |
|
||||||
|
act --version
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: feature
|
||||||
|
attributes:
|
||||||
|
label: Feature description
|
||||||
|
description: Describe feature that you would like to see
|
||||||
|
placeholder: ...
|
||||||
|
validations:
|
||||||
|
required: true
|
18
.github/ISSUE_TEMPLATE/wiki_issue.yml
vendored
Normal file
18
.github/ISSUE_TEMPLATE/wiki_issue.yml
vendored
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
name: Wiki issue
|
||||||
|
description: Report issue/improvement ragarding documentation (wiki)
|
||||||
|
labels:
|
||||||
|
- 'kind/discussion'
|
||||||
|
- 'area/docs'
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: |
|
||||||
|
Thanks for taking the time to fill out this issue!
|
||||||
|
- type: textarea
|
||||||
|
id: details
|
||||||
|
attributes:
|
||||||
|
label: Details
|
||||||
|
description: |
|
||||||
|
Describe issue
|
||||||
|
validations:
|
||||||
|
required: true
|
20
.github/actions/choco/Dockerfile
vendored
Normal file
20
.github/actions/choco/Dockerfile
vendored
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
FROM alpine:3.17
|
||||||
|
|
||||||
|
ARG CHOCOVERSION=1.1.0
|
||||||
|
|
||||||
|
RUN apk add --no-cache bash ca-certificates git \
|
||||||
|
&& apk --no-cache --repository http://dl-cdn.alpinelinux.org/alpine/edge/testing add mono mono-dev \
|
||||||
|
&& cert-sync /etc/ssl/certs/ca-certificates.crt \
|
||||||
|
&& wget "https://github.com/chocolatey/choco/archive/${CHOCOVERSION}.tar.gz" -O- | tar -xzf - \
|
||||||
|
&& cd choco-"${CHOCOVERSION}" \
|
||||||
|
&& chmod +x build.sh zip.sh \
|
||||||
|
&& ./build.sh -v \
|
||||||
|
&& mv ./code_drop/chocolatey/console /opt/chocolatey \
|
||||||
|
&& mkdir -p /opt/chocolatey/lib \
|
||||||
|
&& rm -rf /choco-"${CHOCOVERSION}" \
|
||||||
|
&& apk del mono-dev \
|
||||||
|
&& rm -rf /var/cache/apk/*
|
||||||
|
|
||||||
|
ENV ChocolateyInstall=/opt/chocolatey
|
||||||
|
COPY entrypoint.sh /entrypoint.sh
|
||||||
|
ENTRYPOINT ["/entrypoint.sh"]
|
16
.github/actions/choco/action.yml
vendored
Normal file
16
.github/actions/choco/action.yml
vendored
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
name: 'Chocolatey Packager'
|
||||||
|
description: 'Create the choco package and push it'
|
||||||
|
inputs:
|
||||||
|
version:
|
||||||
|
description: 'Version of package'
|
||||||
|
required: false
|
||||||
|
apiKey:
|
||||||
|
description: 'API Key for chocolately'
|
||||||
|
required: false
|
||||||
|
push:
|
||||||
|
description: 'Option for if package is going to be pushed'
|
||||||
|
required: false
|
||||||
|
default: 'false'
|
||||||
|
runs:
|
||||||
|
using: 'docker'
|
||||||
|
image: 'Dockerfile'
|
31
.github/actions/choco/entrypoint.sh
vendored
Executable file
31
.github/actions/choco/entrypoint.sh
vendored
Executable file
|
@ -0,0 +1,31 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
function choco {
|
||||||
|
mono /opt/chocolatey/choco.exe "$@" --allow-unofficial --nocolor
|
||||||
|
}
|
||||||
|
|
||||||
|
function get_version {
|
||||||
|
local version=${INPUT_VERSION:-$(git describe --tags)}
|
||||||
|
version=(${version//[!0-9.-]/})
|
||||||
|
local version_parts=(${version//-/ })
|
||||||
|
version=${version_parts[0]}
|
||||||
|
if [ ${#version_parts[@]} -gt 1 ]; then
|
||||||
|
version=${version_parts}.${version_parts[1]}
|
||||||
|
fi
|
||||||
|
echo "$version"
|
||||||
|
}
|
||||||
|
|
||||||
|
## Determine the version to pack
|
||||||
|
VERSION=$(get_version)
|
||||||
|
echo "Packing version ${VERSION} of act"
|
||||||
|
rm -f act-cli.*.nupkg
|
||||||
|
mkdir -p tools
|
||||||
|
cp LICENSE tools/LICENSE.txt
|
||||||
|
cp VERIFICATION tools/VERIFICATION.txt
|
||||||
|
cp dist/act_windows_amd64_v1/act.exe tools/
|
||||||
|
choco pack act-cli.nuspec --version ${VERSION}
|
||||||
|
if [[ "$INPUT_PUSH" == "true" ]]; then
|
||||||
|
choco push act-cli.${VERSION}.nupkg --api-key ${INPUT_APIKEY} -s https://push.chocolatey.org/ --timeout 180
|
||||||
|
fi
|
77
.github/actions/run-tests/action.yml
vendored
Normal file
77
.github/actions/run-tests/action.yml
vendored
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
name: 'run-tests'
|
||||||
|
description: 'Runs go test and upload a step summary'
|
||||||
|
inputs:
|
||||||
|
filter:
|
||||||
|
description: 'The go test pattern for the tests to run'
|
||||||
|
required: false
|
||||||
|
default: ''
|
||||||
|
upload-logs-name:
|
||||||
|
description: 'Choose the name of the log artifact'
|
||||||
|
required: false
|
||||||
|
default: logs-${{ github.job }}-${{ strategy.job-index }}
|
||||||
|
upload-logs:
|
||||||
|
description: 'If true uploads logs of each tests as an artifact'
|
||||||
|
required: false
|
||||||
|
default: 'true'
|
||||||
|
runs:
|
||||||
|
using: composite
|
||||||
|
steps:
|
||||||
|
- uses: actions/github-script@v6
|
||||||
|
with:
|
||||||
|
github-token: none # No reason to grant access to the GITHUB_TOKEN
|
||||||
|
script: |
|
||||||
|
let myOutput = '';
|
||||||
|
var fs = require('fs');
|
||||||
|
var uploadLogs = process.env.UPLOAD_LOGS === 'true';
|
||||||
|
if(uploadLogs) {
|
||||||
|
await io.mkdirP('logs');
|
||||||
|
}
|
||||||
|
var filename = null;
|
||||||
|
const options = {};
|
||||||
|
options.ignoreReturnCode = true;
|
||||||
|
options.env = Object.assign({}, process.env);
|
||||||
|
delete options.env.ACTIONS_RUNTIME_URL;
|
||||||
|
delete options.env.ACTIONS_RUNTIME_TOKEN;
|
||||||
|
delete options.env.ACTIONS_CACHE_URL;
|
||||||
|
options.listeners = {
|
||||||
|
stdout: (data) => {
|
||||||
|
for(line of data.toString().split('\n')) {
|
||||||
|
if(/^\s*(===\s[^\s]+\s|---\s[^\s]+:\s)/.test(line)) {
|
||||||
|
if(uploadLogs) {
|
||||||
|
var runprefix = "=== RUN ";
|
||||||
|
if(line.startsWith(runprefix)) {
|
||||||
|
filename = "logs/" + line.substring(runprefix.length).replace(/[^A-Za-z0-9]/g, '-') + ".txt";
|
||||||
|
fs.writeFileSync(filename, line + "\n");
|
||||||
|
} else if(filename) {
|
||||||
|
fs.appendFileSync(filename, line + "\n");
|
||||||
|
filename = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
myOutput += line + "\n";
|
||||||
|
} else if(filename) {
|
||||||
|
fs.appendFileSync(filename, line + "\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var args = ['test', '-v', '-cover', '-coverprofile=coverage.txt', '-covermode=atomic', '-timeout', '20m'];
|
||||||
|
var filter = process.env.FILTER;
|
||||||
|
if(filter) {
|
||||||
|
args.push('-run');
|
||||||
|
args.push(filter);
|
||||||
|
}
|
||||||
|
args.push('./...');
|
||||||
|
var exitcode = await exec.exec('go', args, options);
|
||||||
|
if(process.env.GITHUB_STEP_SUMMARY) {
|
||||||
|
core.summary.addCodeBlock(myOutput);
|
||||||
|
await core.summary.write();
|
||||||
|
}
|
||||||
|
process.exit(exitcode);
|
||||||
|
env:
|
||||||
|
FILTER: ${{ inputs.filter }}
|
||||||
|
UPLOAD_LOGS: ${{ inputs.upload-logs }}
|
||||||
|
- uses: actions/upload-artifact@v3
|
||||||
|
if: always() && inputs.upload-logs == 'true' && !env.ACT
|
||||||
|
with:
|
||||||
|
name: ${{ inputs.upload-logs-name }}
|
||||||
|
path: logs
|
15
.github/dependabot.yml
vendored
Normal file
15
.github/dependabot.yml
vendored
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
# To get started with Dependabot version updates, you'll need to specify which
|
||||||
|
# package ecosystems to update and where the package manifests are located.
|
||||||
|
# Please see the documentation for all configuration options:
|
||||||
|
# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
|
||||||
|
|
||||||
|
version: 2
|
||||||
|
updates:
|
||||||
|
- package-ecosystem: 'github-actions'
|
||||||
|
directory: '/'
|
||||||
|
schedule:
|
||||||
|
interval: 'weekly'
|
||||||
|
- package-ecosystem: 'gomod'
|
||||||
|
directory: '/'
|
||||||
|
schedule:
|
||||||
|
interval: 'weekly'
|
1
.github/workflows/.gitignore
vendored
Normal file
1
.github/workflows/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
test-*.yml
|
181
.github/workflows/checks.yml
vendored
Normal file
181
.github/workflows/checks.yml
vendored
Normal file
|
@ -0,0 +1,181 @@
|
||||||
|
name: checks
|
||||||
|
on: [pull_request, workflow_dispatch]
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
cancel-in-progress: true
|
||||||
|
group: ${{ github.workflow }}-${{ github.ref }}
|
||||||
|
|
||||||
|
env:
|
||||||
|
ACT_OWNER: ${{ github.repository_owner }}
|
||||||
|
ACT_REPOSITORY: ${{ github.repository }}
|
||||||
|
CGO_ENABLED: 0
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
lint:
|
||||||
|
name: lint
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
- uses: actions/setup-go@v4
|
||||||
|
with:
|
||||||
|
go-version-file: go.mod
|
||||||
|
check-latest: true
|
||||||
|
- uses: golangci/golangci-lint-action@v3.7.0
|
||||||
|
with:
|
||||||
|
version: v1.53
|
||||||
|
only-new-issues: true
|
||||||
|
- uses: megalinter/megalinter/flavors/go@v7.4.0
|
||||||
|
env:
|
||||||
|
DEFAULT_BRANCH: master
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
VALIDATE_ALL_CODEBASE: false
|
||||||
|
GITHUB_STATUS_REPORTER: ${{ !env.ACT }}
|
||||||
|
GITHUB_COMMENT_REPORTER: ${{ !env.ACT }}
|
||||||
|
|
||||||
|
test-linux:
|
||||||
|
name: test-linux
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
fetch-depth: 2
|
||||||
|
- name: Set up QEMU
|
||||||
|
uses: docker/setup-qemu-action@v3
|
||||||
|
- uses: actions/setup-go@v4
|
||||||
|
with:
|
||||||
|
go-version-file: go.mod
|
||||||
|
check-latest: true
|
||||||
|
- uses: actions/cache@v3
|
||||||
|
if: ${{ !env.ACT }}
|
||||||
|
with:
|
||||||
|
path: ~/go/pkg/mod
|
||||||
|
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-go-
|
||||||
|
- name: Run Tests
|
||||||
|
uses: ./.github/actions/run-tests
|
||||||
|
with:
|
||||||
|
upload-logs-name: logs-linux
|
||||||
|
- 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
|
||||||
|
- name: Upload Codecov report
|
||||||
|
uses: codecov/codecov-action@v3.1.4
|
||||||
|
with:
|
||||||
|
files: coverage.txt
|
||||||
|
fail_ci_if_error: true # optional (default = false)
|
||||||
|
|
||||||
|
test-host:
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
os:
|
||||||
|
- windows-latest
|
||||||
|
- macos-latest
|
||||||
|
name: test-${{matrix.os}}
|
||||||
|
runs-on: ${{matrix.os}}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
fetch-depth: 2
|
||||||
|
- uses: actions/setup-go@v4
|
||||||
|
with:
|
||||||
|
go-version-file: go.mod
|
||||||
|
check-latest: true
|
||||||
|
- name: Run Tests
|
||||||
|
uses: ./.github/actions/run-tests
|
||||||
|
with:
|
||||||
|
filter: '^TestRunEventHostEnvironment$'
|
||||||
|
upload-logs-name: logs-${{ matrix.os }}
|
||||||
|
|
||||||
|
snapshot:
|
||||||
|
name: snapshot
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- uses: actions/setup-go@v4
|
||||||
|
with:
|
||||||
|
go-version-file: go.mod
|
||||||
|
check-latest: true
|
||||||
|
- uses: actions/cache@v3
|
||||||
|
if: ${{ !env.ACT }}
|
||||||
|
with:
|
||||||
|
path: ~/go/pkg/mod
|
||||||
|
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-go-
|
||||||
|
- name: GoReleaser
|
||||||
|
uses: goreleaser/goreleaser-action@v5
|
||||||
|
with:
|
||||||
|
version: latest
|
||||||
|
args: release --snapshot --clean
|
||||||
|
- name: Capture x86_64 (64-bit) Linux binary
|
||||||
|
if: ${{ !env.ACT }}
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: act-linux-amd64
|
||||||
|
path: dist/act_linux_amd64_v1/act
|
||||||
|
- name: Capture i386 (32-bit) Linux binary
|
||||||
|
if: ${{ !env.ACT }}
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: act-linux-i386
|
||||||
|
path: dist/act_linux_386/act
|
||||||
|
- name: Capture arm64 (64-bit) Linux binary
|
||||||
|
if: ${{ !env.ACT }}
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: act-linux-arm64
|
||||||
|
path: dist/act_linux_arm64/act
|
||||||
|
- name: Capture armv6 (32-bit) Linux binary
|
||||||
|
if: ${{ !env.ACT }}
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: act-linux-armv6
|
||||||
|
path: dist/act_linux_arm_6/act
|
||||||
|
- name: Capture armv7 (32-bit) Linux binary
|
||||||
|
if: ${{ !env.ACT }}
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: act-linux-armv7
|
||||||
|
path: dist/act_linux_arm_7/act
|
||||||
|
- name: Capture x86_64 (64-bit) Windows binary
|
||||||
|
if: ${{ !env.ACT }}
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: act-windows-amd64
|
||||||
|
path: dist/act_windows_amd64_v1/act.exe
|
||||||
|
- name: Capture i386 (32-bit) Windows binary
|
||||||
|
if: ${{ !env.ACT }}
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: act-windows-i386
|
||||||
|
path: dist/act_windows_386/act.exe
|
||||||
|
- name: Capture arm64 (64-bit) Windows binary
|
||||||
|
if: ${{ !env.ACT }}
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: act-windows-arm64
|
||||||
|
path: dist/act_windows_arm64/act.exe
|
||||||
|
- name: Capture armv7 (32-bit) Windows binary
|
||||||
|
if: ${{ !env.ACT }}
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: act-windows-armv7
|
||||||
|
path: dist/act_windows_arm_7/act.exe
|
||||||
|
- name: Capture x86_64 (64-bit) MacOS binary
|
||||||
|
if: ${{ !env.ACT }}
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: act-macos-amd64
|
||||||
|
path: dist/act_darwin_amd64_v1/act
|
||||||
|
- name: Capture arm64 (64-bit) MacOS binary
|
||||||
|
if: ${{ !env.ACT }}
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: act-macos-arm64
|
||||||
|
path: dist/act_darwin_arm64/act
|
||||||
|
- name: Chocolatey
|
||||||
|
uses: ./.github/actions/choco
|
||||||
|
with:
|
||||||
|
version: v0.0.0-pr
|
29
.github/workflows/promote.yml
vendored
Normal file
29
.github/workflows/promote.yml
vendored
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
name: promote
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: '0 2 1 * *'
|
||||||
|
workflow_dispatch: {}
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
release:
|
||||||
|
name: promote
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
ref: master
|
||||||
|
token: ${{ secrets.GORELEASER_GITHUB_TOKEN }}
|
||||||
|
- uses: fregante/setup-git-user@v2
|
||||||
|
- uses: actions/setup-go@v4
|
||||||
|
with:
|
||||||
|
go-version-file: go.mod
|
||||||
|
check-latest: true
|
||||||
|
- uses: actions/cache@v3
|
||||||
|
if: ${{ !env.ACT }}
|
||||||
|
with:
|
||||||
|
path: ~/go/pkg/mod
|
||||||
|
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-go-
|
||||||
|
- run: make promote
|
61
.github/workflows/release.yml
vendored
Normal file
61
.github/workflows/release.yml
vendored
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
name: release
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- v*
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
release:
|
||||||
|
name: release
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
- uses: actions/setup-go@v4
|
||||||
|
with:
|
||||||
|
go-version-file: go.mod
|
||||||
|
check-latest: true
|
||||||
|
- uses: actions/cache@v3
|
||||||
|
if: ${{ !env.ACT }}
|
||||||
|
with:
|
||||||
|
path: ~/go/pkg/mod
|
||||||
|
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-go-
|
||||||
|
- name: GoReleaser
|
||||||
|
uses: goreleaser/goreleaser-action@v5
|
||||||
|
with:
|
||||||
|
version: latest
|
||||||
|
args: release --clean
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GORELEASER_GITHUB_TOKEN }}
|
||||||
|
- name: Winget
|
||||||
|
uses: vedantmgoyal2009/winget-releaser@v2
|
||||||
|
with:
|
||||||
|
identifier: nektos.act
|
||||||
|
installers-regex: '_Windows_\w+\.zip$'
|
||||||
|
token: ${{ secrets.WINGET_TOKEN }}
|
||||||
|
- name: Chocolatey
|
||||||
|
uses: ./.github/actions/choco
|
||||||
|
with:
|
||||||
|
version: ${{ github.ref }}
|
||||||
|
apiKey: ${{ secrets.CHOCO_APIKEY }}
|
||||||
|
push: true
|
||||||
|
- name: GitHub CLI extension
|
||||||
|
uses: actions/github-script@v6
|
||||||
|
with:
|
||||||
|
github-token: ${{ secrets.GORELEASER_GITHUB_TOKEN }}
|
||||||
|
script: |
|
||||||
|
const mainRef = (await github.rest.git.getRef({
|
||||||
|
owner: 'nektos',
|
||||||
|
repo: 'gh-act',
|
||||||
|
ref: 'heads/main',
|
||||||
|
})).data;
|
||||||
|
console.log(mainRef);
|
||||||
|
github.rest.git.createRef({
|
||||||
|
owner: 'nektos',
|
||||||
|
repo: 'gh-act',
|
||||||
|
ref: context.ref,
|
||||||
|
sha: mainRef.object.sha,
|
||||||
|
});
|
23
.github/workflows/stale.yml
vendored
Normal file
23
.github/workflows/stale.yml
vendored
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
name: 'Close stale issues'
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: '0 0 * * *'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
stale:
|
||||||
|
name: Stale
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/stale@v8
|
||||||
|
with:
|
||||||
|
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
stale-issue-message: 'Issue is stale and will be closed in 14 days unless there is new activity'
|
||||||
|
stale-pr-message: 'PR is stale and will be closed in 14 days unless there is new activity'
|
||||||
|
stale-issue-label: 'stale'
|
||||||
|
exempt-issue-labels: 'stale-exempt,kind/feature-request'
|
||||||
|
stale-pr-label: 'stale'
|
||||||
|
exempt-pr-labels: 'stale-exempt'
|
||||||
|
remove-stale-when-updated: 'True'
|
||||||
|
operations-per-run: 500
|
||||||
|
days-before-stale: 180
|
||||||
|
days-before-close: 14
|
|
@ -71,10 +71,6 @@ pull_request_rules:
|
||||||
- and:
|
- and:
|
||||||
- 'approved-reviews-by=@nektos/act-maintainers'
|
- 'approved-reviews-by=@nektos/act-maintainers'
|
||||||
- '#approved-reviews-by>=2'
|
- '#approved-reviews-by>=2'
|
||||||
- and:
|
|
||||||
- 'author=@nektos/act-maintainers'
|
|
||||||
- 'approved-reviews-by=@nektos/act-maintainers'
|
|
||||||
- '#approved-reviews-by>=1'
|
|
||||||
- -draft
|
- -draft
|
||||||
- -merged
|
- -merged
|
||||||
- -closed
|
- -closed
|
||||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
||||||
0.2.59
|
0.2.52
|
|
@ -55,10 +55,7 @@ type Input struct {
|
||||||
replaceGheActionTokenWithGithubCom string
|
replaceGheActionTokenWithGithubCom string
|
||||||
matrix []string
|
matrix []string
|
||||||
actionCachePath string
|
actionCachePath string
|
||||||
actionOfflineMode bool
|
|
||||||
logPrefixJobID bool
|
logPrefixJobID bool
|
||||||
networkName string
|
|
||||||
useNewActionCache bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Input) resolve(path string) string {
|
func (i *Input) resolve(path string) string {
|
||||||
|
|
|
@ -15,7 +15,7 @@ func (i *Input) newPlatforms() map[string]string {
|
||||||
for _, p := range i.platforms {
|
for _, p := range i.platforms {
|
||||||
pParts := strings.Split(p, "=")
|
pParts := strings.Split(p, "=")
|
||||||
if len(pParts) == 2 {
|
if len(pParts) == 2 {
|
||||||
platforms[strings.ToLower(pParts[0])] = pParts[1]
|
platforms[pParts[0]] = pParts[1]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return platforms
|
return platforms
|
||||||
|
|
54
cmd/root.go
54
cmd/root.go
|
@ -14,7 +14,6 @@ import (
|
||||||
"github.com/AlecAivazis/survey/v2"
|
"github.com/AlecAivazis/survey/v2"
|
||||||
"github.com/adrg/xdg"
|
"github.com/adrg/xdg"
|
||||||
"github.com/andreaskoch/go-fswatch"
|
"github.com/andreaskoch/go-fswatch"
|
||||||
docker_container "github.com/docker/docker/api/types/container"
|
|
||||||
"github.com/joho/godotenv"
|
"github.com/joho/godotenv"
|
||||||
gitignore "github.com/sabhiram/go-gitignore"
|
gitignore "github.com/sabhiram/go-gitignore"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
|
@ -97,9 +96,6 @@ func Execute(ctx context.Context, version string) {
|
||||||
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.PersistentFlags().StringVarP(&input.actionCachePath, "action-cache-path", "", filepath.Join(CacheHomeDir, "act"), "Defines the path where the actions get cached and host workspaces created.")
|
||||||
rootCmd.PersistentFlags().BoolVarP(&input.actionOfflineMode, "action-offline-mode", "", false, "If action contents exists, it will not be fetch and pull again. If turn on this,will turn off force pull")
|
|
||||||
rootCmd.PersistentFlags().StringVarP(&input.networkName, "network", "", "host", "Sets a docker network name. Defaults to host.")
|
|
||||||
rootCmd.PersistentFlags().BoolVarP(&input.useNewActionCache, "use-new-action-cache", "", false, "Enable using the new Action Cache for storing Actions locally")
|
|
||||||
rootCmd.SetArgs(args())
|
rootCmd.SetArgs(args())
|
||||||
|
|
||||||
if err := rootCmd.Execute(); err != nil {
|
if err := rootCmd.Execute(); err != nil {
|
||||||
|
@ -107,22 +103,23 @@ func Execute(ctx context.Context, version string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return locations where Act's config can be found in order: XDG spec, .actrc in HOME directory, .actrc in invocation directory
|
|
||||||
func configLocations() []string {
|
func configLocations() []string {
|
||||||
configFileName := ".actrc"
|
configFileName := ".actrc"
|
||||||
|
|
||||||
homePath := filepath.Join(UserHomeDir, configFileName)
|
// reference: https://specifications.freedesktop.org/basedir-spec/latest/ar01s03.html
|
||||||
invocationPath := filepath.Join(".", configFileName)
|
var actrcXdg string
|
||||||
|
for _, fileName := range []string{"act/actrc", configFileName} {
|
||||||
// Though named xdg, adrg's lib support macOS and Windows config paths as well
|
if foundConfig, err := xdg.SearchConfigFile(fileName); foundConfig != "" && err == nil {
|
||||||
// It also takes cares of creating the parent folder so we don't need to bother later
|
actrcXdg = foundConfig
|
||||||
specPath, err := xdg.ConfigFile("act/actrc")
|
break
|
||||||
if err != nil {
|
}
|
||||||
specPath = homePath
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This order should be enforced since the survey part relies on it
|
return []string{
|
||||||
return []string{specPath, homePath, invocationPath}
|
filepath.Join(UserHomeDir, configFileName),
|
||||||
|
actrcXdg,
|
||||||
|
filepath.Join(".", configFileName),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var commonSocketPaths = []string{
|
var commonSocketPaths = []string{
|
||||||
|
@ -268,8 +265,7 @@ func readArgsFile(file string, split bool) []string {
|
||||||
}()
|
}()
|
||||||
scanner := bufio.NewScanner(f)
|
scanner := bufio.NewScanner(f)
|
||||||
for scanner.Scan() {
|
for scanner.Scan() {
|
||||||
arg := os.ExpandEnv(strings.TrimSpace(scanner.Text()))
|
arg := strings.TrimSpace(scanner.Text())
|
||||||
|
|
||||||
if strings.HasPrefix(arg, "-") && split {
|
if strings.HasPrefix(arg, "-") && split {
|
||||||
args = append(args, regexp.MustCompile(`\s`).Split(arg, 2)...)
|
args = append(args, regexp.MustCompile(`\s`).Split(arg, 2)...)
|
||||||
} else if !split {
|
} else if !split {
|
||||||
|
@ -295,8 +291,8 @@ func cleanup(inputs *Input) func(*cobra.Command, []string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseEnvs(env []string) map[string]string {
|
func parseEnvs(env []string, envs map[string]string) bool {
|
||||||
envs := make(map[string]string, len(env))
|
if env != nil {
|
||||||
for _, envVar := range env {
|
for _, envVar := range env {
|
||||||
e := strings.SplitN(envVar, `=`, 2)
|
e := strings.SplitN(envVar, `=`, 2)
|
||||||
if len(e) == 2 {
|
if len(e) == 2 {
|
||||||
|
@ -305,7 +301,9 @@ func parseEnvs(env []string) map[string]string {
|
||||||
envs[e[0]] = ""
|
envs[e[0]] = ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return envs
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func readYamlFile(file string) (map[string]string, error) {
|
func readYamlFile(file string) (map[string]string, error) {
|
||||||
|
@ -411,11 +409,13 @@ func newRunCommand(ctx context.Context, input *Input) func(*cobra.Command, []str
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debugf("Loading environment from %s", input.Envfile())
|
log.Debugf("Loading environment from %s", input.Envfile())
|
||||||
envs := parseEnvs(input.envs)
|
envs := make(map[string]string)
|
||||||
|
_ = parseEnvs(input.envs, envs)
|
||||||
_ = readEnvs(input.Envfile(), envs)
|
_ = readEnvs(input.Envfile(), envs)
|
||||||
|
|
||||||
log.Debugf("Loading action inputs from %s", input.Inputfile())
|
log.Debugf("Loading action inputs from %s", input.Inputfile())
|
||||||
inputs := parseEnvs(input.inputs)
|
inputs := make(map[string]string)
|
||||||
|
_ = parseEnvs(input.inputs, inputs)
|
||||||
_ = readEnvs(input.Inputfile(), inputs)
|
_ = readEnvs(input.Inputfile(), inputs)
|
||||||
|
|
||||||
log.Debugf("Loading secrets from %s", input.Secretfile())
|
log.Debugf("Loading secrets from %s", input.Secretfile())
|
||||||
|
@ -552,7 +552,6 @@ func newRunCommand(ctx context.Context, input *Input) func(*cobra.Command, []str
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !cfgFound && len(cfgLocations) > 0 {
|
if !cfgFound && len(cfgLocations) > 0 {
|
||||||
// The first config location refers to the global config folder one
|
|
||||||
if err := defaultImageSurvey(cfgLocations[0]); err != nil {
|
if err := defaultImageSurvey(cfgLocations[0]); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -579,12 +578,11 @@ func newRunCommand(ctx context.Context, input *Input) func(*cobra.Command, []str
|
||||||
EventName: eventName,
|
EventName: eventName,
|
||||||
EventPath: input.EventPath(),
|
EventPath: input.EventPath(),
|
||||||
DefaultBranch: defaultbranch,
|
DefaultBranch: defaultbranch,
|
||||||
ForcePull: !input.actionOfflineMode && input.forcePull,
|
ForcePull: input.forcePull,
|
||||||
ForceRebuild: input.forceRebuild,
|
ForceRebuild: input.forceRebuild,
|
||||||
ReuseContainers: input.reuseContainers,
|
ReuseContainers: input.reuseContainers,
|
||||||
Workdir: input.Workdir(),
|
Workdir: input.Workdir(),
|
||||||
ActionCacheDir: input.actionCachePath,
|
ActionCacheDir: input.actionCachePath,
|
||||||
ActionOfflineMode: input.actionOfflineMode,
|
|
||||||
BindWorkdir: input.bindWorkdir,
|
BindWorkdir: input.bindWorkdir,
|
||||||
LogOutput: !input.noOutput,
|
LogOutput: !input.noOutput,
|
||||||
JSONLogger: input.jsonLogger,
|
JSONLogger: input.jsonLogger,
|
||||||
|
@ -614,12 +612,6 @@ func newRunCommand(ctx context.Context, input *Input) func(*cobra.Command, []str
|
||||||
ReplaceGheActionWithGithubCom: input.replaceGheActionWithGithubCom,
|
ReplaceGheActionWithGithubCom: input.replaceGheActionWithGithubCom,
|
||||||
ReplaceGheActionTokenWithGithubCom: input.replaceGheActionTokenWithGithubCom,
|
ReplaceGheActionTokenWithGithubCom: input.replaceGheActionTokenWithGithubCom,
|
||||||
Matrix: matrixes,
|
Matrix: matrixes,
|
||||||
ContainerNetworkMode: docker_container.NetworkMode(input.networkName),
|
|
||||||
}
|
|
||||||
if input.useNewActionCache {
|
|
||||||
config.ActionCache = &runner.GoGitActionCache{
|
|
||||||
Path: config.ActionCacheDir,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
r, err := runner.New(config)
|
r, err := runner.New(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
76
go.mod
76
go.mod
|
@ -1,102 +1,92 @@
|
||||||
module github.com/nektos/act
|
module github.com/nektos/act
|
||||||
|
|
||||||
go 1.21.13
|
go 1.20
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/AlecAivazis/survey/v2 v2.3.7
|
github.com/AlecAivazis/survey/v2 v2.3.7
|
||||||
|
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.21
|
github.com/creack/pty v1.1.18
|
||||||
github.com/docker/cli v25.0.3+incompatible
|
github.com/docker/cli v24.0.6+incompatible
|
||||||
github.com/docker/distribution v2.8.3+incompatible
|
github.com/docker/distribution v2.8.3+incompatible
|
||||||
github.com/docker/docker v25.0.6+incompatible
|
github.com/docker/docker v24.0.6+incompatible // 24.0 branch
|
||||||
github.com/docker/go-connections v0.5.0
|
github.com/docker/go-connections v0.4.0
|
||||||
github.com/go-git/go-billy/v5 v5.5.0
|
github.com/go-git/go-billy/v5 v5.5.0
|
||||||
github.com/go-git/go-git/v5 v5.11.0
|
github.com/go-git/go-git/v5 v5.9.0
|
||||||
|
github.com/gobwas/glob v0.2.3
|
||||||
github.com/imdario/mergo v0.3.16
|
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.20
|
github.com/mattn/go-isatty v0.0.19
|
||||||
github.com/moby/buildkit v0.13.2
|
github.com/moby/buildkit v0.12.2
|
||||||
github.com/moby/patternmatcher v0.6.0
|
github.com/moby/patternmatcher v0.6.0
|
||||||
github.com/opencontainers/image-spec v1.1.0-rc5
|
github.com/opencontainers/image-spec v1.1.0-rc5
|
||||||
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.27
|
github.com/rhysd/actionlint v1.6.26
|
||||||
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.3
|
github.com/sirupsen/logrus v1.9.3
|
||||||
github.com/spf13/cobra v1.8.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.4
|
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.9
|
go.etcd.io/bbolt v1.3.7
|
||||||
golang.org/x/term v0.18.0
|
golang.org/x/term v0.13.0
|
||||||
gopkg.in/yaml.v3 v3.0.1
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
gotest.tools/v3 v3.5.1
|
gotest.tools/v3 v3.5.1
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
|
||||||
github.com/Masterminds/semver v1.5.0
|
|
||||||
github.com/gobwas/glob v0.2.3
|
|
||||||
)
|
|
||||||
|
|
||||||
require (
|
require (
|
||||||
dario.cat/mergo v1.0.0 // indirect
|
dario.cat/mergo v1.0.0 // indirect
|
||||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
|
|
||||||
github.com/Microsoft/go-winio v0.6.1 // indirect
|
github.com/Microsoft/go-winio v0.6.1 // indirect
|
||||||
github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 // indirect
|
github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 // indirect
|
||||||
github.com/cloudflare/circl v1.3.7 // indirect
|
github.com/acomagu/bufpipe v1.0.4 // indirect
|
||||||
github.com/containerd/containerd v1.7.13 // indirect
|
github.com/cloudflare/circl v1.3.3 // indirect
|
||||||
github.com/containerd/log v0.1.0 // indirect
|
github.com/containerd/containerd v1.7.2 // indirect
|
||||||
github.com/cyphar/filepath-securejoin v0.2.4 // indirect
|
github.com/cyphar/filepath-securejoin v0.2.4 // indirect
|
||||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
github.com/distribution/reference v0.5.0 // indirect
|
github.com/distribution/reference v0.5.0 // indirect
|
||||||
github.com/docker/docker-credential-helpers v0.8.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.16.0 // indirect
|
github.com/fatih/color v1.15.0 // indirect
|
||||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
|
||||||
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
|
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
|
||||||
github.com/go-logr/logr v1.3.0 // indirect
|
|
||||||
github.com/go-logr/stdr v1.2.2 // 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/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||||
github.com/google/go-cmp v0.6.0 // 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.17.4 // 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.15 // indirect
|
github.com/mattn/go-runewidth v0.0.15 // indirect
|
||||||
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect
|
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect
|
||||||
github.com/mitchellh/mapstructure v1.1.2 // indirect
|
github.com/mitchellh/mapstructure v1.1.2 // indirect
|
||||||
github.com/moby/sys/sequential v0.5.0 // indirect
|
github.com/moby/sys/sequential v0.5.0 // indirect
|
||||||
github.com/moby/sys/user v0.1.0 // 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.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.7 // indirect
|
github.com/rivo/uniseg v0.4.4 // indirect
|
||||||
github.com/robfig/cron/v3 v3.0.1 // indirect
|
github.com/robfig/cron/v3 v3.0.1 // indirect
|
||||||
github.com/sergi/go-diff v1.2.0 // indirect
|
github.com/sergi/go-diff v1.2.0 // indirect
|
||||||
github.com/skeema/knownhosts v1.2.1 // 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-20190905194746-02993c407bfb // 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
|
||||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 // indirect
|
golang.org/x/crypto v0.13.0 // indirect
|
||||||
go.opentelemetry.io/otel v1.21.0 // indirect
|
golang.org/x/mod v0.12.0 // indirect
|
||||||
go.opentelemetry.io/otel/metric v1.21.0 // indirect
|
golang.org/x/net v0.15.0 // indirect
|
||||||
go.opentelemetry.io/otel/trace v1.21.0 // indirect
|
golang.org/x/sync v0.3.0 // indirect
|
||||||
golang.org/x/crypto v0.21.0 // indirect
|
golang.org/x/sys v0.13.0 // indirect
|
||||||
golang.org/x/mod v0.13.0 // indirect
|
golang.org/x/text v0.13.0 // indirect
|
||||||
golang.org/x/net v0.23.0 // indirect
|
golang.org/x/tools v0.13.0 // indirect
|
||||||
golang.org/x/sync v0.6.0 // indirect
|
|
||||||
golang.org/x/sys v0.18.0 // indirect
|
|
||||||
golang.org/x/text v0.14.0 // indirect
|
|
||||||
golang.org/x/tools v0.14.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
|
||||||
)
|
)
|
||||||
|
|
198
go.sum
198
go.sum
|
@ -1,44 +1,37 @@
|
||||||
dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk=
|
dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk=
|
||||||
dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
|
dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
|
||||||
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9vkmnHYOMsOr4WLk+Vo07yKIzd94sVoIqshQ4bU=
|
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230106234847-43070de90fa1 h1:EKPd1INOIyr5hWOWhvpmQpY6tKjeG0hT1s3AMC/9fic=
|
||||||
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8=
|
|
||||||
github.com/AlecAivazis/survey/v2 v2.3.7 h1:6I/u8FvytdGsgonrYsVn2t8t4QiRnh6QSTqkkhIiSjQ=
|
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/AlecAivazis/survey/v2 v2.3.7/go.mod h1:xUTIdE4KCOIjsBAE1JYsUPoCqYdZ1reCfTwbto0Fduo=
|
||||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8=
|
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8=
|
||||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
|
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
|
||||||
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/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
|
github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
|
||||||
github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=
|
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/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
|
||||||
github.com/Microsoft/hcsshim v0.11.4 h1:68vKo2VN8DE9AdN4tnkWnmdhqdbpUFM8OF3Airm7fz8=
|
github.com/Microsoft/hcsshim v0.10.0-rc.8 h1:YSZVvlIIDD1UxQpJp0h+dnpLUw+TrY0cx8obKsp3bek=
|
||||||
github.com/Microsoft/hcsshim v0.11.4/go.mod h1:smjE4dvqPX9Zldna+t5FG3rnoHhaB7QYxPRqGcpAD9w=
|
|
||||||
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-20230828082145-3c4c8a2d2371 h1:kkhsdkhsCvIsutKu5zLMgWtgh9YxGCNAw8Ad8hjwfYg=
|
github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 h1:kkhsdkhsCvIsutKu5zLMgWtgh9YxGCNAw8Ad8hjwfYg=
|
||||||
github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0=
|
github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0=
|
||||||
|
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/adrg/xdg v0.4.0 h1:RzRqFcjH4nE5C6oTAxhBtoE2IRyjBSa62SCbyPidvls=
|
github.com/adrg/xdg v0.4.0 h1:RzRqFcjH4nE5C6oTAxhBtoE2IRyjBSa62SCbyPidvls=
|
||||||
github.com/adrg/xdg v0.4.0/go.mod h1:N6ag73EX4wyxeaoeHctc1mas01KZgsj5tYiAIwqJE/E=
|
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.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
|
||||||
github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM=
|
github.com/cloudflare/circl v1.3.3 h1:fE/Qz0QdIGqeWfnwq0RE0R7MI51s0M2E4Ga9kq5AEMs=
|
||||||
github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
|
|
||||||
github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA=
|
github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA=
|
||||||
github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU=
|
github.com/containerd/containerd v1.7.2 h1:UF2gdONnxO8I6byZXDi5sXWiWvlW3D/sci7dTQimEJo=
|
||||||
github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA=
|
github.com/containerd/containerd v1.7.2/go.mod h1:afcz74+K10M/+cjGHIVQrCt3RAQhUSCAjJ9iMYhhkuI=
|
||||||
github.com/containerd/containerd v1.7.13 h1:wPYKIeGMN8vaggSKuV1X0wZulpMz4CrgEsZdaCyB6Is=
|
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||||
github.com/containerd/containerd v1.7.13/go.mod h1:zT3up6yTRfEUa6+GsITYIJNgSVL9NQ4x4h1RPzk0Wu4=
|
|
||||||
github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I=
|
|
||||||
github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo=
|
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
|
||||||
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.21 h1:1/QdRyBaHHJP61QkWMXlOIBfsgdDeeKfK8SYVUWJKf0=
|
github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
|
||||||
github.com/creack/pty v1.1.21/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
|
github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
|
||||||
github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg=
|
github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg=
|
||||||
github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
|
github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
|
||||||
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=
|
||||||
|
@ -46,55 +39,43 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK2OFGvA0=
|
github.com/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK2OFGvA0=
|
||||||
github.com/distribution/reference v0.5.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
|
github.com/distribution/reference v0.5.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
|
||||||
github.com/docker/cli v25.0.3+incompatible h1:KLeNs7zws74oFuVhgZQ5ONGZiXUUdgsdy6/EsX/6284=
|
github.com/docker/cli v24.0.6+incompatible h1:fF+XCQCgJjjQNIMjzaSmiKJSCcfcXb3TWTcc7GAneOY=
|
||||||
github.com/docker/cli v25.0.3+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
github.com/docker/cli v24.0.6+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||||
github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk=
|
github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk=
|
||||||
github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||||
github.com/docker/docker v25.0.6+incompatible h1:5cPwbwriIcsua2REJe8HqQV+6WlWc1byg2QSXzBxBGg=
|
github.com/docker/docker v24.0.6+incompatible h1:hceabKCtUgDqPu+qm0NgsaXf28Ljf4/pWFL7xjWWDgE=
|
||||||
github.com/docker/docker v25.0.6+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
github.com/docker/docker v24.0.6+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||||
github.com/docker/docker-credential-helpers v0.8.0 h1:YQFtbBQb4VrpoPxhFuzEBPQ9E16qz5SpHLS+uswaCp8=
|
github.com/docker/docker-credential-helpers v0.7.0 h1:xtCHsjxogADNZcdv1pKUHXryefjlVRqWqIhk/uXJp0A=
|
||||||
github.com/docker/docker-credential-helpers v0.8.0/go.mod h1:UGFXcuoQ5TxPiB54nHOZ32AWRqQdECoh/Mg0AlEYb40=
|
github.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0=
|
||||||
github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c=
|
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
|
||||||
github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc=
|
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
|
||||||
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-20230808193330-2592e75ae04a h1:mATvB/9r/3gvcejNsXKSkQ6lcIaNec2nyfOdlTBR2lU=
|
github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a h1:mATvB/9r/3gvcejNsXKSkQ6lcIaNec2nyfOdlTBR2lU=
|
||||||
github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM=
|
|
||||||
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.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
|
github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs=
|
||||||
github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
|
github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw=
|
||||||
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
|
|
||||||
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
|
||||||
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.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI=
|
||||||
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic=
|
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic=
|
||||||
github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU=
|
github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU=
|
||||||
github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow=
|
github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow=
|
||||||
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4=
|
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20230305113008-0c11038e723f h1:Pz0DHeFij3XFhoBRGUDPzSJ+w2UcK5/0JvF8DRI58r8=
|
||||||
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII=
|
github.com/go-git/go-git/v5 v5.9.0 h1:cD9SFA7sHVRdJ7AYck1ZaAa/yeuBvGPxwXDL8cxrObY=
|
||||||
github.com/go-git/go-git/v5 v5.11.0 h1:XIZc1p+8YzypNr34itUfSvYJcv+eYdTnTvOZ2vD3cA4=
|
github.com/go-git/go-git/v5 v5.9.0/go.mod h1:RKIqga24sWdMGZF+1Ekv9kylsDz6LzdTSI2s/OsZWE0=
|
||||||
github.com/go-git/go-git/v5 v5.11.0/go.mod h1:6GFcX2P3NM7FPBfpePbpLd21XxsgdAt+lKqXmCUiUCY=
|
|
||||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
|
||||||
github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY=
|
|
||||||
github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
|
||||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
|
||||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
|
||||||
github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
|
github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
|
||||||
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
|
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
|
||||||
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/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
|
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/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||||
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
|
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||||
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||||
github.com/google/go-cmp v0.6.0/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/grpc-ecosystem/grpc-gateway/v2 v2.16.0 h1:YBftPWNWd4WwGqtY2yeZL2ef8rHAxPBD8KFhJpmcqms=
|
|
||||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg=
|
|
||||||
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.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4=
|
github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4=
|
||||||
|
@ -113,78 +94,80 @@ 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.17.4 h1:Ej5ixsIri7BrIjBkRZLTo6ghwrEtHFk7ijlczPW4fZ4=
|
github.com/klauspost/compress v1.16.3 h1:XuJt9zzcnaz6a16/OU53ZjWp/v7/42WcR5t2a0PcNQY=
|
||||||
github.com/klauspost/compress v1.17.4/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM=
|
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/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.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
|
||||||
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=
|
||||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
github.com/matryer/is v1.2.0 h1:92UTHpy8CDwaJ08GqLDzhhuixiBUUD1p3AU6PHddz4A=
|
||||||
|
github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA=
|
||||||
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||||
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.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
|
||||||
github.com/mattn/go-isatty v0.0.20/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.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
|
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
|
||||||
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
github.com/mattn/go-runewidth v0.0.15/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/moby/buildkit v0.13.2 h1:nXNszM4qD9E7QtG7bFWPnDI1teUQFQglBzon/IU3SzI=
|
github.com/moby/buildkit v0.12.2 h1:B7guBgY6sfk4dBlv/ORUxyYlp0UojYaYyATgtNwSCXc=
|
||||||
github.com/moby/buildkit v0.13.2/go.mod h1:2cyVOv9NoHM7arphK9ZfHIWKn9YVZRFd1wXB8kKmEzY=
|
github.com/moby/buildkit v0.12.2/go.mod h1:adB4y0SxxX8trnrY+oEulb48ODLqPO6pKMF0ppGcCoI=
|
||||||
github.com/moby/patternmatcher v0.6.0 h1:GmP9lR19aU5GqSSFko+5pRqHi+Ohk1O69aFiKkVGiPk=
|
github.com/moby/patternmatcher v0.6.0 h1:GmP9lR19aU5GqSSFko+5pRqHi+Ohk1O69aFiKkVGiPk=
|
||||||
github.com/moby/patternmatcher v0.6.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc=
|
github.com/moby/patternmatcher v0.6.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc=
|
||||||
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/sys/user v0.1.0 h1:WmZ93f5Ux6het5iituh9x2zAG7NFY9Aqi49jjE1PaQg=
|
github.com/moby/term v0.0.0-20200312100748-672ec06f55cd h1:aY7OQNf2XqY/JQ6qREWamhI/81os/agb2BAGpcx5yWI=
|
||||||
github.com/moby/sys/user v0.1.0/go.mod h1:fKJhFOnsCN6xZ5gSfbM6zaHGgDJMrqt9/reuj4T7MmU=
|
github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo=
|
||||||
github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0=
|
|
||||||
github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=
|
|
||||||
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
|
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
|
||||||
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
|
|
||||||
github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI=
|
github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI=
|
||||||
github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M=
|
|
||||||
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-rc5 h1:Ygwkfw9bpDvs+c9E34SdgGOj41dX/cbdlwvlWt0pnFI=
|
github.com/opencontainers/image-spec v1.1.0-rc5 h1:Ygwkfw9bpDvs+c9E34SdgGOj41dX/cbdlwvlWt0pnFI=
|
||||||
github.com/opencontainers/image-spec v1.1.0-rc5/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8=
|
github.com/opencontainers/image-spec v1.1.0-rc5/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8=
|
||||||
|
github.com/opencontainers/runc v1.1.7 h1:y2EZDS8sNng4Ksf0GUYNhKbTShZJPJg1FiXJNH/uoCk=
|
||||||
|
github.com/opencontainers/runc v1.1.7/go.mod h1:CbUumNnWCuTGFukNXahoo/RFBZvDAgRh/smNYNOhA50=
|
||||||
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=
|
||||||
github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI=
|
github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI=
|
||||||
|
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
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.27 h1:xxwe8YmveBcC8lydW6GoHMGmB6H/MTqUU60F2p10wjw=
|
github.com/rhysd/actionlint v1.6.26 h1:zi7jPZf3Ks14gCXYAAL47uBziyFlX7+Xwilqhexct9g=
|
||||||
github.com/rhysd/actionlint v1.6.27/go.mod h1:m2nFUjAnOrxCMXuOMz9evYBRCLUsMnKY2IJl/N5umbk=
|
github.com/rhysd/actionlint v1.6.26/go.mod h1:TIj1DlCgtYLOv5CH9wCK+WJTOr1qAdnFzkGi0IgSCO4=
|
||||||
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.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
|
github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis=
|
||||||
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
||||||
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
|
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
|
||||||
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
|
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
|
||||||
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
|
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
|
||||||
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
|
|
||||||
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/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/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.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||||
github.com/skeema/knownhosts v1.2.1 h1:SHWdIUa82uGZz+F+47k8SY4QhhI291cXCpopT1lK2AQ=
|
github.com/skeema/knownhosts v1.2.0 h1:h9r9cf0+u7wSE+M183ZtMGgOJKiL96brpaz5ekfJCpM=
|
||||||
github.com/skeema/knownhosts v1.2.1/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo=
|
github.com/skeema/knownhosts v1.2.0/go.mod h1:g4fPeYpque7P0xefxtGzV81ihjC8sX2IqpAoNkjxbMo=
|
||||||
github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0=
|
github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I=
|
||||||
github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho=
|
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.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||||
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
|
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
|
||||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||||
|
@ -201,9 +184,8 @@ github.com/timshannon/bolthold v0.0.0-20210913165410-232392fc8a6a h1:oIi7H/bwFUY
|
||||||
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/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/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||||
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo=
|
|
||||||
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
|
||||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
|
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
|
||||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
|
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
|
||||||
github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=
|
github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=
|
||||||
|
@ -212,24 +194,8 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
|
||||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||||
go.etcd.io/bbolt v1.3.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.9 h1:8x7aARPEXiXbHmtUwAIv7eV2fQFHrLLavdiJ3uzJXoI=
|
go.etcd.io/bbolt v1.3.7 h1:j+zJOnnEjF/kyHlDDgGnVL/AIqIJPq8UoB2GSNfkUfQ=
|
||||||
go.etcd.io/bbolt v1.3.9/go.mod h1:zaO32+Ti0PK1ivdPtgMESzuzL2VPoIG1PCQNvOdo/dE=
|
go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw=
|
||||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 h1:aFJWCqJMNjENlcleuuOkGAPH82y0yULBScfXcIEdS24=
|
|
||||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1/go.mod h1:sEGXWArGqc3tVa+ekntsN65DmVbVeW+7lTKTjZF3/Fo=
|
|
||||||
go.opentelemetry.io/otel v1.21.0 h1:hzLeKBZEL7Okw2mGzZ0cc4k/A7Fta0uoPgaJCr8fsFc=
|
|
||||||
go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo=
|
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 h1:cl5P5/GIfFh4t6xyruOgJP5QiA1pw4fYYdv6nc6CBWw=
|
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0/go.mod h1:zgBdWWAu7oEEMC06MMKc5NLbA/1YDXV1sMpSqEeLQLg=
|
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.21.0 h1:digkEZCJWobwBqMwC0cwCq8/wkkRy/OowZg5OArWZrM=
|
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.21.0/go.mod h1:/OpE/y70qVkndM0TrxT4KBoN3RsFZP0QaofcfYrj76I=
|
|
||||||
go.opentelemetry.io/otel/metric v1.21.0 h1:tlYWfeo+Bocx5kLEloTjbcDwBuELRrIFxwdQ36PlJu4=
|
|
||||||
go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM=
|
|
||||||
go.opentelemetry.io/otel/sdk v1.21.0 h1:FTt8qirL1EysG6sTQRZ5TokkU8d0ugCj8htOgThZXQ8=
|
|
||||||
go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E=
|
|
||||||
go.opentelemetry.io/otel/trace v1.21.0 h1:WD9i5gzvoUPuXIXH24ZNBudiarZDKuekPqi/E8fpfLc=
|
|
||||||
go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ=
|
|
||||||
go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I=
|
|
||||||
go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM=
|
|
||||||
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=
|
||||||
|
@ -237,14 +203,15 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y
|
||||||
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.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
|
golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
|
||||||
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
|
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
|
||||||
golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
|
golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck=
|
||||||
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
|
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
|
||||||
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.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||||
golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY=
|
golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
|
||||||
golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
golang.org/x/mod v0.12.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-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=
|
||||||
|
@ -255,26 +222,27 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug
|
||||||
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
|
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
|
||||||
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.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
|
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
|
||||||
golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs=
|
golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8=
|
||||||
golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
|
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
|
||||||
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/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
|
golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
|
||||||
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
|
||||||
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-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-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-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-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-20210616094352-59db8d763f22/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-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=
|
||||||
|
@ -284,15 +252,15 @@ golang.org/x/sys v0.2.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.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
|
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
|
||||||
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.13.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-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.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
|
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
|
||||||
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.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
|
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
|
||||||
golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8=
|
golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek=
|
||||||
golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=
|
golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
|
||||||
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=
|
||||||
|
@ -300,35 +268,25 @@ 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/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||||
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
|
||||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||||
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
|
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
|
||||||
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
|
||||||
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-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.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.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||||
golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc=
|
golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ=
|
||||||
golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg=
|
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
|
||||||
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/genproto v0.0.0-20231016165738-49dd2c1f3d0b h1:+YaDE2r2OG8t/z5qmsh7Y+XXwCbvadxxZ0YY6mTdrVA=
|
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20231016165738-49dd2c1f3d0b h1:CIC2YMXmIhYw6evmhPxBKJ4fmLbOFtXQN/GV3XOZR8k=
|
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20231016165738-49dd2c1f3d0b/go.mod h1:IBQ646DjkDkvUIsVq/cc03FUFQ9wbZu7yE396YcL870=
|
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20231016165738-49dd2c1f3d0b h1:ZlWIi1wSK56/8hn4QcBp/j9M7Gt3U/3hZw3mC7vDICo=
|
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20231016165738-49dd2c1f3d0b/go.mod h1:swOH3j0KzcDDgGUWr+SNpyTen5YrXjS3eyPzFYKc6lc=
|
|
||||||
google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk=
|
|
||||||
google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98=
|
|
||||||
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
|
|
||||||
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
|
||||||
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-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/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
|
gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
|
||||||
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
|
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
@ -338,5 +296,7 @@ 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.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/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
|
||||||
gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU=
|
gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU=
|
||||||
gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU=
|
gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU=
|
||||||
|
|
|
@ -9,7 +9,6 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"regexp"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
@ -387,12 +386,7 @@ func (h *Handler) findCache(db *bolthold.Store, keys []string, version string) (
|
||||||
|
|
||||||
for _, prefix := range keys[1:] {
|
for _, prefix := range keys[1:] {
|
||||||
found := false
|
found := false
|
||||||
prefixPattern := fmt.Sprintf("^%s", regexp.QuoteMeta(prefix))
|
if err := db.ForEach(bolthold.Where("Key").Ge(prefix).And("Version").Eq(version).SortBy("Key"), func(v *Cache) error {
|
||||||
re, err := regexp.Compile(prefixPattern)
|
|
||||||
if err != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if err := db.ForEach(bolthold.Where("Key").RegExp(re).And("Version").Eq(version).SortBy("CreatedAt").Reverse(), func(v *Cache) error {
|
|
||||||
if !strings.HasPrefix(v.Key, prefix) {
|
if !strings.HasPrefix(v.Key, prefix) {
|
||||||
return stop
|
return stop
|
||||||
}
|
}
|
||||||
|
|
|
@ -225,10 +225,6 @@ type NewGitCloneExecutorInput struct {
|
||||||
Ref string
|
Ref string
|
||||||
Dir string
|
Dir string
|
||||||
Token string
|
Token string
|
||||||
OfflineMode bool
|
|
||||||
|
|
||||||
// For Gitea
|
|
||||||
InsecureSkipTLS bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// CloneIfRequired ...
|
// CloneIfRequired ...
|
||||||
|
@ -250,8 +246,6 @@ func CloneIfRequired(ctx context.Context, refName plumbing.ReferenceName, input
|
||||||
cloneOptions := git.CloneOptions{
|
cloneOptions := git.CloneOptions{
|
||||||
URL: input.URL,
|
URL: input.URL,
|
||||||
Progress: progressWriter,
|
Progress: progressWriter,
|
||||||
|
|
||||||
InsecureSkipTLS: input.InsecureSkipTLS, // For Gitea
|
|
||||||
}
|
}
|
||||||
if input.Token != "" {
|
if input.Token != "" {
|
||||||
cloneOptions.Auth = &http.BasicAuth{
|
cloneOptions.Auth = &http.BasicAuth{
|
||||||
|
@ -308,22 +302,13 @@ func NewGitCloneExecutor(input NewGitCloneExecutorInput) common.Executor {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
isOfflineMode := input.OfflineMode
|
|
||||||
|
|
||||||
// fetch latest changes
|
// fetch latest changes
|
||||||
fetchOptions, pullOptions := gitOptions(input.Token)
|
fetchOptions, pullOptions := gitOptions(input.Token)
|
||||||
|
|
||||||
if input.InsecureSkipTLS { // For Gitea
|
|
||||||
fetchOptions.InsecureSkipTLS = true
|
|
||||||
pullOptions.InsecureSkipTLS = true
|
|
||||||
}
|
|
||||||
|
|
||||||
if !isOfflineMode {
|
|
||||||
err = r.Fetch(&fetchOptions)
|
err = r.Fetch(&fetchOptions)
|
||||||
if err != nil && !errors.Is(err, git.NoErrAlreadyUpToDate) {
|
if err != nil && !errors.Is(err, git.NoErrAlreadyUpToDate) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
var hash *plumbing.Hash
|
var hash *plumbing.Hash
|
||||||
rev := plumbing.Revision(input.Ref)
|
rev := plumbing.Revision(input.Ref)
|
||||||
|
@ -382,11 +367,10 @@ func NewGitCloneExecutor(input NewGitCloneExecutorInput) common.Executor {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !isOfflineMode {
|
|
||||||
if err = w.Pull(&pullOptions); err != nil && err != git.NoErrAlreadyUpToDate {
|
if err = w.Pull(&pullOptions); err != nil && err != git.NoErrAlreadyUpToDate {
|
||||||
logger.Debugf("Unable to pull %s: %v", refName, err)
|
logger.Debugf("Unable to pull %s: %v", refName, err)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
logger.Debugf("Cloned %s to %s", input.URL, input.Dir)
|
logger.Debugf("Cloned %s to %s", input.URL, input.Dir)
|
||||||
|
|
||||||
if hash.String() != input.Ref && refType == "branch" {
|
if hash.String() != input.Ref && refType == "branch" {
|
||||||
|
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/docker/go-connections/nat"
|
|
||||||
"github.com/nektos/act/pkg/common"
|
"github.com/nektos/act/pkg/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -27,13 +26,11 @@ type NewContainerInput struct {
|
||||||
UsernsMode string
|
UsernsMode string
|
||||||
Platform string
|
Platform string
|
||||||
Options string
|
Options string
|
||||||
NetworkAliases []string
|
|
||||||
ExposedPorts nat.PortSet
|
|
||||||
PortBindings nat.PortMap
|
|
||||||
|
|
||||||
// Gitea specific
|
// Gitea specific
|
||||||
AutoRemove bool
|
AutoRemove bool
|
||||||
|
|
||||||
|
NetworkAliases []string
|
||||||
ValidVolumes []string
|
ValidVolumes []string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
//go:build !(WITHOUT_DOCKER || !(linux || darwin || windows || netbsd))
|
//go:build !(WITHOUT_DOCKER || !(linux || darwin || windows))
|
||||||
|
|
||||||
package container
|
package container
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
//go:build !(WITHOUT_DOCKER || !(linux || darwin || windows || netbsd))
|
//go:build !(WITHOUT_DOCKER || !(linux || darwin || windows))
|
||||||
|
|
||||||
package container
|
package container
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
//go:build !(WITHOUT_DOCKER || !(linux || darwin || windows || netbsd))
|
//go:build !(WITHOUT_DOCKER || !(linux || darwin || windows))
|
||||||
|
|
||||||
// This file is exact copy of https://github.com/docker/cli/blob/9ac8584acfd501c3f4da0e845e3a40ed15c85041/cli/command/container/opts.go
|
// This file is exact copy of https://github.com/docker/cli/blob/9ac8584acfd501c3f4da0e845e3a40ed15c85041/cli/command/container/opts.go
|
||||||
// appended with license information.
|
// appended with license information.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
//go:build !(WITHOUT_DOCKER || !(linux || darwin || windows || netbsd))
|
//go:build !(WITHOUT_DOCKER || !(linux || darwin || windows))
|
||||||
|
|
||||||
package container
|
package container
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
//go:build !(WITHOUT_DOCKER || !(linux || darwin || windows || netbsd))
|
//go:build !(WITHOUT_DOCKER || !(linux || darwin || windows))
|
||||||
|
|
||||||
package container
|
package container
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
//go:build !(WITHOUT_DOCKER || !(linux || darwin || windows || netbsd))
|
//go:build !(WITHOUT_DOCKER || !(linux || darwin || windows))
|
||||||
|
|
||||||
package container
|
package container
|
||||||
|
|
||||||
|
@ -15,19 +15,6 @@ func NewDockerNetworkCreateExecutor(name string, config *types.NetworkCreate) co
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer cli.Close()
|
|
||||||
|
|
||||||
// Only create the network if it doesn't exist
|
|
||||||
networks, err := cli.NetworkList(ctx, types.NetworkListOptions{})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
for _, network := range networks {
|
|
||||||
if network.Name == name {
|
|
||||||
common.Logger(ctx).Debugf("Network %v exists", name)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = cli.NetworkCreate(ctx, name, *config)
|
_, err = cli.NetworkCreate(ctx, name, *config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -44,32 +31,7 @@ func NewDockerNetworkRemoveExecutor(name string) common.Executor {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer cli.Close()
|
|
||||||
|
|
||||||
// Make shure that all network of the specified name are removed
|
return cli.NetworkRemove(ctx, name)
|
||||||
// cli.NetworkRemove refuses to remove a network if there are duplicates
|
|
||||||
networks, err := cli.NetworkList(ctx, types.NetworkListOptions{})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
common.Logger(ctx).Debugf("%v", networks)
|
|
||||||
for _, network := range networks {
|
|
||||||
if network.Name == name {
|
|
||||||
result, err := cli.NetworkInspect(ctx, network.ID, types.NetworkInspectOptions{})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(result.Containers) == 0 {
|
|
||||||
if err = cli.NetworkRemove(ctx, network.ID); err != nil {
|
|
||||||
common.Logger(ctx).Debugf("%v", err)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
common.Logger(ctx).Debugf("Refusing to remove network %v because it still has active endpoints", name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
//go:build !(WITHOUT_DOCKER || !(linux || darwin || windows || netbsd))
|
//go:build !(WITHOUT_DOCKER || !(linux || darwin || windows))
|
||||||
|
|
||||||
package container
|
package container
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
//go:build !(WITHOUT_DOCKER || !(linux || darwin || windows || netbsd))
|
//go:build !(WITHOUT_DOCKER || !(linux || darwin || windows))
|
||||||
|
|
||||||
package container
|
package container
|
||||||
|
|
||||||
|
@ -38,7 +38,6 @@ import (
|
||||||
"golang.org/x/term"
|
"golang.org/x/term"
|
||||||
|
|
||||||
"github.com/nektos/act/pkg/common"
|
"github.com/nektos/act/pkg/common"
|
||||||
"github.com/nektos/act/pkg/filecollector"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewContainer creates a reference to a container
|
// NewContainer creates a reference to a container
|
||||||
|
@ -87,7 +86,7 @@ func supportsContainerImagePlatform(ctx context.Context, cli client.APIClient) b
|
||||||
|
|
||||||
func (cr *containerReference) Create(capAdd []string, capDrop []string) common.Executor {
|
func (cr *containerReference) Create(capAdd []string, capDrop []string) common.Executor {
|
||||||
return common.
|
return common.
|
||||||
NewInfoExecutor("%sdocker create image=%s platform=%s entrypoint=%+q cmd=%+q network=%+q", logPrefix, cr.input.Image, cr.input.Platform, cr.input.Entrypoint, cr.input.Cmd, cr.input.NetworkMode).
|
NewInfoExecutor("%sdocker create image=%s platform=%s entrypoint=%+q cmd=%+q", logPrefix, cr.input.Image, cr.input.Platform, cr.input.Entrypoint, cr.input.Cmd).
|
||||||
Then(
|
Then(
|
||||||
common.NewPipelineExecutor(
|
common.NewPipelineExecutor(
|
||||||
cr.connect(),
|
cr.connect(),
|
||||||
|
@ -99,7 +98,7 @@ func (cr *containerReference) Create(capAdd []string, capDrop []string) common.E
|
||||||
|
|
||||||
func (cr *containerReference) Start(attach bool) common.Executor {
|
func (cr *containerReference) Start(attach bool) common.Executor {
|
||||||
return common.
|
return common.
|
||||||
NewInfoExecutor("%sdocker run image=%s platform=%s entrypoint=%+q cmd=%+q network=%+q", logPrefix, cr.input.Image, cr.input.Platform, cr.input.Entrypoint, cr.input.Cmd, cr.input.NetworkMode).
|
NewInfoExecutor("%sdocker run image=%s platform=%s entrypoint=%+q cmd=%+q", logPrefix, cr.input.Image, cr.input.Platform, cr.input.Entrypoint, cr.input.Cmd).
|
||||||
Then(
|
Then(
|
||||||
common.NewPipelineExecutor(
|
common.NewPipelineExecutor(
|
||||||
cr.connect(),
|
cr.connect(),
|
||||||
|
@ -261,10 +260,8 @@ func RunnerArch(ctx context.Context) string {
|
||||||
|
|
||||||
archMapper := map[string]string{
|
archMapper := map[string]string{
|
||||||
"x86_64": "X64",
|
"x86_64": "X64",
|
||||||
"amd64": "X64",
|
|
||||||
"386": "X86",
|
"386": "X86",
|
||||||
"aarch64": "ARM64",
|
"aarch64": "ARM64",
|
||||||
"arm64": "ARM64",
|
|
||||||
}
|
}
|
||||||
if arch, ok := archMapper[info.Architecture]; ok {
|
if arch, ok := archMapper[info.Architecture]; ok {
|
||||||
return arch
|
return arch
|
||||||
|
@ -373,8 +370,8 @@ func (cr *containerReference) mergeContainerConfigs(ctx context.Context, config
|
||||||
// So comment out the following code.
|
// So comment out the following code.
|
||||||
|
|
||||||
// if len(copts.netMode.Value()) == 0 {
|
// if len(copts.netMode.Value()) == 0 {
|
||||||
// if err = copts.netMode.Set(cr.input.NetworkMode); err != nil {
|
// if err = copts.netMode.Set("host"); err != nil {
|
||||||
// return nil, nil, fmt.Errorf("Cannot parse networkmode=%s. This is an internal error and should not happen: '%w'", cr.input.NetworkMode, err)
|
// return nil, nil, fmt.Errorf("Cannot parse networkmode=host. This is an internal error and should not happen: '%w'", err)
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
@ -432,7 +429,6 @@ func (cr *containerReference) create(capAdd []string, capDrop []string) common.E
|
||||||
Image: input.Image,
|
Image: input.Image,
|
||||||
WorkingDir: input.WorkingDir,
|
WorkingDir: input.WorkingDir,
|
||||||
Env: input.Env,
|
Env: input.Env,
|
||||||
ExposedPorts: input.ExposedPorts,
|
|
||||||
Tty: isTerminal,
|
Tty: isTerminal,
|
||||||
}
|
}
|
||||||
logger.Debugf("Common container.Config ==> %+v", config)
|
logger.Debugf("Common container.Config ==> %+v", config)
|
||||||
|
@ -476,7 +472,6 @@ func (cr *containerReference) create(capAdd []string, capDrop []string) common.E
|
||||||
NetworkMode: container.NetworkMode(input.NetworkMode),
|
NetworkMode: container.NetworkMode(input.NetworkMode),
|
||||||
Privileged: input.Privileged,
|
Privileged: input.Privileged,
|
||||||
UsernsMode: container.UsernsMode(input.UsernsMode),
|
UsernsMode: container.UsernsMode(input.UsernsMode),
|
||||||
PortBindings: input.PortBindings,
|
|
||||||
AutoRemove: input.AutoRemove,
|
AutoRemove: input.AutoRemove,
|
||||||
}
|
}
|
||||||
logger.Debugf("Common container.HostConfig ==> %+v", hostConfig)
|
logger.Debugf("Common container.HostConfig ==> %+v", hostConfig)
|
||||||
|
@ -492,10 +487,7 @@ func (cr *containerReference) create(capAdd []string, capDrop []string) common.E
|
||||||
// For Gitea
|
// For Gitea
|
||||||
// network-scoped alias is supported only for containers in user defined networks
|
// network-scoped alias is supported only for containers in user defined networks
|
||||||
var networkingConfig *network.NetworkingConfig
|
var networkingConfig *network.NetworkingConfig
|
||||||
logger.Debugf("input.NetworkAliases ==> %v", input.NetworkAliases)
|
if hostConfig.NetworkMode.IsUserDefined() && len(input.NetworkAliases) > 0 {
|
||||||
n := hostConfig.NetworkMode
|
|
||||||
// IsUserDefined and IsHost are broken on windows
|
|
||||||
if n.IsUserDefined() && n != "host" && len(input.NetworkAliases) > 0 {
|
|
||||||
endpointConfig := &network.EndpointSettings{
|
endpointConfig := &network.EndpointSettings{
|
||||||
Aliases: input.NetworkAliases,
|
Aliases: input.NetworkAliases,
|
||||||
}
|
}
|
||||||
|
@ -717,28 +709,10 @@ func (cr *containerReference) waitForCommand(ctx context.Context, isTerminal boo
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cr *containerReference) CopyTarStream(ctx context.Context, destPath string, tarStream io.Reader) error {
|
func (cr *containerReference) CopyTarStream(ctx context.Context, destPath string, tarStream io.Reader) error {
|
||||||
// Mkdir
|
err := cr.cli.CopyToContainer(ctx, cr.id, destPath, tarStream, types.CopyToContainerOptions{})
|
||||||
buf := &bytes.Buffer{}
|
|
||||||
tw := tar.NewWriter(buf)
|
|
||||||
_ = tw.WriteHeader(&tar.Header{
|
|
||||||
Name: destPath,
|
|
||||||
Mode: 777,
|
|
||||||
Typeflag: tar.TypeDir,
|
|
||||||
})
|
|
||||||
tw.Close()
|
|
||||||
err := cr.cli.CopyToContainer(ctx, cr.id, "/", buf, types.CopyToContainerOptions{})
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed to mkdir to copy content to container: %w", err)
|
|
||||||
}
|
|
||||||
// Copy Content
|
|
||||||
err = cr.cli.CopyToContainer(ctx, cr.id, destPath, tarStream, types.CopyToContainerOptions{})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to copy content to container: %w", err)
|
return fmt.Errorf("failed to copy content to container: %w", err)
|
||||||
}
|
}
|
||||||
// If this fails, then folders have wrong permissions on non root container
|
|
||||||
if cr.UID != 0 || cr.GID != 0 {
|
|
||||||
_ = cr.Exec([]string{"chown", "-R", fmt.Sprintf("%d:%d", cr.UID, cr.GID), destPath}, nil, "0", "")(ctx)
|
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -779,12 +753,12 @@ func (cr *containerReference) copyDir(dstPath string, srcPath string, useGitIgno
|
||||||
ignorer = gitignore.NewMatcher(ps)
|
ignorer = gitignore.NewMatcher(ps)
|
||||||
}
|
}
|
||||||
|
|
||||||
fc := &filecollector.FileCollector{
|
fc := &fileCollector{
|
||||||
Fs: &filecollector.DefaultFs{},
|
Fs: &defaultFs{},
|
||||||
Ignorer: ignorer,
|
Ignorer: ignorer,
|
||||||
SrcPath: srcPath,
|
SrcPath: srcPath,
|
||||||
SrcPrefix: srcPrefix,
|
SrcPrefix: srcPrefix,
|
||||||
Handler: &filecollector.TarCollector{
|
Handler: &tarCollector{
|
||||||
TarWriter: tw,
|
TarWriter: tw,
|
||||||
UID: cr.UID,
|
UID: cr.UID,
|
||||||
GID: cr.GID,
|
GID: cr.GID,
|
||||||
|
@ -792,7 +766,7 @@ func (cr *containerReference) copyDir(dstPath string, srcPath string, useGitIgno
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
err = filepath.Walk(srcPath, fc.CollectFiles(ctx, []string{}))
|
err = filepath.Walk(srcPath, fc.collectFiles(ctx, []string{}))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,6 @@ func TestDocker(t *testing.T) {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
client, err := GetDockerClient(ctx)
|
client, err := GetDockerClient(ctx)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
defer client.Close()
|
|
||||||
|
|
||||||
dockerBuild := NewDockerBuildExecutor(NewDockerBuildExecutorInput{
|
dockerBuild := NewDockerBuildExecutor(NewDockerBuildExecutorInput{
|
||||||
ContextDir: "testdata",
|
ContextDir: "testdata",
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
//go:build WITHOUT_DOCKER || !(linux || darwin || windows || netbsd)
|
//go:build WITHOUT_DOCKER || !(linux || darwin || windows)
|
||||||
|
|
||||||
package container
|
package container
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ func NewDockerVolumeRemoveExecutor(volume string, force bool) common.Executor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDockerNetworkCreateExecutor(name string, config *types.NetworkCreate) common.Executor {
|
func NewDockerNetworkCreateExecutor(name string) common.Executor {
|
||||||
return func(ctx context.Context) error {
|
return func(ctx context.Context) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
//go:build !(WITHOUT_DOCKER || !(linux || darwin || windows || netbsd))
|
//go:build !(WITHOUT_DOCKER || !(linux || darwin || windows))
|
||||||
|
|
||||||
package container
|
package container
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package filecollector
|
package container
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"archive/tar"
|
"archive/tar"
|
||||||
|
@ -17,18 +17,18 @@ import (
|
||||||
"github.com/go-git/go-git/v5/plumbing/format/index"
|
"github.com/go-git/go-git/v5/plumbing/format/index"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Handler interface {
|
type fileCollectorHandler interface {
|
||||||
WriteFile(path string, fi fs.FileInfo, linkName string, f io.Reader) error
|
WriteFile(path string, fi fs.FileInfo, linkName string, f io.Reader) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type TarCollector struct {
|
type tarCollector struct {
|
||||||
TarWriter *tar.Writer
|
TarWriter *tar.Writer
|
||||||
UID int
|
UID int
|
||||||
GID int
|
GID int
|
||||||
DstDir string
|
DstDir string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tc TarCollector) WriteFile(fpath string, fi fs.FileInfo, linkName string, f io.Reader) error {
|
func (tc tarCollector) WriteFile(fpath string, fi fs.FileInfo, linkName string, f io.Reader) error {
|
||||||
// create a new dir/file header
|
// create a new dir/file header
|
||||||
header, err := tar.FileInfoHeader(fi, linkName)
|
header, err := tar.FileInfoHeader(fi, linkName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -59,11 +59,11 @@ func (tc TarCollector) WriteFile(fpath string, fi fs.FileInfo, linkName string,
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type CopyCollector struct {
|
type copyCollector struct {
|
||||||
DstDir string
|
DstDir string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cc *CopyCollector) WriteFile(fpath string, fi fs.FileInfo, linkName string, f io.Reader) error {
|
func (cc *copyCollector) WriteFile(fpath string, fi fs.FileInfo, linkName string, f io.Reader) error {
|
||||||
fdestpath := filepath.Join(cc.DstDir, fpath)
|
fdestpath := filepath.Join(cc.DstDir, fpath)
|
||||||
if err := os.MkdirAll(filepath.Dir(fdestpath), 0o777); err != nil {
|
if err := os.MkdirAll(filepath.Dir(fdestpath), 0o777); err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -82,29 +82,29 @@ func (cc *CopyCollector) WriteFile(fpath string, fi fs.FileInfo, linkName string
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type FileCollector struct {
|
type fileCollector struct {
|
||||||
Ignorer gitignore.Matcher
|
Ignorer gitignore.Matcher
|
||||||
SrcPath string
|
SrcPath string
|
||||||
SrcPrefix string
|
SrcPrefix string
|
||||||
Fs Fs
|
Fs fileCollectorFs
|
||||||
Handler Handler
|
Handler fileCollectorHandler
|
||||||
}
|
}
|
||||||
|
|
||||||
type Fs interface {
|
type fileCollectorFs interface {
|
||||||
Walk(root string, fn filepath.WalkFunc) error
|
Walk(root string, fn filepath.WalkFunc) error
|
||||||
OpenGitIndex(path string) (*index.Index, error)
|
OpenGitIndex(path string) (*index.Index, error)
|
||||||
Open(path string) (io.ReadCloser, error)
|
Open(path string) (io.ReadCloser, error)
|
||||||
Readlink(path string) (string, error)
|
Readlink(path string) (string, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type DefaultFs struct {
|
type defaultFs struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*DefaultFs) Walk(root string, fn filepath.WalkFunc) error {
|
func (*defaultFs) Walk(root string, fn filepath.WalkFunc) error {
|
||||||
return filepath.Walk(root, fn)
|
return filepath.Walk(root, fn)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*DefaultFs) OpenGitIndex(path string) (*index.Index, error) {
|
func (*defaultFs) OpenGitIndex(path string) (*index.Index, error) {
|
||||||
r, err := git.PlainOpen(path)
|
r, err := git.PlainOpen(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -116,16 +116,16 @@ func (*DefaultFs) OpenGitIndex(path string) (*index.Index, error) {
|
||||||
return i, nil
|
return i, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*DefaultFs) Open(path string) (io.ReadCloser, error) {
|
func (*defaultFs) Open(path string) (io.ReadCloser, error) {
|
||||||
return os.Open(path)
|
return os.Open(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*DefaultFs) Readlink(path string) (string, error) {
|
func (*defaultFs) Readlink(path string) (string, error) {
|
||||||
return os.Readlink(path)
|
return os.Readlink(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
//nolint:gocyclo
|
//nolint:gocyclo
|
||||||
func (fc *FileCollector) CollectFiles(ctx context.Context, submodulePath []string) filepath.WalkFunc {
|
func (fc *fileCollector) collectFiles(ctx context.Context, submodulePath []string) filepath.WalkFunc {
|
||||||
i, _ := fc.Fs.OpenGitIndex(path.Join(fc.SrcPath, path.Join(submodulePath...)))
|
i, _ := fc.Fs.OpenGitIndex(path.Join(fc.SrcPath, path.Join(submodulePath...)))
|
||||||
return func(file string, fi os.FileInfo, err error) error {
|
return func(file string, fi os.FileInfo, err error) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -166,7 +166,7 @@ func (fc *FileCollector) CollectFiles(ctx context.Context, submodulePath []strin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err == nil && entry.Mode == filemode.Submodule {
|
if err == nil && entry.Mode == filemode.Submodule {
|
||||||
err = fc.Fs.Walk(file, fc.CollectFiles(ctx, split))
|
err = fc.Fs.Walk(file, fc.collectFiles(ctx, split))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package filecollector
|
package container
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"archive/tar"
|
"archive/tar"
|
||||||
|
@ -95,16 +95,16 @@ func TestIgnoredTrackedfile(t *testing.T) {
|
||||||
tw := tar.NewWriter(tmpTar)
|
tw := tar.NewWriter(tmpTar)
|
||||||
ps, _ := gitignore.ReadPatterns(worktree, []string{})
|
ps, _ := gitignore.ReadPatterns(worktree, []string{})
|
||||||
ignorer := gitignore.NewMatcher(ps)
|
ignorer := gitignore.NewMatcher(ps)
|
||||||
fc := &FileCollector{
|
fc := &fileCollector{
|
||||||
Fs: &memoryFs{Filesystem: fs},
|
Fs: &memoryFs{Filesystem: fs},
|
||||||
Ignorer: ignorer,
|
Ignorer: ignorer,
|
||||||
SrcPath: "mygitrepo",
|
SrcPath: "mygitrepo",
|
||||||
SrcPrefix: "mygitrepo" + string(filepath.Separator),
|
SrcPrefix: "mygitrepo" + string(filepath.Separator),
|
||||||
Handler: &TarCollector{
|
Handler: &tarCollector{
|
||||||
TarWriter: tw,
|
TarWriter: tw,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
err := fc.Fs.Walk("mygitrepo", fc.CollectFiles(context.Background(), []string{}))
|
err := fc.Fs.Walk("mygitrepo", fc.collectFiles(context.Background(), []string{}))
|
||||||
assert.NoError(t, err, "successfully collect files")
|
assert.NoError(t, err, "successfully collect files")
|
||||||
tw.Close()
|
tw.Close()
|
||||||
_, _ = tmpTar.Seek(0, io.SeekStart)
|
_, _ = tmpTar.Seek(0, io.SeekStart)
|
||||||
|
@ -115,58 +115,3 @@ func TestIgnoredTrackedfile(t *testing.T) {
|
||||||
_, err = tr.Next()
|
_, err = tr.Next()
|
||||||
assert.ErrorIs(t, err, io.EOF, "tar must only contain one element")
|
assert.ErrorIs(t, err, io.EOF, "tar must only contain one element")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSymlinks(t *testing.T) {
|
|
||||||
fs := memfs.New()
|
|
||||||
_ = fs.MkdirAll("mygitrepo/.git", 0o777)
|
|
||||||
dotgit, _ := fs.Chroot("mygitrepo/.git")
|
|
||||||
worktree, _ := fs.Chroot("mygitrepo")
|
|
||||||
repo, _ := git.Init(filesystem.NewStorage(dotgit, cache.NewObjectLRUDefault()), worktree)
|
|
||||||
// This file shouldn't be in the tar
|
|
||||||
f, err := worktree.Create(".env")
|
|
||||||
assert.NoError(t, err)
|
|
||||||
_, err = f.Write([]byte("test=val1\n"))
|
|
||||||
assert.NoError(t, err)
|
|
||||||
f.Close()
|
|
||||||
err = worktree.Symlink(".env", "test.env")
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
w, err := repo.Worktree()
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
// .gitignore is in the tar after adding it to the index
|
|
||||||
_, err = w.Add(".env")
|
|
||||||
assert.NoError(t, err)
|
|
||||||
_, err = w.Add("test.env")
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
tmpTar, _ := fs.Create("temp.tar")
|
|
||||||
tw := tar.NewWriter(tmpTar)
|
|
||||||
ps, _ := gitignore.ReadPatterns(worktree, []string{})
|
|
||||||
ignorer := gitignore.NewMatcher(ps)
|
|
||||||
fc := &FileCollector{
|
|
||||||
Fs: &memoryFs{Filesystem: fs},
|
|
||||||
Ignorer: ignorer,
|
|
||||||
SrcPath: "mygitrepo",
|
|
||||||
SrcPrefix: "mygitrepo" + string(filepath.Separator),
|
|
||||||
Handler: &TarCollector{
|
|
||||||
TarWriter: tw,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
err = fc.Fs.Walk("mygitrepo", fc.CollectFiles(context.Background(), []string{}))
|
|
||||||
assert.NoError(t, err, "successfully collect files")
|
|
||||||
tw.Close()
|
|
||||||
_, _ = tmpTar.Seek(0, io.SeekStart)
|
|
||||||
tr := tar.NewReader(tmpTar)
|
|
||||||
h, err := tr.Next()
|
|
||||||
files := map[string]tar.Header{}
|
|
||||||
for err == nil {
|
|
||||||
files[h.Name] = *h
|
|
||||||
h, err = tr.Next()
|
|
||||||
}
|
|
||||||
|
|
||||||
assert.Equal(t, ".env", files[".env"].Name)
|
|
||||||
assert.Equal(t, "test.env", files["test.env"].Name)
|
|
||||||
assert.Equal(t, ".env", files["test.env"].Linkname)
|
|
||||||
assert.ErrorIs(t, err, io.EOF, "tar must be read cleanly to EOF")
|
|
||||||
}
|
|
|
@ -21,7 +21,6 @@ import (
|
||||||
"golang.org/x/term"
|
"golang.org/x/term"
|
||||||
|
|
||||||
"github.com/nektos/act/pkg/common"
|
"github.com/nektos/act/pkg/common"
|
||||||
"github.com/nektos/act/pkg/filecollector"
|
|
||||||
"github.com/nektos/act/pkg/lookpath"
|
"github.com/nektos/act/pkg/lookpath"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -75,7 +74,7 @@ func (e *HostEnvironment) CopyTarStream(ctx context.Context, destPath string, ta
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
tr := tar.NewReader(tarStream)
|
tr := tar.NewReader(tarStream)
|
||||||
cp := &filecollector.CopyCollector{
|
cp := ©Collector{
|
||||||
DstDir: destPath,
|
DstDir: destPath,
|
||||||
}
|
}
|
||||||
for {
|
for {
|
||||||
|
@ -114,16 +113,16 @@ func (e *HostEnvironment) CopyDir(destPath, srcPath string, useGitIgnore bool) c
|
||||||
|
|
||||||
ignorer = gitignore.NewMatcher(ps)
|
ignorer = gitignore.NewMatcher(ps)
|
||||||
}
|
}
|
||||||
fc := &filecollector.FileCollector{
|
fc := &fileCollector{
|
||||||
Fs: &filecollector.DefaultFs{},
|
Fs: &defaultFs{},
|
||||||
Ignorer: ignorer,
|
Ignorer: ignorer,
|
||||||
SrcPath: srcPath,
|
SrcPath: srcPath,
|
||||||
SrcPrefix: srcPrefix,
|
SrcPrefix: srcPrefix,
|
||||||
Handler: &filecollector.CopyCollector{
|
Handler: ©Collector{
|
||||||
DstDir: destPath,
|
DstDir: destPath,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
return filepath.Walk(srcPath, fc.CollectFiles(ctx, []string{}))
|
return filepath.Walk(srcPath, fc.collectFiles(ctx, []string{}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,21 +135,21 @@ func (e *HostEnvironment) GetContainerArchive(ctx context.Context, srcPath strin
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
tc := &filecollector.TarCollector{
|
tc := &tarCollector{
|
||||||
TarWriter: tw,
|
TarWriter: tw,
|
||||||
}
|
}
|
||||||
if fi.IsDir() {
|
if fi.IsDir() {
|
||||||
srcPrefix := srcPath
|
srcPrefix := filepath.Dir(srcPath)
|
||||||
if !strings.HasSuffix(srcPrefix, string(filepath.Separator)) {
|
if !strings.HasSuffix(srcPrefix, string(filepath.Separator)) {
|
||||||
srcPrefix += string(filepath.Separator)
|
srcPrefix += string(filepath.Separator)
|
||||||
}
|
}
|
||||||
fc := &filecollector.FileCollector{
|
fc := &fileCollector{
|
||||||
Fs: &filecollector.DefaultFs{},
|
Fs: &defaultFs{},
|
||||||
SrcPath: srcPath,
|
SrcPath: srcPath,
|
||||||
SrcPrefix: srcPrefix,
|
SrcPrefix: srcPrefix,
|
||||||
Handler: tc,
|
Handler: tc,
|
||||||
}
|
}
|
||||||
err = filepath.Walk(srcPath, fc.CollectFiles(ctx, []string{}))
|
err = filepath.Walk(srcPath, fc.collectFiles(ctx, []string{}))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,71 +1,4 @@
|
||||||
package container
|
package container
|
||||||
|
|
||||||
import (
|
|
||||||
"archive/tar"
|
|
||||||
"context"
|
|
||||||
"io"
|
|
||||||
"os"
|
|
||||||
"path"
|
|
||||||
"path/filepath"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Type assert HostEnvironment implements ExecutionsEnvironment
|
// Type assert HostEnvironment implements ExecutionsEnvironment
|
||||||
var _ ExecutionsEnvironment = &HostEnvironment{}
|
var _ ExecutionsEnvironment = &HostEnvironment{}
|
||||||
|
|
||||||
func TestCopyDir(t *testing.T) {
|
|
||||||
dir, err := os.MkdirTemp("", "test-host-env-*")
|
|
||||||
assert.NoError(t, err)
|
|
||||||
defer os.RemoveAll(dir)
|
|
||||||
ctx := context.Background()
|
|
||||||
e := &HostEnvironment{
|
|
||||||
Path: filepath.Join(dir, "path"),
|
|
||||||
TmpDir: filepath.Join(dir, "tmp"),
|
|
||||||
ToolCache: filepath.Join(dir, "tool_cache"),
|
|
||||||
ActPath: filepath.Join(dir, "act_path"),
|
|
||||||
StdOut: os.Stdout,
|
|
||||||
Workdir: path.Join("testdata", "scratch"),
|
|
||||||
}
|
|
||||||
_ = os.MkdirAll(e.Path, 0700)
|
|
||||||
_ = os.MkdirAll(e.TmpDir, 0700)
|
|
||||||
_ = os.MkdirAll(e.ToolCache, 0700)
|
|
||||||
_ = os.MkdirAll(e.ActPath, 0700)
|
|
||||||
err = e.CopyDir(e.Workdir, e.Path, true)(ctx)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGetContainerArchive(t *testing.T) {
|
|
||||||
dir, err := os.MkdirTemp("", "test-host-env-*")
|
|
||||||
assert.NoError(t, err)
|
|
||||||
defer os.RemoveAll(dir)
|
|
||||||
ctx := context.Background()
|
|
||||||
e := &HostEnvironment{
|
|
||||||
Path: filepath.Join(dir, "path"),
|
|
||||||
TmpDir: filepath.Join(dir, "tmp"),
|
|
||||||
ToolCache: filepath.Join(dir, "tool_cache"),
|
|
||||||
ActPath: filepath.Join(dir, "act_path"),
|
|
||||||
StdOut: os.Stdout,
|
|
||||||
Workdir: path.Join("testdata", "scratch"),
|
|
||||||
}
|
|
||||||
_ = os.MkdirAll(e.Path, 0700)
|
|
||||||
_ = os.MkdirAll(e.TmpDir, 0700)
|
|
||||||
_ = os.MkdirAll(e.ToolCache, 0700)
|
|
||||||
_ = os.MkdirAll(e.ActPath, 0700)
|
|
||||||
expectedContent := []byte("sdde/7sh")
|
|
||||||
err = os.WriteFile(filepath.Join(e.Path, "action.yml"), expectedContent, 0600)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
archive, err := e.GetContainerArchive(ctx, e.Path)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
defer archive.Close()
|
|
||||||
reader := tar.NewReader(archive)
|
|
||||||
h, err := reader.Next()
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.Equal(t, "action.yml", h.Name)
|
|
||||||
content, err := io.ReadAll(reader)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.Equal(t, expectedContent, content)
|
|
||||||
_, err = reader.Next()
|
|
||||||
assert.ErrorIs(t, err, io.EOF)
|
|
||||||
}
|
|
||||||
|
|
1
pkg/container/testdata/scratch/test.txt
vendored
1
pkg/container/testdata/scratch/test.txt
vendored
|
@ -1 +0,0 @@
|
||||||
testfile
|
|
|
@ -43,9 +43,6 @@ func TestFunctionContains(t *testing.T) {
|
||||||
assert.Equal(t, tt.expected, output)
|
assert.Equal(t, tt.expected, output)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := NewInterpeter(env, Config{}).Evaluate("contains('one')", DefaultStatusCheckNone)
|
|
||||||
assert.Error(t, err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFunctionStartsWith(t *testing.T) {
|
func TestFunctionStartsWith(t *testing.T) {
|
||||||
|
@ -75,9 +72,6 @@ func TestFunctionStartsWith(t *testing.T) {
|
||||||
assert.Equal(t, tt.expected, output)
|
assert.Equal(t, tt.expected, output)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := NewInterpeter(env, Config{}).Evaluate("startsWith('one')", DefaultStatusCheckNone)
|
|
||||||
assert.Error(t, err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFunctionEndsWith(t *testing.T) {
|
func TestFunctionEndsWith(t *testing.T) {
|
||||||
|
@ -107,9 +101,6 @@ func TestFunctionEndsWith(t *testing.T) {
|
||||||
assert.Equal(t, tt.expected, output)
|
assert.Equal(t, tt.expected, output)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := NewInterpeter(env, Config{}).Evaluate("endsWith('one')", DefaultStatusCheckNone)
|
|
||||||
assert.Error(t, err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFunctionJoin(t *testing.T) {
|
func TestFunctionJoin(t *testing.T) {
|
||||||
|
@ -137,9 +128,6 @@ func TestFunctionJoin(t *testing.T) {
|
||||||
assert.Equal(t, tt.expected, output)
|
assert.Equal(t, tt.expected, output)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := NewInterpeter(env, Config{}).Evaluate("join()", DefaultStatusCheckNone)
|
|
||||||
assert.Error(t, err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFunctionToJSON(t *testing.T) {
|
func TestFunctionToJSON(t *testing.T) {
|
||||||
|
@ -166,9 +154,6 @@ func TestFunctionToJSON(t *testing.T) {
|
||||||
assert.Equal(t, tt.expected, output)
|
assert.Equal(t, tt.expected, output)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := NewInterpeter(env, Config{}).Evaluate("tojson()", DefaultStatusCheckNone)
|
|
||||||
assert.Error(t, err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFunctionFromJSON(t *testing.T) {
|
func TestFunctionFromJSON(t *testing.T) {
|
||||||
|
@ -192,9 +177,6 @@ func TestFunctionFromJSON(t *testing.T) {
|
||||||
assert.Equal(t, tt.expected, output)
|
assert.Equal(t, tt.expected, output)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := NewInterpeter(env, Config{}).Evaluate("fromjson()", DefaultStatusCheckNone)
|
|
||||||
assert.Error(t, err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFunctionHashFiles(t *testing.T) {
|
func TestFunctionHashFiles(t *testing.T) {
|
||||||
|
@ -248,7 +230,6 @@ func TestFunctionFormat(t *testing.T) {
|
||||||
{"format('{0', '{1}', 'World')", nil, "Unclosed brackets. The following format string is invalid: '{0'", "format-invalid-format-string"},
|
{"format('{0', '{1}', 'World')", nil, "Unclosed brackets. The following format string is invalid: '{0'", "format-invalid-format-string"},
|
||||||
{"format('{2}', '{1}', 'World')", "", "The following format string references more arguments than were supplied: '{2}'", "format-invalid-replacement-reference"},
|
{"format('{2}', '{1}', 'World')", "", "The following format string references more arguments than were supplied: '{2}'", "format-invalid-replacement-reference"},
|
||||||
{"format('{2147483648}')", "", "The following format string is invalid: '{2147483648}'", "format-invalid-replacement-reference"},
|
{"format('{2147483648}')", "", "The following format string is invalid: '{2147483648}'", "format-invalid-replacement-reference"},
|
||||||
{"format('{0} {1} {2} {3}', 1.0, 1.1, 1234567890.0, 12345678901234567890.0)", "1 1.1 1234567890 1.23456789012346E+19", nil, "format-floats"},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
env := &EvaluationEnvironment{
|
env := &EvaluationEnvironment{
|
||||||
|
@ -266,7 +247,4 @@ func TestFunctionFormat(t *testing.T) {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := NewInterpeter(env, Config{}).Evaluate("format()", DefaultStatusCheckNone)
|
|
||||||
assert.Error(t, err)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -157,8 +157,6 @@ func (impl *interperterImpl) evaluateVariable(variableNode *actionlint.VariableN
|
||||||
return impl.env.Github, nil
|
return impl.env.Github, nil
|
||||||
case "gitea": // compatible with Gitea
|
case "gitea": // compatible with Gitea
|
||||||
return impl.env.Github, nil
|
return impl.env.Github, nil
|
||||||
case "forge":
|
|
||||||
return impl.env.Github, nil
|
|
||||||
case "env":
|
case "env":
|
||||||
return impl.env.Env, nil
|
return impl.env.Env, nil
|
||||||
case "job":
|
case "job":
|
||||||
|
@ -451,7 +449,7 @@ func (impl *interperterImpl) coerceToString(value reflect.Value) reflect.Value {
|
||||||
} else if math.IsInf(value.Float(), -1) {
|
} else if math.IsInf(value.Float(), -1) {
|
||||||
return reflect.ValueOf("-Infinity")
|
return reflect.ValueOf("-Infinity")
|
||||||
}
|
}
|
||||||
return reflect.ValueOf(fmt.Sprintf("%.15G", value.Float()))
|
return reflect.ValueOf(fmt.Sprint(value))
|
||||||
|
|
||||||
case reflect.Slice:
|
case reflect.Slice:
|
||||||
return reflect.ValueOf("Array")
|
return reflect.ValueOf("Array")
|
||||||
|
@ -593,58 +591,23 @@ func (impl *interperterImpl) evaluateFuncCall(funcCallNode *actionlint.FuncCallN
|
||||||
args = append(args, reflect.ValueOf(value))
|
args = append(args, reflect.ValueOf(value))
|
||||||
}
|
}
|
||||||
|
|
||||||
argCountCheck := func(argCount int) error {
|
|
||||||
if len(args) != argCount {
|
|
||||||
return fmt.Errorf("'%s' expected %d arguments but got %d instead", funcCallNode.Callee, argCount, len(args))
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
argAtLeastCheck := func(atLeast int) error {
|
|
||||||
if len(args) < atLeast {
|
|
||||||
return fmt.Errorf("'%s' expected at least %d arguments but got %d instead", funcCallNode.Callee, atLeast, len(args))
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
switch strings.ToLower(funcCallNode.Callee) {
|
switch strings.ToLower(funcCallNode.Callee) {
|
||||||
case "contains":
|
case "contains":
|
||||||
if err := argCountCheck(2); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return impl.contains(args[0], args[1])
|
return impl.contains(args[0], args[1])
|
||||||
case "startswith":
|
case "startswith":
|
||||||
if err := argCountCheck(2); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return impl.startsWith(args[0], args[1])
|
return impl.startsWith(args[0], args[1])
|
||||||
case "endswith":
|
case "endswith":
|
||||||
if err := argCountCheck(2); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return impl.endsWith(args[0], args[1])
|
return impl.endsWith(args[0], args[1])
|
||||||
case "format":
|
case "format":
|
||||||
if err := argAtLeastCheck(1); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return impl.format(args[0], args[1:]...)
|
return impl.format(args[0], args[1:]...)
|
||||||
case "join":
|
case "join":
|
||||||
if err := argAtLeastCheck(1); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if len(args) == 1 {
|
if len(args) == 1 {
|
||||||
return impl.join(args[0], reflect.ValueOf(","))
|
return impl.join(args[0], reflect.ValueOf(","))
|
||||||
}
|
}
|
||||||
return impl.join(args[0], args[1])
|
return impl.join(args[0], args[1])
|
||||||
case "tojson":
|
case "tojson":
|
||||||
if err := argCountCheck(1); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return impl.toJSON(args[0])
|
return impl.toJSON(args[0])
|
||||||
case "fromjson":
|
case "fromjson":
|
||||||
if err := argCountCheck(1); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return impl.fromJSON(args[0])
|
return impl.fromJSON(args[0])
|
||||||
case "hashfiles":
|
case "hashfiles":
|
||||||
if impl.env.HashFiles != nil {
|
if impl.env.HashFiles != nil {
|
||||||
|
|
|
@ -15,7 +15,6 @@ func NewInterpeter(
|
||||||
matrix map[string]interface{},
|
matrix map[string]interface{},
|
||||||
gitCtx *model.GithubContext,
|
gitCtx *model.GithubContext,
|
||||||
results map[string]*JobResult,
|
results map[string]*JobResult,
|
||||||
vars map[string]string,
|
|
||||||
) exprparser.Interpreter {
|
) exprparser.Interpreter {
|
||||||
strategy := make(map[string]interface{})
|
strategy := make(map[string]interface{})
|
||||||
if job.Strategy != nil {
|
if job.Strategy != nil {
|
||||||
|
@ -63,7 +62,6 @@ func NewInterpeter(
|
||||||
Matrix: matrix,
|
Matrix: matrix,
|
||||||
Needs: using,
|
Needs: using,
|
||||||
Inputs: nil, // not supported yet
|
Inputs: nil, // not supported yet
|
||||||
Vars: vars,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
config := exprparser.Config{
|
config := exprparser.Config{
|
||||||
|
|
|
@ -48,15 +48,12 @@ func Parse(content []byte, options ...ParseOption) ([]*SingleWorkflow, error) {
|
||||||
}
|
}
|
||||||
for _, matrix := range matricxes {
|
for _, matrix := range matricxes {
|
||||||
job := job.Clone()
|
job := job.Clone()
|
||||||
evaluator := NewExpressionEvaluator(NewInterpeter(id, origin.GetJob(id), matrix, pc.gitContext, results, pc.vars))
|
|
||||||
if job.Name == "" {
|
if job.Name == "" {
|
||||||
job.Name = nameWithMatrix(id, matrix)
|
job.Name = id
|
||||||
} else {
|
|
||||||
job.Name = evaluator.Interpolate(job.Name)
|
|
||||||
}
|
}
|
||||||
|
job.Name = nameWithMatrix(job.Name, matrix)
|
||||||
job.Strategy.RawMatrix = encodeMatrix(matrix)
|
job.Strategy.RawMatrix = encodeMatrix(matrix)
|
||||||
|
evaluator := NewExpressionEvaluator(NewInterpeter(id, origin.GetJob(id), matrix, pc.gitContext, results))
|
||||||
runsOn := origin.GetJob(id).RunsOn()
|
runsOn := origin.GetJob(id).RunsOn()
|
||||||
for i, v := range runsOn {
|
for i, v := range runsOn {
|
||||||
runsOn[i] = evaluator.Interpolate(v)
|
runsOn[i] = evaluator.Interpolate(v)
|
||||||
|
@ -89,16 +86,9 @@ func WithGitContext(context *model.GithubContext) ParseOption {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func WithVars(vars map[string]string) ParseOption {
|
|
||||||
return func(c *parseContext) {
|
|
||||||
c.vars = vars
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type parseContext struct {
|
type parseContext struct {
|
||||||
jobResults map[string]string
|
jobResults map[string]string
|
||||||
gitContext *model.GithubContext
|
gitContext *model.GithubContext
|
||||||
vars map[string]string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type ParseOption func(c *parseContext)
|
type ParseOption func(c *parseContext)
|
||||||
|
|
|
@ -17,11 +17,6 @@ func TestParse(t *testing.T) {
|
||||||
options []ParseOption
|
options []ParseOption
|
||||||
wantErr bool
|
wantErr bool
|
||||||
}{
|
}{
|
||||||
{
|
|
||||||
name: "multiple_named_matrix",
|
|
||||||
options: nil,
|
|
||||||
wantErr: false,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: "multiple_jobs",
|
name: "multiple_jobs",
|
||||||
options: nil,
|
options: nil,
|
||||||
|
|
|
@ -259,11 +259,6 @@ func ParseRawOn(rawOn *yaml.Node) ([]*Event, error) {
|
||||||
return nil, fmt.Errorf("unknown on type: %#v", branches)
|
return nil, fmt.Errorf("unknown on type: %#v", branches)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case map[string]interface{}:
|
|
||||||
if k != "workflow_dispatch" || act != "inputs" {
|
|
||||||
return nil, fmt.Errorf("unknown on type: %#v", v)
|
|
||||||
}
|
|
||||||
acts = nil
|
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("unknown on type: %#v", branches)
|
return nil, fmt.Errorf("unknown on type: %#v", branches)
|
||||||
}
|
}
|
||||||
|
|
|
@ -186,14 +186,6 @@ func TestParseRawOn(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
input: "on:\n workflow_dispatch:\n inputs:\n test:\n type: string",
|
|
||||||
result: []*Event{
|
|
||||||
{
|
|
||||||
Name: "workflow_dispatch",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
for _, kase := range kases {
|
for _, kase := range kases {
|
||||||
t.Run(kase.input, func(t *testing.T) {
|
t.Run(kase.input, func(t *testing.T) {
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
name: test
|
|
||||||
jobs:
|
|
||||||
job1:
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
os: [ubuntu-22.04, ubuntu-20.04]
|
|
||||||
version: [1.17, 1.18, 1.19]
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
name: On ${{ matrix.os }} with go v${{ matrix.version }}
|
|
||||||
steps:
|
|
||||||
- uses: actions/setup-go@v3
|
|
||||||
with:
|
|
||||||
go-version: ${{ matrix.version }}
|
|
||||||
- run: uname -a && go version
|
|
|
@ -1,101 +0,0 @@
|
||||||
name: test
|
|
||||||
jobs:
|
|
||||||
job1:
|
|
||||||
name: On ubuntu-20.04 with go v1.17
|
|
||||||
runs-on: ubuntu-20.04
|
|
||||||
steps:
|
|
||||||
- uses: actions/setup-go@v3
|
|
||||||
with:
|
|
||||||
go-version: ${{ matrix.version }}
|
|
||||||
- run: uname -a && go version
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
os:
|
|
||||||
- ubuntu-20.04
|
|
||||||
version:
|
|
||||||
- 1.17
|
|
||||||
---
|
|
||||||
name: test
|
|
||||||
jobs:
|
|
||||||
job1:
|
|
||||||
name: On ubuntu-20.04 with go v1.18
|
|
||||||
runs-on: ubuntu-20.04
|
|
||||||
steps:
|
|
||||||
- uses: actions/setup-go@v3
|
|
||||||
with:
|
|
||||||
go-version: ${{ matrix.version }}
|
|
||||||
- run: uname -a && go version
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
os:
|
|
||||||
- ubuntu-20.04
|
|
||||||
version:
|
|
||||||
- 1.18
|
|
||||||
---
|
|
||||||
name: test
|
|
||||||
jobs:
|
|
||||||
job1:
|
|
||||||
name: On ubuntu-20.04 with go v1.19
|
|
||||||
runs-on: ubuntu-20.04
|
|
||||||
steps:
|
|
||||||
- uses: actions/setup-go@v3
|
|
||||||
with:
|
|
||||||
go-version: ${{ matrix.version }}
|
|
||||||
- run: uname -a && go version
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
os:
|
|
||||||
- ubuntu-20.04
|
|
||||||
version:
|
|
||||||
- 1.19
|
|
||||||
---
|
|
||||||
name: test
|
|
||||||
jobs:
|
|
||||||
job1:
|
|
||||||
name: On ubuntu-22.04 with go v1.17
|
|
||||||
runs-on: ubuntu-22.04
|
|
||||||
steps:
|
|
||||||
- uses: actions/setup-go@v3
|
|
||||||
with:
|
|
||||||
go-version: ${{ matrix.version }}
|
|
||||||
- run: uname -a && go version
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
os:
|
|
||||||
- ubuntu-22.04
|
|
||||||
version:
|
|
||||||
- 1.17
|
|
||||||
---
|
|
||||||
name: test
|
|
||||||
jobs:
|
|
||||||
job1:
|
|
||||||
name: On ubuntu-22.04 with go v1.18
|
|
||||||
runs-on: ubuntu-22.04
|
|
||||||
steps:
|
|
||||||
- uses: actions/setup-go@v3
|
|
||||||
with:
|
|
||||||
go-version: ${{ matrix.version }}
|
|
||||||
- run: uname -a && go version
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
os:
|
|
||||||
- ubuntu-22.04
|
|
||||||
version:
|
|
||||||
- 1.18
|
|
||||||
---
|
|
||||||
name: test
|
|
||||||
jobs:
|
|
||||||
job1:
|
|
||||||
name: On ubuntu-22.04 with go v1.19
|
|
||||||
runs-on: ubuntu-22.04
|
|
||||||
steps:
|
|
||||||
- uses: actions/setup-go@v3
|
|
||||||
with:
|
|
||||||
go-version: ${{ matrix.version }}
|
|
||||||
- run: uname -a && go version
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
os:
|
|
||||||
- ubuntu-22.04
|
|
||||||
version:
|
|
||||||
- 1.19
|
|
|
@ -168,7 +168,7 @@ func (ghc *GithubContext) SetRepositoryAndOwner(ctx context.Context, githubInsta
|
||||||
if ghc.Repository == "" {
|
if ghc.Repository == "" {
|
||||||
repo, err := git.FindGithubRepo(ctx, repoPath, githubInstance, remoteName)
|
repo, err := git.FindGithubRepo(ctx, repoPath, githubInstance, remoteName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
common.Logger(ctx).Warningf("unable to get git repo (githubInstance: %v; remoteName: %v, repoPath: %v): %v", githubInstance, remoteName, repoPath, err)
|
common.Logger(ctx).Warningf("unable to get git repo: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ghc.Repository = repo
|
ghc.Repository = repo
|
||||||
|
|
|
@ -148,10 +148,12 @@ func NewWorkflowPlanner(path string, noWorkflowRecurse bool) (WorkflowPlanner, e
|
||||||
workflow.Name = wf.workflowDirEntry.Name()
|
workflow.Name = wf.workflowDirEntry.Name()
|
||||||
}
|
}
|
||||||
|
|
||||||
err = validateJobName(workflow)
|
jobNameRegex := regexp.MustCompile(`^([[:alpha:]_][[:alnum:]_\-]*)$`)
|
||||||
if err != nil {
|
for k := range workflow.Jobs {
|
||||||
|
if ok := jobNameRegex.MatchString(k); !ok {
|
||||||
_ = f.Close()
|
_ = f.Close()
|
||||||
return nil, err
|
return nil, fmt.Errorf("workflow is not valid. '%s': Job name '%s' is invalid. Names must start with a letter or '_' and contain only alphanumeric characters, '-', or '_'", workflow.Name, k)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wp.workflows = append(wp.workflows, workflow)
|
wp.workflows = append(wp.workflows, workflow)
|
||||||
|
@ -169,42 +171,6 @@ func CombineWorkflowPlanner(workflows ...*Workflow) WorkflowPlanner {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSingleWorkflowPlanner(name string, f io.Reader) (WorkflowPlanner, error) {
|
|
||||||
wp := new(workflowPlanner)
|
|
||||||
|
|
||||||
log.Debugf("Reading workflow %s", name)
|
|
||||||
workflow, err := ReadWorkflow(f)
|
|
||||||
if err != nil {
|
|
||||||
if err == io.EOF {
|
|
||||||
return nil, fmt.Errorf("unable to read workflow '%s': file is empty: %w", name, err)
|
|
||||||
}
|
|
||||||
return nil, fmt.Errorf("workflow is not valid. '%s': %w", name, err)
|
|
||||||
}
|
|
||||||
workflow.File = name
|
|
||||||
if workflow.Name == "" {
|
|
||||||
workflow.Name = name
|
|
||||||
}
|
|
||||||
|
|
||||||
err = validateJobName(workflow)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
wp.workflows = append(wp.workflows, workflow)
|
|
||||||
|
|
||||||
return wp, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func validateJobName(workflow *Workflow) error {
|
|
||||||
jobNameRegex := regexp.MustCompile(`^([[:alpha:]_][[:alnum:]_\-]*)$`)
|
|
||||||
for k := range workflow.Jobs {
|
|
||||||
if ok := jobNameRegex.MatchString(k); !ok {
|
|
||||||
return fmt.Errorf("workflow is not valid. '%s': Job name '%s' is invalid. Names must start with a letter or '_' and contain only alphanumeric characters, '-', or '_'", workflow.Name, k)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type workflowPlanner struct {
|
type workflowPlanner struct {
|
||||||
workflows []*Workflow
|
workflows []*Workflow
|
||||||
}
|
}
|
||||||
|
|
|
@ -103,40 +103,22 @@ type WorkflowDispatch struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *Workflow) WorkflowDispatchConfig() *WorkflowDispatch {
|
func (w *Workflow) WorkflowDispatchConfig() *WorkflowDispatch {
|
||||||
switch w.RawOn.Kind {
|
if w.RawOn.Kind != yaml.MappingNode {
|
||||||
case yaml.ScalarNode:
|
|
||||||
var val string
|
|
||||||
if !decodeNode(w.RawOn, &val) {
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if val == "workflow_dispatch" {
|
|
||||||
return &WorkflowDispatch{}
|
|
||||||
}
|
|
||||||
case yaml.SequenceNode:
|
|
||||||
var val []string
|
|
||||||
if !decodeNode(w.RawOn, &val) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
for _, v := range val {
|
|
||||||
if v == "workflow_dispatch" {
|
|
||||||
return &WorkflowDispatch{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case yaml.MappingNode:
|
|
||||||
var val map[string]yaml.Node
|
var val map[string]yaml.Node
|
||||||
if !decodeNode(w.RawOn, &val) {
|
if !decodeNode(w.RawOn, &val) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
n, found := val["workflow_dispatch"]
|
var config WorkflowDispatch
|
||||||
var workflowDispatch WorkflowDispatch
|
node := val["workflow_dispatch"]
|
||||||
if found && decodeNode(n, &workflowDispatch) {
|
if !decodeNode(node, &config) {
|
||||||
return &workflowDispatch
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return nil
|
|
||||||
|
return &config
|
||||||
}
|
}
|
||||||
|
|
||||||
type WorkflowCallInput struct {
|
type WorkflowCallInput struct {
|
||||||
|
@ -317,39 +299,15 @@ func (j *Job) Needs() []string {
|
||||||
// RunsOn list for Job
|
// RunsOn list for Job
|
||||||
func (j *Job) RunsOn() []string {
|
func (j *Job) RunsOn() []string {
|
||||||
switch j.RawRunsOn.Kind {
|
switch j.RawRunsOn.Kind {
|
||||||
case yaml.MappingNode:
|
|
||||||
var val struct {
|
|
||||||
Group string
|
|
||||||
Labels yaml.Node
|
|
||||||
}
|
|
||||||
|
|
||||||
if !decodeNode(j.RawRunsOn, &val) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
labels := nodeAsStringSlice(val.Labels)
|
|
||||||
|
|
||||||
if val.Group != "" {
|
|
||||||
labels = append(labels, val.Group)
|
|
||||||
}
|
|
||||||
|
|
||||||
return labels
|
|
||||||
default:
|
|
||||||
return nodeAsStringSlice(j.RawRunsOn)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func nodeAsStringSlice(node yaml.Node) []string {
|
|
||||||
switch node.Kind {
|
|
||||||
case yaml.ScalarNode:
|
case yaml.ScalarNode:
|
||||||
var val string
|
var val string
|
||||||
if !decodeNode(node, &val) {
|
if !decodeNode(j.RawRunsOn, &val) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return []string{val}
|
return []string{val}
|
||||||
case yaml.SequenceNode:
|
case yaml.SequenceNode:
|
||||||
var val []string
|
var val []string
|
||||||
if !decodeNode(node, &val) {
|
if !decodeNode(j.RawRunsOn, &val) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return val
|
return val
|
||||||
|
@ -749,7 +707,7 @@ func (w *Workflow) GetJobIDs() []string {
|
||||||
}
|
}
|
||||||
|
|
||||||
var OnDecodeNodeError = func(node yaml.Node, out interface{}, err error) {
|
var OnDecodeNodeError = func(node yaml.Node, out interface{}, err error) {
|
||||||
log.Errorf("Failed to decode node %v into %T: %v", node, out, err)
|
log.Fatalf("Failed to decode node %v into %T: %v", node, out, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func decodeNode(node yaml.Node, out interface{}) bool {
|
func decodeNode(node yaml.Node, out interface{}) bool {
|
||||||
|
|
|
@ -153,60 +153,6 @@ jobs:
|
||||||
assert.Contains(t, workflow.On(), "pull_request")
|
assert.Contains(t, workflow.On(), "pull_request")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestReadWorkflow_DecodeNodeError(t *testing.T) {
|
|
||||||
yaml := `
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
test:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- run: echo
|
|
||||||
env:
|
|
||||||
foo: {{ a }}
|
|
||||||
`
|
|
||||||
|
|
||||||
workflow, err := ReadWorkflow(strings.NewReader(yaml))
|
|
||||||
assert.NoError(t, err, "read workflow should succeed")
|
|
||||||
assert.Nil(t, workflow.GetJob("test").Steps[0].GetEnv())
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestReadWorkflow_RunsOnLabels(t *testing.T) {
|
|
||||||
yaml := `
|
|
||||||
name: local-action-docker-url
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
test:
|
|
||||||
container: nginx:latest
|
|
||||||
runs-on:
|
|
||||||
labels: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: ./actions/docker-url`
|
|
||||||
|
|
||||||
workflow, err := ReadWorkflow(strings.NewReader(yaml))
|
|
||||||
assert.NoError(t, err, "read workflow should succeed")
|
|
||||||
assert.Equal(t, workflow.Jobs["test"].RunsOn(), []string{"ubuntu-latest"})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestReadWorkflow_RunsOnLabelsWithGroup(t *testing.T) {
|
|
||||||
yaml := `
|
|
||||||
name: local-action-docker-url
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
test:
|
|
||||||
container: nginx:latest
|
|
||||||
runs-on:
|
|
||||||
labels: [ubuntu-latest]
|
|
||||||
group: linux
|
|
||||||
steps:
|
|
||||||
- uses: ./actions/docker-url`
|
|
||||||
|
|
||||||
workflow, err := ReadWorkflow(strings.NewReader(yaml))
|
|
||||||
assert.NoError(t, err, "read workflow should succeed")
|
|
||||||
assert.Equal(t, workflow.Jobs["test"].RunsOn(), []string{"ubuntu-latest", "linux"})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestReadWorkflow_StringContainer(t *testing.T) {
|
func TestReadWorkflow_StringContainer(t *testing.T) {
|
||||||
yaml := `
|
yaml := `
|
||||||
name: local-action-docker-url
|
name: local-action-docker-url
|
||||||
|
@ -518,107 +464,3 @@ func TestStep_ShellCommand(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestReadWorkflow_WorkflowDispatchConfig(t *testing.T) {
|
|
||||||
yaml := `
|
|
||||||
name: local-action-docker-url
|
|
||||||
`
|
|
||||||
workflow, err := ReadWorkflow(strings.NewReader(yaml))
|
|
||||||
assert.NoError(t, err, "read workflow should succeed")
|
|
||||||
workflowDispatch := workflow.WorkflowDispatchConfig()
|
|
||||||
assert.Nil(t, workflowDispatch)
|
|
||||||
|
|
||||||
yaml = `
|
|
||||||
name: local-action-docker-url
|
|
||||||
on: push
|
|
||||||
`
|
|
||||||
workflow, err = ReadWorkflow(strings.NewReader(yaml))
|
|
||||||
assert.NoError(t, err, "read workflow should succeed")
|
|
||||||
workflowDispatch = workflow.WorkflowDispatchConfig()
|
|
||||||
assert.Nil(t, workflowDispatch)
|
|
||||||
|
|
||||||
yaml = `
|
|
||||||
name: local-action-docker-url
|
|
||||||
on: workflow_dispatch
|
|
||||||
`
|
|
||||||
workflow, err = ReadWorkflow(strings.NewReader(yaml))
|
|
||||||
assert.NoError(t, err, "read workflow should succeed")
|
|
||||||
workflowDispatch = workflow.WorkflowDispatchConfig()
|
|
||||||
assert.NotNil(t, workflowDispatch)
|
|
||||||
assert.Nil(t, workflowDispatch.Inputs)
|
|
||||||
|
|
||||||
yaml = `
|
|
||||||
name: local-action-docker-url
|
|
||||||
on: [push, pull_request]
|
|
||||||
`
|
|
||||||
workflow, err = ReadWorkflow(strings.NewReader(yaml))
|
|
||||||
assert.NoError(t, err, "read workflow should succeed")
|
|
||||||
workflowDispatch = workflow.WorkflowDispatchConfig()
|
|
||||||
assert.Nil(t, workflowDispatch)
|
|
||||||
|
|
||||||
yaml = `
|
|
||||||
name: local-action-docker-url
|
|
||||||
on: [push, workflow_dispatch]
|
|
||||||
`
|
|
||||||
workflow, err = ReadWorkflow(strings.NewReader(yaml))
|
|
||||||
assert.NoError(t, err, "read workflow should succeed")
|
|
||||||
workflowDispatch = workflow.WorkflowDispatchConfig()
|
|
||||||
assert.NotNil(t, workflowDispatch)
|
|
||||||
assert.Nil(t, workflowDispatch.Inputs)
|
|
||||||
|
|
||||||
yaml = `
|
|
||||||
name: local-action-docker-url
|
|
||||||
on:
|
|
||||||
- push
|
|
||||||
- workflow_dispatch
|
|
||||||
`
|
|
||||||
workflow, err = ReadWorkflow(strings.NewReader(yaml))
|
|
||||||
assert.NoError(t, err, "read workflow should succeed")
|
|
||||||
workflowDispatch = workflow.WorkflowDispatchConfig()
|
|
||||||
assert.NotNil(t, workflowDispatch)
|
|
||||||
assert.Nil(t, workflowDispatch.Inputs)
|
|
||||||
|
|
||||||
yaml = `
|
|
||||||
name: local-action-docker-url
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
pull_request:
|
|
||||||
`
|
|
||||||
workflow, err = ReadWorkflow(strings.NewReader(yaml))
|
|
||||||
assert.NoError(t, err, "read workflow should succeed")
|
|
||||||
workflowDispatch = workflow.WorkflowDispatchConfig()
|
|
||||||
assert.Nil(t, workflowDispatch)
|
|
||||||
|
|
||||||
yaml = `
|
|
||||||
name: local-action-docker-url
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
pull_request:
|
|
||||||
workflow_dispatch:
|
|
||||||
inputs:
|
|
||||||
logLevel:
|
|
||||||
description: 'Log level'
|
|
||||||
required: true
|
|
||||||
default: 'warning'
|
|
||||||
type: choice
|
|
||||||
options:
|
|
||||||
- info
|
|
||||||
- warning
|
|
||||||
- debug
|
|
||||||
`
|
|
||||||
workflow, err = ReadWorkflow(strings.NewReader(yaml))
|
|
||||||
assert.NoError(t, err, "read workflow should succeed")
|
|
||||||
workflowDispatch = workflow.WorkflowDispatchConfig()
|
|
||||||
assert.NotNil(t, workflowDispatch)
|
|
||||||
assert.Equal(t, WorkflowDispatchInput{
|
|
||||||
Default: "warning",
|
|
||||||
Description: "Log level",
|
|
||||||
Options: []string{
|
|
||||||
"info",
|
|
||||||
"warning",
|
|
||||||
"debug",
|
|
||||||
},
|
|
||||||
Required: true,
|
|
||||||
Type: "choice",
|
|
||||||
}, workflowDispatch.Inputs["logLevel"])
|
|
||||||
}
|
|
||||||
|
|
|
@ -3,7 +3,6 @@ package runner
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"embed"
|
"embed"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/fs"
|
"io/fs"
|
||||||
|
@ -42,24 +41,14 @@ var trampoline embed.FS
|
||||||
|
|
||||||
func readActionImpl(ctx context.Context, step *model.Step, actionDir string, actionPath string, readFile actionYamlReader, writeFile fileWriter) (*model.Action, error) {
|
func readActionImpl(ctx context.Context, step *model.Step, actionDir string, actionPath string, readFile actionYamlReader, writeFile fileWriter) (*model.Action, error) {
|
||||||
logger := common.Logger(ctx)
|
logger := common.Logger(ctx)
|
||||||
allErrors := []error{}
|
|
||||||
addError := func(fileName string, err error) {
|
|
||||||
if err != nil {
|
|
||||||
allErrors = append(allErrors, fmt.Errorf("failed to read '%s' from action '%s' with path '%s' of step %w", fileName, step.String(), actionPath, err))
|
|
||||||
} else {
|
|
||||||
// One successful read, clear error state
|
|
||||||
allErrors = nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
reader, closer, err := readFile("action.yml")
|
reader, closer, err := readFile("action.yml")
|
||||||
addError("action.yml", err)
|
if err != nil {
|
||||||
|
logger.Debugf("readActionImpl actionDir %s actionPath %s failed %v", actionDir, actionPath, err)
|
||||||
|
}
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
reader, closer, err = readFile("action.yaml")
|
reader, closer, err = readFile("action.yaml")
|
||||||
addError("action.yaml", err)
|
if err != nil {
|
||||||
if os.IsNotExist(err) {
|
if _, closer, err2 := readFile("Dockerfile"); err2 == nil {
|
||||||
_, closer, err := readFile("Dockerfile")
|
|
||||||
addError("Dockerfile", err)
|
|
||||||
if err == nil {
|
|
||||||
closer.Close()
|
closer.Close()
|
||||||
action := &model.Action{
|
action := &model.Action{
|
||||||
Name: "(Synthetic)",
|
Name: "(Synthetic)",
|
||||||
|
@ -104,10 +93,10 @@ func readActionImpl(ctx context.Context, step *model.Step, actionDir string, act
|
||||||
return action, nil
|
return action, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
} else if err != nil {
|
||||||
if allErrors != nil {
|
return nil, err
|
||||||
return nil, errors.Join(allErrors...)
|
|
||||||
}
|
}
|
||||||
defer closer.Close()
|
defer closer.Close()
|
||||||
|
|
||||||
|
@ -124,6 +113,9 @@ func maybeCopyToActionDir(ctx context.Context, step actionStep, actionDir string
|
||||||
if stepModel.Type() != model.StepTypeUsesActionRemote {
|
if stepModel.Type() != model.StepTypeUsesActionRemote {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
if err := removeGitIgnore(ctx, actionDir); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
var containerActionDirCopy string
|
var containerActionDirCopy string
|
||||||
containerActionDirCopy = strings.TrimSuffix(containerActionDir, actionPath)
|
containerActionDirCopy = strings.TrimSuffix(containerActionDir, actionPath)
|
||||||
|
@ -132,21 +124,6 @@ func maybeCopyToActionDir(ctx context.Context, step actionStep, actionDir string
|
||||||
if !strings.HasSuffix(containerActionDirCopy, `/`) {
|
if !strings.HasSuffix(containerActionDirCopy, `/`) {
|
||||||
containerActionDirCopy += `/`
|
containerActionDirCopy += `/`
|
||||||
}
|
}
|
||||||
|
|
||||||
if rc.Config != nil && rc.Config.ActionCache != nil {
|
|
||||||
raction := step.(*stepActionRemote)
|
|
||||||
ta, err := rc.Config.ActionCache.GetTarArchive(ctx, raction.cacheDir, raction.resolvedSha, "")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer ta.Close()
|
|
||||||
return rc.JobContainer.CopyTarStream(ctx, containerActionDirCopy, ta)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := removeGitIgnore(ctx, actionDir); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return rc.JobContainer.CopyDir(containerActionDirCopy, actionDir+"/", rc.Config.UseGitIgnore)(ctx)
|
return rc.JobContainer.CopyDir(containerActionDirCopy, actionDir+"/", rc.Config.UseGitIgnore)(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -307,13 +284,6 @@ func execAsDocker(ctx context.Context, step actionStep, actionName string, based
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer buildContext.Close()
|
defer buildContext.Close()
|
||||||
} else if rc.Config.ActionCache != nil {
|
|
||||||
rstep := step.(*stepActionRemote)
|
|
||||||
buildContext, err = rc.Config.ActionCache.GetTarArchive(ctx, rstep.cacheDir, rstep.resolvedSha, contextDir)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer buildContext.Close()
|
|
||||||
}
|
}
|
||||||
prepImage = container.NewDockerBuildExecutor(container.NewDockerBuildExecutorInput{
|
prepImage = container.NewDockerBuildExecutor(container.NewDockerBuildExecutorInput{
|
||||||
ContextDir: contextDir,
|
ContextDir: contextDir,
|
||||||
|
@ -477,11 +447,15 @@ func getContainerActionPaths(step *model.Step, actionDir string, rc *RunContext)
|
||||||
actionName = strings.ReplaceAll(actionName, "\\", "/")
|
actionName = strings.ReplaceAll(actionName, "\\", "/")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
common.Logger(context.Background()).Debugf("getContainerActionPaths step.Type %s, rc.Config.Workdir %s, actionName %s, containerActionDir %s", step.Type().String(), rc.Config.Workdir, actionName, containerActionDir)
|
||||||
return actionName, containerActionDir
|
return actionName, containerActionDir
|
||||||
}
|
}
|
||||||
|
|
||||||
func getOsSafeRelativePath(s, prefix string) string {
|
func getOsSafeRelativePath(s, prefix string) string {
|
||||||
actionName := strings.TrimPrefix(s, prefix)
|
actionName := strings.TrimPrefix(s, prefix)
|
||||||
|
if s == actionName {
|
||||||
|
common.Logger(context.Background()).Errorf("getOsSafeRelativePath %s does not beging with %s", s, prefix)
|
||||||
|
}
|
||||||
if runtime.GOOS == "windows" {
|
if runtime.GOOS == "windows" {
|
||||||
actionName = strings.ReplaceAll(actionName, "\\", "/")
|
actionName = strings.ReplaceAll(actionName, "\\", "/")
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,6 @@ import (
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
|
||||||
"io"
|
"io"
|
||||||
"io/fs"
|
"io/fs"
|
||||||
"path"
|
"path"
|
||||||
|
@ -87,9 +86,6 @@ func (c GoGitActionCache) Fetch(ctx context.Context, cacheDir, url, ref, token s
|
||||||
Auth: auth,
|
Auth: auth,
|
||||||
Force: true,
|
Force: true,
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
if tagOrSha && errors.Is(err, git.NoErrAlreadyUpToDate) {
|
|
||||||
return "", fmt.Errorf("couldn't find remote ref \"%s\"", ref)
|
|
||||||
}
|
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
if tagOrSha {
|
if tagOrSha {
|
||||||
|
|
|
@ -20,7 +20,6 @@ type jobInfo interface {
|
||||||
result(result string)
|
result(result string)
|
||||||
}
|
}
|
||||||
|
|
||||||
//nolint:contextcheck,gocyclo
|
|
||||||
func newJobExecutor(info jobInfo, sf stepFactory, rc *RunContext) common.Executor {
|
func newJobExecutor(info jobInfo, sf stepFactory, rc *RunContext) common.Executor {
|
||||||
steps := make([]common.Executor, 0)
|
steps := make([]common.Executor, 0)
|
||||||
preSteps := make([]common.Executor, 0)
|
preSteps := make([]common.Executor, 0)
|
||||||
|
@ -102,7 +101,7 @@ func newJobExecutor(info jobInfo, sf stepFactory, rc *RunContext) common.Executo
|
||||||
|
|
||||||
postExec := useStepLogger(rc, stepModel, stepStagePost, step.post())
|
postExec := useStepLogger(rc, stepModel, stepStagePost, step.post())
|
||||||
if postExecutor != nil {
|
if postExecutor != nil {
|
||||||
// run the post executor in reverse order
|
// run the post exector in reverse order
|
||||||
postExecutor = postExec.Finally(postExecutor)
|
postExecutor = postExec.Finally(postExecutor)
|
||||||
} else {
|
} else {
|
||||||
postExecutor = postExec
|
postExecutor = postExec
|
||||||
|
@ -118,19 +117,22 @@ func newJobExecutor(info jobInfo, sf stepFactory, rc *RunContext) common.Executo
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
logger := common.Logger(ctx)
|
logger := common.Logger(ctx)
|
||||||
|
logger.Infof("Cleaning up services for job %s", rc.JobName)
|
||||||
|
if err := rc.stopServiceContainers()(ctx); err != nil {
|
||||||
|
logger.Errorf("Error while cleaning services: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
logger.Infof("Cleaning up container for job %s", rc.JobName)
|
logger.Infof("Cleaning up container for job %s", rc.JobName)
|
||||||
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.IsHostEnv(ctx) && rc.Config.ContainerNetworkMode == "" {
|
if !rc.IsHostEnv(ctx) && rc.Config.ContainerNetworkMode == "" {
|
||||||
// clean network in docker mode only
|
// 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.
|
||||||
networkName, _ := rc.networkName()
|
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, networkName)
|
if err := container.NewDockerNetworkRemoveExecutor(rc.networkName())(ctx); err != nil {
|
||||||
if err := container.NewDockerNetworkRemoveExecutor(networkName)(ctx); err != nil {
|
|
||||||
logger.Errorf("Error while cleaning network: %v", err)
|
logger.Errorf("Error while cleaning network: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package runner
|
package runner
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"archive/tar"
|
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
@ -68,51 +67,12 @@ func newRemoteReusableWorkflowExecutor(rc *RunContext) common.Executor {
|
||||||
// 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 := ""
|
||||||
|
|
||||||
if rc.Config.ActionCache != nil {
|
|
||||||
return newActionCacheReusableWorkflowExecutor(rc, filename, remoteReusableWorkflow)
|
|
||||||
}
|
|
||||||
|
|
||||||
return common.NewPipelineExecutor(
|
return common.NewPipelineExecutor(
|
||||||
newMutexExecutor(cloneIfRequired(rc, *remoteReusableWorkflow, workflowDir, token)),
|
newMutexExecutor(cloneIfRequired(rc, *remoteReusableWorkflow, workflowDir, token)),
|
||||||
newReusableWorkflowExecutor(rc, workflowDir, remoteReusableWorkflow.FilePath()),
|
newReusableWorkflowExecutor(rc, workflowDir, remoteReusableWorkflow.FilePath()),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func newActionCacheReusableWorkflowExecutor(rc *RunContext, filename string, remoteReusableWorkflow *remoteReusableWorkflow) common.Executor {
|
|
||||||
return func(ctx context.Context) error {
|
|
||||||
ghctx := rc.getGithubContext(ctx)
|
|
||||||
remoteReusableWorkflow.URL = ghctx.ServerURL
|
|
||||||
sha, err := rc.Config.ActionCache.Fetch(ctx, filename, remoteReusableWorkflow.CloneURL(), remoteReusableWorkflow.Ref, ghctx.Token)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
archive, err := rc.Config.ActionCache.GetTarArchive(ctx, filename, sha, fmt.Sprintf(".github/workflows/%s", remoteReusableWorkflow.Filename))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer archive.Close()
|
|
||||||
treader := tar.NewReader(archive)
|
|
||||||
if _, err = treader.Next(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
planner, err := model.NewSingleWorkflowPlanner(remoteReusableWorkflow.Filename, treader)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
plan, err := planner.PlanEvent("workflow_call")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
runner, err := NewReusableWorkflowRunner(rc)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return runner.NewPlanExecutor(plan)(ctx)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
executorLock sync.Mutex
|
executorLock sync.Mutex
|
||||||
)
|
)
|
||||||
|
@ -143,7 +103,6 @@ func cloneIfRequired(rc *RunContext, remoteReusableWorkflow remoteReusableWorkfl
|
||||||
Ref: remoteReusableWorkflow.Ref,
|
Ref: remoteReusableWorkflow.Ref,
|
||||||
Dir: targetDirectory,
|
Dir: targetDirectory,
|
||||||
Token: token,
|
Token: token,
|
||||||
OfflineMode: rc.Config.ActionOfflineMode,
|
|
||||||
})(ctx)
|
})(ctx)
|
||||||
},
|
},
|
||||||
nil,
|
nil,
|
||||||
|
|
|
@ -19,14 +19,15 @@ import (
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
"text/template"
|
"text/template"
|
||||||
|
"time"
|
||||||
|
|
||||||
docker "github.com/docker/docker/api/types"
|
docker "github.com/docker/docker/api/types"
|
||||||
"github.com/docker/go-connections/nat"
|
"github.com/opencontainers/selinux/go-selinux"
|
||||||
|
|
||||||
"github.com/nektos/act/pkg/common"
|
"github.com/nektos/act/pkg/common"
|
||||||
"github.com/nektos/act/pkg/container"
|
"github.com/nektos/act/pkg/container"
|
||||||
"github.com/nektos/act/pkg/exprparser"
|
"github.com/nektos/act/pkg/exprparser"
|
||||||
"github.com/nektos/act/pkg/model"
|
"github.com/nektos/act/pkg/model"
|
||||||
"github.com/opencontainers/selinux/go-selinux"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// RunContext contains info about current job
|
// RunContext contains info about current job
|
||||||
|
@ -68,7 +69,7 @@ func (rc *RunContext) String() string {
|
||||||
if rc.caller != nil {
|
if rc.caller != nil {
|
||||||
// prefix the reusable workflow with the caller job
|
// prefix the reusable workflow with the caller job
|
||||||
// this is required to create unique container names
|
// this is required to create unique container names
|
||||||
name = fmt.Sprintf("%s/%s", rc.caller.runContext.Name, name)
|
name = fmt.Sprintf("%s/%s", rc.caller.runContext.Run.JobID, name)
|
||||||
}
|
}
|
||||||
return name
|
return name
|
||||||
}
|
}
|
||||||
|
@ -98,11 +99,9 @@ func (rc *RunContext) jobContainerName() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// networkName return the name of the network which will be created by `act` automatically for job,
|
// networkName return the name of the network which will be created by `act` automatically for job,
|
||||||
func (rc *RunContext) networkName() (string, bool) {
|
// only create network if `rc.Config.ContainerNetworkMode` is empty string.
|
||||||
if len(rc.Run.Job().Services) > 0 || rc.Config.ContainerNetworkMode == "" {
|
func (rc *RunContext) networkName() string {
|
||||||
return fmt.Sprintf("%s-%s-network", rc.jobContainerName(), rc.Run.JobID), true
|
return fmt.Sprintf("%s-network", rc.jobContainerName())
|
||||||
}
|
|
||||||
return string(rc.Config.ContainerNetworkMode), false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func getDockerDaemonSocketMountPath(daemonPath string) string {
|
func getDockerDaemonSocketMountPath(daemonPath string) string {
|
||||||
|
@ -140,7 +139,7 @@ func (rc *RunContext) GetBindsAndMounts() ([]string, map[string]string) {
|
||||||
ext := container.LinuxContainerEnvironmentExtensions{}
|
ext := container.LinuxContainerEnvironmentExtensions{}
|
||||||
|
|
||||||
mounts := map[string]string{
|
mounts := map[string]string{
|
||||||
"act-toolcache": "/opt/hostedtoolcache",
|
"act-toolcache": "/toolcache",
|
||||||
name + "-env": ext.GetActPath(),
|
name + "-env": ext.GetActPath(),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -394,7 +393,6 @@ func (rc *RunContext) startHostEnvironment() common.Executor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//nolint:gocyclo
|
|
||||||
func (rc *RunContext) startJobContainer() common.Executor {
|
func (rc *RunContext) startJobContainer() common.Executor {
|
||||||
return func(ctx context.Context) error {
|
return func(ctx context.Context) error {
|
||||||
logger := common.Logger(ctx)
|
logger := common.Logger(ctx)
|
||||||
|
@ -433,15 +431,14 @@ func (rc *RunContext) startJobContainer() common.Executor {
|
||||||
|
|
||||||
// specify the network to which the container will connect when `docker create` stage. (like execute command line: docker create --network <networkName> <image>)
|
// specify the network to which the container will connect when `docker create` stage. (like execute command line: docker create --network <networkName> <image>)
|
||||||
networkName := string(rc.Config.ContainerNetworkMode)
|
networkName := string(rc.Config.ContainerNetworkMode)
|
||||||
var createAndDeleteNetwork bool
|
|
||||||
if networkName == "" {
|
if networkName == "" {
|
||||||
// if networkName is empty string, will create a new network for the containers.
|
// if networkName is empty string, will create a new network for the containers.
|
||||||
// and it will be removed after at last.
|
// and it will be removed after at last.
|
||||||
networkName, createAndDeleteNetwork = rc.networkName()
|
networkName = rc.networkName()
|
||||||
}
|
}
|
||||||
|
|
||||||
// add service containers
|
// add service containers
|
||||||
for serviceID, spec := range rc.Run.Job().Services {
|
for serviceId, spec := range rc.Run.Job().Services {
|
||||||
// interpolate env
|
// interpolate env
|
||||||
interpolatedEnvs := make(map[string]string, len(spec.Env))
|
interpolatedEnvs := make(map[string]string, len(spec.Env))
|
||||||
for k, v := range spec.Env {
|
for k, v := range spec.Env {
|
||||||
|
@ -451,36 +448,21 @@ func (rc *RunContext) startJobContainer() common.Executor {
|
||||||
for k, v := range interpolatedEnvs {
|
for k, v := range interpolatedEnvs {
|
||||||
envs = append(envs, fmt.Sprintf("%s=%s", k, v))
|
envs = append(envs, fmt.Sprintf("%s=%s", k, v))
|
||||||
}
|
}
|
||||||
|
// interpolate cmd
|
||||||
interpolatedCmd := make([]string, 0, len(spec.Cmd))
|
interpolatedCmd := make([]string, 0, len(spec.Cmd))
|
||||||
for _, v := range spec.Cmd {
|
for _, v := range spec.Cmd {
|
||||||
interpolatedCmd = append(interpolatedCmd, rc.ExprEval.Interpolate(ctx, v))
|
interpolatedCmd = append(interpolatedCmd, rc.ExprEval.Interpolate(ctx, v))
|
||||||
}
|
}
|
||||||
|
username, password, err := rc.handleServiceCredentials(ctx, spec.Credentials)
|
||||||
username, password, err = rc.handleServiceCredentials(ctx, spec.Credentials)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to handle service %s credentials: %w", serviceID, err)
|
return fmt.Errorf("failed to handle service %s credentials: %w", serviceId, err)
|
||||||
}
|
}
|
||||||
|
serviceBinds, serviceMounts := rc.GetServiceBindsAndMounts(spec.Volumes)
|
||||||
interpolatedVolumes := make([]string, 0, len(spec.Volumes))
|
serviceContainerName := createSimpleContainerName(rc.jobContainerName(), serviceId)
|
||||||
for _, volume := range spec.Volumes {
|
|
||||||
interpolatedVolumes = append(interpolatedVolumes, rc.ExprEval.Interpolate(ctx, volume))
|
|
||||||
}
|
|
||||||
serviceBinds, serviceMounts := rc.GetServiceBindsAndMounts(interpolatedVolumes)
|
|
||||||
|
|
||||||
interpolatedPorts := make([]string, 0, len(spec.Ports))
|
|
||||||
for _, port := range spec.Ports {
|
|
||||||
interpolatedPorts = append(interpolatedPorts, rc.ExprEval.Interpolate(ctx, port))
|
|
||||||
}
|
|
||||||
exposedPorts, portBindings, err := nat.ParsePortSpecs(interpolatedPorts)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed to parse service %s ports: %w", serviceID, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
serviceContainerName := createContainerName(rc.jobContainerName(), serviceID)
|
|
||||||
c := container.NewContainer(&container.NewContainerInput{
|
c := container.NewContainer(&container.NewContainerInput{
|
||||||
Name: serviceContainerName,
|
Name: serviceContainerName,
|
||||||
WorkingDir: ext.ToContainerPath(rc.Config.Workdir),
|
WorkingDir: ext.ToContainerPath(rc.Config.Workdir),
|
||||||
Image: rc.ExprEval.Interpolate(ctx, spec.Image),
|
Image: spec.Image,
|
||||||
Username: username,
|
Username: username,
|
||||||
Password: password,
|
Password: password,
|
||||||
Cmd: interpolatedCmd,
|
Cmd: interpolatedCmd,
|
||||||
|
@ -493,51 +475,30 @@ func (rc *RunContext) startJobContainer() common.Executor {
|
||||||
UsernsMode: rc.Config.UsernsMode,
|
UsernsMode: rc.Config.UsernsMode,
|
||||||
Platform: rc.Config.ContainerArchitecture,
|
Platform: rc.Config.ContainerArchitecture,
|
||||||
AutoRemove: rc.Config.AutoRemove,
|
AutoRemove: rc.Config.AutoRemove,
|
||||||
Options: rc.ExprEval.Interpolate(ctx, spec.Options),
|
Options: spec.Options,
|
||||||
NetworkMode: networkName,
|
NetworkMode: networkName,
|
||||||
NetworkAliases: []string{serviceID},
|
NetworkAliases: []string{serviceId},
|
||||||
ExposedPorts: exposedPorts,
|
|
||||||
PortBindings: portBindings,
|
|
||||||
ValidVolumes: rc.Config.ValidVolumes,
|
ValidVolumes: rc.Config.ValidVolumes,
|
||||||
})
|
})
|
||||||
rc.ServiceContainers = append(rc.ServiceContainers, c)
|
rc.ServiceContainers = append(rc.ServiceContainers, c)
|
||||||
}
|
}
|
||||||
|
|
||||||
rc.cleanUpJobContainer = func(ctx context.Context) error {
|
rc.cleanUpJobContainer = func(ctx context.Context) error {
|
||||||
reuseJobContainer := func(ctx context.Context) bool {
|
if rc.JobContainer != nil && !rc.Config.ReuseContainers {
|
||||||
return rc.Config.ReuseContainers
|
return rc.JobContainer.Remove().
|
||||||
}
|
Then(container.NewDockerVolumeRemoveExecutor(rc.jobContainerName(), false)).
|
||||||
|
Then(container.NewDockerVolumeRemoveExecutor(rc.jobContainerName()+"-env", false))(ctx)
|
||||||
if rc.JobContainer != nil {
|
|
||||||
return rc.JobContainer.Remove().IfNot(reuseJobContainer).
|
|
||||||
Then(container.NewDockerVolumeRemoveExecutor(rc.jobContainerName(), false)).IfNot(reuseJobContainer).
|
|
||||||
Then(container.NewDockerVolumeRemoveExecutor(rc.jobContainerName()+"-env", false)).IfNot(reuseJobContainer).
|
|
||||||
Then(func(ctx context.Context) error {
|
|
||||||
if len(rc.ServiceContainers) > 0 {
|
|
||||||
logger.Infof("Cleaning up services for job %s", rc.JobName)
|
|
||||||
if err := rc.stopServiceContainers()(ctx); err != nil {
|
|
||||||
logger.Errorf("Error while cleaning services: %v", err)
|
|
||||||
}
|
|
||||||
if createAndDeleteNetwork {
|
|
||||||
// clean network if it has been created by act
|
|
||||||
// if using service containers
|
|
||||||
// it means that the network to which containers are connecting is created by `act_runner`,
|
|
||||||
// so, we should remove the network at last.
|
|
||||||
logger.Infof("Cleaning up network for job %s, and network name is: %s", rc.JobName, networkName)
|
|
||||||
if err := container.NewDockerNetworkRemoveExecutor(networkName)(ctx); err != nil {
|
|
||||||
logger.Errorf("Error while cleaning network: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})(ctx)
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lifetime := fmt.Sprint(rc.Config.ContainerMaxLifetime.Round(time.Second).Seconds())
|
||||||
|
if lifetime == "0" {
|
||||||
|
lifetime = "infinity"
|
||||||
|
}
|
||||||
rc.JobContainer = container.NewContainer(&container.NewContainerInput{
|
rc.JobContainer = container.NewContainer(&container.NewContainerInput{
|
||||||
Cmd: nil,
|
Cmd: nil,
|
||||||
Entrypoint: []string{"tail", "-f", "/dev/null"},
|
Entrypoint: []string{"/bin/sleep", lifetime},
|
||||||
WorkingDir: ext.ToContainerPath(rc.Config.Workdir),
|
WorkingDir: ext.ToContainerPath(rc.Config.Workdir),
|
||||||
Image: image,
|
Image: image,
|
||||||
Username: username,
|
Username: username,
|
||||||
|
@ -569,7 +530,6 @@ 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.stopJobContainer(),
|
|
||||||
container.NewDockerNetworkCreateExecutor(networkName, &networkConfig).IfBool(!rc.IsHostEnv(ctx) && rc.Config.ContainerNetworkMode == ""), // if the value of `ContainerNetworkMode` is empty string, then will create a new network for containers.
|
container.NewDockerNetworkCreateExecutor(networkName, &networkConfig).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),
|
||||||
|
@ -647,10 +607,10 @@ func (rc *RunContext) UpdateExtraPath(ctx context.Context, githubEnvPath string)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// stopJobContainer removes the job container (if it exists) and its volume (if it exists)
|
// stopJobContainer removes the job container (if it exists) and its volume (if it exists) if !rc.Config.ReuseContainers
|
||||||
func (rc *RunContext) stopJobContainer() common.Executor {
|
func (rc *RunContext) stopJobContainer() common.Executor {
|
||||||
return func(ctx context.Context) error {
|
return func(ctx context.Context) error {
|
||||||
if rc.cleanUpJobContainer != nil {
|
if rc.cleanUpJobContainer != nil && !rc.Config.ReuseContainers {
|
||||||
return rc.cleanUpJobContainer(ctx)
|
return rc.cleanUpJobContainer(ctx)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -667,7 +627,7 @@ func (rc *RunContext) pullServicesImages(forcePull bool) common.Executor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rc *RunContext) startServiceContainers(_ string) common.Executor {
|
func (rc *RunContext) startServiceContainers(networkName string) common.Executor {
|
||||||
return func(ctx context.Context) error {
|
return func(ctx context.Context) error {
|
||||||
execs := []common.Executor{}
|
execs := []common.Executor{}
|
||||||
for _, c := range rc.ServiceContainers {
|
for _, c := range rc.ServiceContainers {
|
||||||
|
@ -685,7 +645,7 @@ func (rc *RunContext) stopServiceContainers() common.Executor {
|
||||||
return func(ctx context.Context) error {
|
return func(ctx context.Context) error {
|
||||||
execs := []common.Executor{}
|
execs := []common.Executor{}
|
||||||
for _, c := range rc.ServiceContainers {
|
for _, c := range rc.ServiceContainers {
|
||||||
execs = append(execs, c.Remove().Finally(c.Close()))
|
execs = append(execs, c.Remove())
|
||||||
}
|
}
|
||||||
return common.NewParallelExecutor(len(execs), execs...)(ctx)
|
return common.NewParallelExecutor(len(execs), execs...)(ctx)
|
||||||
}
|
}
|
||||||
|
@ -841,11 +801,13 @@ func (rc *RunContext) containerImage(ctx context.Context) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rc *RunContext) runsOnImage(ctx context.Context) string {
|
func (rc *RunContext) runsOnImage(ctx context.Context) string {
|
||||||
if rc.Run.Job().RunsOn() == nil {
|
job := rc.Run.Job()
|
||||||
|
|
||||||
|
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())
|
||||||
}
|
}
|
||||||
|
|
||||||
runsOn := rc.Run.Job().RunsOn()
|
runsOn := job.RunsOn()
|
||||||
for i, v := range runsOn {
|
for i, v := range runsOn {
|
||||||
runsOn[i] = rc.ExprEval.Interpolate(ctx, v)
|
runsOn[i] = rc.ExprEval.Interpolate(ctx, v)
|
||||||
}
|
}
|
||||||
|
@ -856,8 +818,8 @@ func (rc *RunContext) runsOnImage(ctx context.Context) string {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, platformName := range rc.runsOnPlatformNames(ctx) {
|
for _, runnerLabel := range runsOn {
|
||||||
image := rc.Config.Platforms[strings.ToLower(platformName)]
|
image := rc.Config.Platforms[strings.ToLower(runnerLabel)]
|
||||||
if image != "" {
|
if image != "" {
|
||||||
return image
|
return image
|
||||||
}
|
}
|
||||||
|
@ -866,21 +828,6 @@ func (rc *RunContext) runsOnImage(ctx context.Context) string {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rc *RunContext) runsOnPlatformNames(ctx context.Context) []string {
|
|
||||||
job := rc.Run.Job()
|
|
||||||
|
|
||||||
if job.RunsOn() == nil {
|
|
||||||
return []string{}
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := rc.ExprEval.EvaluateYamlNode(ctx, &job.RawRunsOn); err != nil {
|
|
||||||
common.Logger(ctx).Errorf("Error while evaluating runs-on: %v", err)
|
|
||||||
return []string{}
|
|
||||||
}
|
|
||||||
|
|
||||||
return job.RunsOn()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (rc *RunContext) platformImage(ctx context.Context) string {
|
func (rc *RunContext) platformImage(ctx context.Context) string {
|
||||||
if containerImage := rc.containerImage(ctx); containerImage != "" {
|
if containerImage := rc.containerImage(ctx); containerImage != "" {
|
||||||
return containerImage
|
return containerImage
|
||||||
|
@ -893,7 +840,7 @@ func (rc *RunContext) options(ctx context.Context) string {
|
||||||
job := rc.Run.Job()
|
job := rc.Run.Job()
|
||||||
c := job.Container()
|
c := job.Container()
|
||||||
if c != nil {
|
if c != nil {
|
||||||
return rc.Config.ContainerOptions + " " + rc.ExprEval.Interpolate(ctx, c.Options)
|
return rc.ExprEval.Interpolate(ctx, c.Options)
|
||||||
}
|
}
|
||||||
|
|
||||||
return rc.Config.ContainerOptions
|
return rc.Config.ContainerOptions
|
||||||
|
@ -911,6 +858,8 @@ func (rc *RunContext) isEnabled(ctx context.Context) (bool, error) {
|
||||||
|
|
||||||
if jobType == model.JobTypeInvalid {
|
if jobType == model.JobTypeInvalid {
|
||||||
return false, jobTypeErr
|
return false, jobTypeErr
|
||||||
|
} else if jobType != model.JobTypeDefault {
|
||||||
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if !runJob {
|
if !runJob {
|
||||||
|
@ -918,13 +867,14 @@ func (rc *RunContext) isEnabled(ctx context.Context) (bool, error) {
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if jobType != model.JobTypeDefault {
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
img := rc.platformImage(ctx)
|
img := rc.platformImage(ctx)
|
||||||
if img == "" {
|
if img == "" {
|
||||||
for _, platformName := range rc.runsOnPlatformNames(ctx) {
|
if job.RunsOn() == nil {
|
||||||
|
l.Errorf("'runs-on' key not defined in %s", rc.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, runnerLabel := range job.RunsOn() {
|
||||||
|
platformName := rc.ExprEval.Interpolate(ctx, runnerLabel)
|
||||||
l.Infof("\U0001F6A7 Skipping unsupported platform -- Try running with `-P %+v=...`", platformName)
|
l.Infof("\U0001F6A7 Skipping unsupported platform -- Try running with `-P %+v=...`", platformName)
|
||||||
}
|
}
|
||||||
return false, nil
|
return false, nil
|
||||||
|
@ -1228,7 +1178,9 @@ func (rc *RunContext) withGithubEnv(ctx context.Context, github *model.GithubCon
|
||||||
setActionRuntimeVars(rc, env)
|
setActionRuntimeVars(rc, env)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, platformName := range rc.runsOnPlatformNames(ctx) {
|
job := rc.Run.Job()
|
||||||
|
for _, runnerLabel := range job.RunsOn() {
|
||||||
|
platformName := rc.ExprEval.Interpolate(ctx, runnerLabel)
|
||||||
if platformName != "" {
|
if platformName != "" {
|
||||||
if platformName == "ubuntu-latest" {
|
if platformName == "ubuntu-latest" {
|
||||||
// hardcode current ubuntu-latest since we have no way to check that 'on the fly'
|
// hardcode current ubuntu-latest since we have no way to check that 'on the fly'
|
||||||
|
|
|
@ -470,53 +470,6 @@ func createJob(t *testing.T, input string, result string) *model.Job {
|
||||||
return job
|
return job
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRunContextRunsOnPlatformNames(t *testing.T) {
|
|
||||||
log.SetLevel(log.DebugLevel)
|
|
||||||
assertObject := assert.New(t)
|
|
||||||
|
|
||||||
rc := createIfTestRunContext(map[string]*model.Job{
|
|
||||||
"job1": createJob(t, `runs-on: ubuntu-latest`, ""),
|
|
||||||
})
|
|
||||||
assertObject.Equal([]string{"ubuntu-latest"}, rc.runsOnPlatformNames(context.Background()))
|
|
||||||
|
|
||||||
rc = createIfTestRunContext(map[string]*model.Job{
|
|
||||||
"job1": createJob(t, `runs-on: ${{ 'ubuntu-latest' }}`, ""),
|
|
||||||
})
|
|
||||||
assertObject.Equal([]string{"ubuntu-latest"}, rc.runsOnPlatformNames(context.Background()))
|
|
||||||
|
|
||||||
rc = createIfTestRunContext(map[string]*model.Job{
|
|
||||||
"job1": createJob(t, `runs-on: [self-hosted, my-runner]`, ""),
|
|
||||||
})
|
|
||||||
assertObject.Equal([]string{"self-hosted", "my-runner"}, rc.runsOnPlatformNames(context.Background()))
|
|
||||||
|
|
||||||
rc = createIfTestRunContext(map[string]*model.Job{
|
|
||||||
"job1": createJob(t, `runs-on: [self-hosted, "${{ 'my-runner' }}"]`, ""),
|
|
||||||
})
|
|
||||||
assertObject.Equal([]string{"self-hosted", "my-runner"}, rc.runsOnPlatformNames(context.Background()))
|
|
||||||
|
|
||||||
rc = createIfTestRunContext(map[string]*model.Job{
|
|
||||||
"job1": createJob(t, `runs-on: ${{ fromJSON('["ubuntu-latest"]') }}`, ""),
|
|
||||||
})
|
|
||||||
assertObject.Equal([]string{"ubuntu-latest"}, rc.runsOnPlatformNames(context.Background()))
|
|
||||||
|
|
||||||
// test missing / invalid runs-on
|
|
||||||
rc = createIfTestRunContext(map[string]*model.Job{
|
|
||||||
"job1": createJob(t, `name: something`, ""),
|
|
||||||
})
|
|
||||||
assertObject.Equal([]string{}, rc.runsOnPlatformNames(context.Background()))
|
|
||||||
|
|
||||||
rc = createIfTestRunContext(map[string]*model.Job{
|
|
||||||
"job1": createJob(t, `runs-on:
|
|
||||||
mapping: value`, ""),
|
|
||||||
})
|
|
||||||
assertObject.Equal([]string{}, rc.runsOnPlatformNames(context.Background()))
|
|
||||||
|
|
||||||
rc = createIfTestRunContext(map[string]*model.Job{
|
|
||||||
"job1": createJob(t, `runs-on: ${{ invalid expression }}`, ""),
|
|
||||||
})
|
|
||||||
assertObject.Equal([]string{}, rc.runsOnPlatformNames(context.Background()))
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestRunContextIsEnabled(t *testing.T) {
|
func TestRunContextIsEnabled(t *testing.T) {
|
||||||
log.SetLevel(log.DebugLevel)
|
log.SetLevel(log.DebugLevel)
|
||||||
assertObject := assert.New(t)
|
assertObject := assert.New(t)
|
||||||
|
@ -619,17 +572,6 @@ if: always()`, ""),
|
||||||
})
|
})
|
||||||
rc.Run.JobID = "job2"
|
rc.Run.JobID = "job2"
|
||||||
assertObject.True(rc.isEnabled(context.Background()))
|
assertObject.True(rc.isEnabled(context.Background()))
|
||||||
|
|
||||||
rc = createIfTestRunContext(map[string]*model.Job{
|
|
||||||
"job1": createJob(t, `uses: ./.github/workflows/reusable.yml`, ""),
|
|
||||||
})
|
|
||||||
assertObject.True(rc.isEnabled(context.Background()))
|
|
||||||
|
|
||||||
rc = createIfTestRunContext(map[string]*model.Job{
|
|
||||||
"job1": createJob(t, `uses: ./.github/workflows/reusable.yml
|
|
||||||
if: false`, ""),
|
|
||||||
})
|
|
||||||
assertObject.False(rc.isEnabled(context.Background()))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRunContextGetEnv(t *testing.T) {
|
func TestRunContextGetEnv(t *testing.T) {
|
||||||
|
|
|
@ -25,7 +25,6 @@ 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
|
ActionCacheDir string // path used for caching action contents
|
||||||
ActionOfflineMode bool // when offline, use 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
|
||||||
|
@ -61,20 +60,17 @@ type Config struct {
|
||||||
ReplaceGheActionWithGithubCom []string // Use actions from GitHub Enterprise instance to GitHub
|
ReplaceGheActionWithGithubCom []string // Use actions from GitHub Enterprise instance to GitHub
|
||||||
ReplaceGheActionTokenWithGithubCom string // Token of private action repo on GitHub.
|
ReplaceGheActionTokenWithGithubCom string // Token of private action repo on GitHub.
|
||||||
Matrix map[string]map[string]bool // Matrix config to run
|
Matrix map[string]map[string]bool // Matrix config to run
|
||||||
ContainerNetworkMode docker_container.NetworkMode // the network mode of job containers (the value of --network)
|
|
||||||
ActionCache ActionCache // Use a custom ActionCache Implementation
|
|
||||||
|
|
||||||
PresetGitHubContext *model.GithubContext // the preset github context, overrides some fields like DefaultBranch, Env, Secrets etc.
|
PresetGitHubContext *model.GithubContext // the preset github context, overrides some fields like DefaultBranch, Env, Secrets etc.
|
||||||
EventJSON string // the content of JSON file to use for event.json in containers, overrides EventPath
|
EventJSON string // the content of JSON file to use for event.json in containers, overrides EventPath
|
||||||
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)
|
||||||
|
ContainerNetworkEnableIPv6 bool // create the network with IPv6 support enabled
|
||||||
DefaultActionInstance string // the default actions web site
|
DefaultActionInstance string // the default actions web site
|
||||||
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
|
||||||
InsecureSkipTLS bool // whether to skip verifying TLS certificate of the Gitea instance
|
|
||||||
|
|
||||||
ContainerNetworkEnableIPv6 bool // create the network with IPv6 support enabled
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetToken: Adapt to Gitea
|
// GetToken: Adapt to Gitea
|
||||||
|
@ -211,6 +207,7 @@ 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())
|
||||||
executor, err := rc.Executor()
|
executor, err := rc.Executor()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -302,11 +302,6 @@ func TestRunEvent(t *testing.T) {
|
||||||
{workdir, "set-env-step-env-override", "push", "", platforms, secrets},
|
{workdir, "set-env-step-env-override", "push", "", platforms, secrets},
|
||||||
{workdir, "set-env-new-env-file-per-step", "push", "", platforms, secrets},
|
{workdir, "set-env-new-env-file-per-step", "push", "", platforms, secrets},
|
||||||
{workdir, "no-panic-on-invalid-composite-action", "push", "jobs failed due to invalid action", platforms, secrets},
|
{workdir, "no-panic-on-invalid-composite-action", "push", "jobs failed due to invalid action", platforms, secrets},
|
||||||
|
|
||||||
// services
|
|
||||||
{workdir, "services", "push", "", platforms, secrets},
|
|
||||||
{workdir, "services-host-network", "push", "", platforms, secrets},
|
|
||||||
{workdir, "services-with-container", "push", "", platforms, secrets},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, table := range tables {
|
for _, table := range tables {
|
||||||
|
|
|
@ -34,9 +34,6 @@ const (
|
||||||
stepStagePost
|
stepStagePost
|
||||||
)
|
)
|
||||||
|
|
||||||
// Controls how many symlinks are resolved for local and remote Actions
|
|
||||||
const maxSymlinkDepth = 10
|
|
||||||
|
|
||||||
func (s stepStage) String() string {
|
func (s stepStage) String() string {
|
||||||
switch s {
|
switch s {
|
||||||
case stepStagePre:
|
case stepStagePre:
|
||||||
|
@ -310,13 +307,3 @@ func mergeIntoMapCaseInsensitive(target map[string]string, maps ...map[string]st
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func symlinkJoin(filename, sym, parent string) (string, error) {
|
|
||||||
dir := path.Dir(filename)
|
|
||||||
dest := path.Join(dir, sym)
|
|
||||||
prefix := path.Clean(parent) + "/"
|
|
||||||
if strings.HasPrefix(dest, prefix) || prefix == "./" {
|
|
||||||
return dest, nil
|
|
||||||
}
|
|
||||||
return "", fmt.Errorf("symlink tries to access file '%s' outside of '%s'", strings.ReplaceAll(dest, "'", "''"), strings.ReplaceAll(parent, "'", "''"))
|
|
||||||
}
|
|
||||||
|
|
|
@ -3,10 +3,7 @@ package runner
|
||||||
import (
|
import (
|
||||||
"archive/tar"
|
"archive/tar"
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
"io"
|
||||||
"io/fs"
|
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
@ -45,33 +42,19 @@ func (sal *stepActionLocal) main() common.Executor {
|
||||||
localReader := func(ctx context.Context) actionYamlReader {
|
localReader := func(ctx context.Context) actionYamlReader {
|
||||||
_, cpath := getContainerActionPaths(sal.Step, path.Join(actionDir, ""), sal.RunContext)
|
_, cpath := getContainerActionPaths(sal.Step, path.Join(actionDir, ""), sal.RunContext)
|
||||||
return func(filename string) (io.Reader, io.Closer, error) {
|
return func(filename string) (io.Reader, io.Closer, error) {
|
||||||
spath := path.Join(cpath, filename)
|
tars, err := sal.RunContext.JobContainer.GetContainerArchive(ctx, path.Join(cpath, filename))
|
||||||
for i := 0; i < maxSymlinkDepth; i++ {
|
if err != nil {
|
||||||
tars, err := sal.RunContext.JobContainer.GetContainerArchive(ctx, spath)
|
common.Logger(context.Background()).Debugf("stepActionLocal reader %s failed %v", path.Join(cpath, filename), err)
|
||||||
if errors.Is(err, fs.ErrNotExist) {
|
return nil, nil, os.ErrNotExist
|
||||||
return nil, nil, err
|
|
||||||
} else if err != nil {
|
|
||||||
return nil, nil, fs.ErrNotExist
|
|
||||||
}
|
}
|
||||||
treader := tar.NewReader(tars)
|
treader := tar.NewReader(tars)
|
||||||
header, err := treader.Next()
|
if _, err := treader.Next(); err != nil {
|
||||||
if errors.Is(err, io.EOF) {
|
common.Logger(context.Background()).Debugf("stepActionLocal reader %s failed %v", path.Join(cpath, filename), err)
|
||||||
return nil, nil, os.ErrNotExist
|
return nil, nil, os.ErrNotExist
|
||||||
} else if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
}
|
||||||
if header.FileInfo().Mode()&os.ModeSymlink == os.ModeSymlink {
|
|
||||||
spath, err = symlinkJoin(spath, header.Linkname, cpath)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return treader, tars, nil
|
return treader, tars, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil, nil, fmt.Errorf("max depth %d of symlinks exceeded while reading %s", maxSymlinkDepth, spath)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
actionModel, err := sal.readAction(ctx, sal.Step, actionDir, "", localReader(ctx), os.WriteFile)
|
actionModel, err := sal.readAction(ctx, sal.Step, actionDir, "", localReader(ctx), os.WriteFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package runner
|
package runner
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"archive/tar"
|
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
@ -29,8 +28,6 @@ type stepActionRemote struct {
|
||||||
action *model.Action
|
action *model.Action
|
||||||
env map[string]string
|
env map[string]string
|
||||||
remoteAction *remoteAction
|
remoteAction *remoteAction
|
||||||
cacheDir string
|
|
||||||
resolvedSha string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var stepActionRemoteNewCloneExecutor = git.NewGitCloneExecutor
|
var stepActionRemoteNewCloneExecutor = git.NewGitCloneExecutor
|
||||||
|
@ -65,48 +62,6 @@ func (sar *stepActionRemote) prepareActionExecutor() common.Executor {
|
||||||
github.Token = sar.RunContext.Config.ReplaceGheActionTokenWithGithubCom
|
github.Token = sar.RunContext.Config.ReplaceGheActionTokenWithGithubCom
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if sar.RunContext.Config.ActionCache != nil {
|
|
||||||
cache := sar.RunContext.Config.ActionCache
|
|
||||||
|
|
||||||
var err error
|
|
||||||
sar.cacheDir = fmt.Sprintf("%s/%s", sar.remoteAction.Org, sar.remoteAction.Repo)
|
|
||||||
repoURL := sar.remoteAction.URL + "/" + sar.cacheDir
|
|
||||||
repoRef := sar.remoteAction.Ref
|
|
||||||
sar.resolvedSha, err = cache.Fetch(ctx, sar.cacheDir, repoURL, repoRef, github.Token)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed to fetch \"%s\" version \"%s\": %w", repoURL, repoRef, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
remoteReader := func(ctx context.Context) actionYamlReader {
|
|
||||||
return func(filename string) (io.Reader, io.Closer, error) {
|
|
||||||
spath := path.Join(sar.remoteAction.Path, filename)
|
|
||||||
for i := 0; i < maxSymlinkDepth; i++ {
|
|
||||||
tars, err := cache.GetTarArchive(ctx, sar.cacheDir, sar.resolvedSha, spath)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, os.ErrNotExist
|
|
||||||
}
|
|
||||||
treader := tar.NewReader(tars)
|
|
||||||
header, err := treader.Next()
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, os.ErrNotExist
|
|
||||||
}
|
|
||||||
if header.FileInfo().Mode()&os.ModeSymlink == os.ModeSymlink {
|
|
||||||
spath, err = symlinkJoin(spath, header.Linkname, ".")
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return treader, tars, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil, nil, fmt.Errorf("max depth %d of symlinks exceeded while reading %s", maxSymlinkDepth, spath)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
actionModel, err := sar.readAction(ctx, sar.Step, sar.resolvedSha, sar.remoteAction.Path, remoteReader(ctx), os.WriteFile)
|
|
||||||
sar.action = actionModel
|
|
||||||
return 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{
|
||||||
|
@ -120,9 +75,6 @@ func (sar *stepActionRemote) prepareActionExecutor() common.Executor {
|
||||||
For GitHub, they are the same, always github.com.
|
For GitHub, they are the same, always github.com.
|
||||||
But for Gitea, tasks triggered by a.com can clone actions from b.com.
|
But for Gitea, tasks triggered by a.com can clone actions from b.com.
|
||||||
*/
|
*/
|
||||||
OfflineMode: sar.RunContext.Config.ActionOfflineMode,
|
|
||||||
|
|
||||||
InsecureSkipTLS: sar.cloneSkipTLS(), // For Gitea
|
|
||||||
})
|
})
|
||||||
var ntErr common.Executor
|
var ntErr common.Executor
|
||||||
if err := gitClone(ctx); err != nil {
|
if err := gitClone(ctx); err != nil {
|
||||||
|
@ -260,22 +212,6 @@ func (sar *stepActionRemote) getCompositeSteps() *compositeSteps {
|
||||||
return sar.compositeSteps
|
return sar.compositeSteps
|
||||||
}
|
}
|
||||||
|
|
||||||
// For Gitea
|
|
||||||
// cloneSkipTLS returns true if the runner can clone an action from the Gitea instance
|
|
||||||
func (sar *stepActionRemote) cloneSkipTLS() bool {
|
|
||||||
if !sar.RunContext.Config.InsecureSkipTLS {
|
|
||||||
// Return false if the Gitea instance is not an insecure instance
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if sar.remoteAction.URL == "" {
|
|
||||||
// Empty URL means the default action instance should be used
|
|
||||||
// Return true if the URL of the Gitea instance is the same as the URL of the default action instance
|
|
||||||
return sar.RunContext.Config.DefaultActionInstance == sar.RunContext.Config.GitHubInstance
|
|
||||||
}
|
|
||||||
// Return true if the URL of the remote action is the same as the URL of the Gitea instance
|
|
||||||
return sar.remoteAction.URL == sar.RunContext.Config.GitHubInstance
|
|
||||||
}
|
|
||||||
|
|
||||||
type remoteAction struct {
|
type remoteAction struct {
|
||||||
URL string
|
URL string
|
||||||
Org string
|
Org string
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
name: services-host-network
|
|
||||||
on: push
|
|
||||||
jobs:
|
|
||||||
services-host-network:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
services:
|
|
||||||
nginx:
|
|
||||||
image: "nginx:latest"
|
|
||||||
ports:
|
|
||||||
- "8080:80"
|
|
||||||
steps:
|
|
||||||
- run: apt-get -qq update && apt-get -yqq install --no-install-recommends curl net-tools
|
|
||||||
- run: netstat -tlpen
|
|
||||||
- run: curl -v http://localhost:8080
|
|
|
@ -1,16 +0,0 @@
|
||||||
name: services-with-containers
|
|
||||||
on: push
|
|
||||||
jobs:
|
|
||||||
services-with-containers:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
# https://docs.github.com/en/actions/using-containerized-services/about-service-containers#running-jobs-in-a-container
|
|
||||||
container:
|
|
||||||
image: "ubuntu:latest"
|
|
||||||
services:
|
|
||||||
nginx:
|
|
||||||
image: "nginx:latest"
|
|
||||||
ports:
|
|
||||||
- "8080:80"
|
|
||||||
steps:
|
|
||||||
- run: apt-get -qq update && apt-get -yqq install --no-install-recommends curl
|
|
||||||
- run: curl -v http://nginx:80
|
|
|
@ -1,21 +0,0 @@
|
||||||
{
|
|
||||||
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
|
||||||
"extends": ["local>forgejo/renovate-config"],
|
|
||||||
"packageRules": [
|
|
||||||
{
|
|
||||||
"description": "Disable runner test data",
|
|
||||||
"matchFileNames": ["pkg/runner/testdata/**"],
|
|
||||||
"enabled": false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Require approval for all dependencies",
|
|
||||||
"matchDepNames": ["/.+/"],
|
|
||||||
"dependencyDashboardApproval": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Separate minor and patch for some packages",
|
|
||||||
"matchDepNames": ["github.com/rhysd/actionlint"],
|
|
||||||
"separateMinorPatch": true
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
Loading…
Reference in a new issue