Showing preview only (2,695K chars total). Download the full file or copy to clipboard to get everything.
Repository: nektos/act
Branch: master
Commit: 9e6190d2bd63
Files: 411
Total size: 2.5 MB
Directory structure:
gitextract_bc5cehu6/
├── .actrc
├── .codespellrc
├── .editorconfig
├── .github/
│ ├── FUNDING.yml
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug_report.yml
│ │ ├── config.yml
│ │ ├── feature_template.yml
│ │ └── wiki_issue.yml
│ ├── actions/
│ │ └── choco/
│ │ ├── Dockerfile
│ │ ├── action.yml
│ │ └── entrypoint.sh
│ ├── dependabot.yml
│ └── workflows/
│ ├── .gitignore
│ ├── checks.yml
│ ├── codespell.yml
│ ├── promote.yml
│ ├── release.yml
│ └── stale.yml
├── .gitignore
├── .gitleaksignore
├── .golangci.yml
├── .goreleaser.yml
├── .markdownlint.yml
├── .mega-linter.yml
├── .mergify.yml
├── .prettierignore
├── .prettierrc.yml
├── CONTRIBUTING.md
├── IMAGES.md
├── LICENSE
├── Makefile
├── README.md
├── VERIFICATION
├── VERSION
├── act-cli.nuspec
├── cmd/
│ ├── dir.go
│ ├── execute_test.go
│ ├── graph.go
│ ├── input.go
│ ├── list.go
│ ├── notices.go
│ ├── platforms.go
│ ├── root.go
│ ├── root_test.go
│ ├── secrets.go
│ └── testdata/
│ ├── env.actrc
│ ├── secrets.yml
│ ├── simple.actrc
│ └── split.actrc
├── codecov.yml
├── go.mod
├── go.sum
├── install.sh
├── main.go
├── main_test.go
└── pkg/
├── artifactcache/
│ ├── doc.go
│ ├── handler.go
│ ├── handler_test.go
│ ├── model.go
│ ├── storage.go
│ └── testdata/
│ └── example/
│ └── example.yaml
├── artifacts/
│ ├── artifact.pb.go
│ ├── artifacts_v4.go
│ ├── server.go
│ ├── server_test.go
│ └── testdata/
│ ├── GHSL-2023-004/
│ │ └── artifacts.yml
│ ├── upload-and-download/
│ │ └── artifacts.yml
│ └── v4/
│ └── artifacts.yml
├── common/
│ ├── auth.go
│ ├── auth_test.go
│ ├── cartesian.go
│ ├── cartesian_test.go
│ ├── context.go
│ ├── context_test.go
│ ├── draw.go
│ ├── dryrun.go
│ ├── executor.go
│ ├── executor_test.go
│ ├── file.go
│ ├── git/
│ │ ├── git.go
│ │ └── git_test.go
│ ├── job_error.go
│ ├── line_writer.go
│ ├── line_writer_test.go
│ ├── logger.go
│ └── outbound_ip.go
├── container/
│ ├── DOCKER_LICENSE
│ ├── container_types.go
│ ├── docker_auth.go
│ ├── docker_build.go
│ ├── docker_cli.go
│ ├── docker_cli_test.go
│ ├── docker_images.go
│ ├── docker_images_test.go
│ ├── docker_logger.go
│ ├── docker_network.go
│ ├── docker_pull.go
│ ├── docker_pull_test.go
│ ├── docker_run.go
│ ├── docker_run_test.go
│ ├── docker_socket.go
│ ├── docker_socket_test.go
│ ├── docker_stub.go
│ ├── docker_volume.go
│ ├── executions_environment.go
│ ├── host_environment.go
│ ├── host_environment_test.go
│ ├── linux_container_environment_extensions.go
│ ├── linux_container_environment_extensions_test.go
│ ├── parse_env_file.go
│ ├── testdata/
│ │ ├── Dockerfile
│ │ ├── docker-pull-options/
│ │ │ └── config.json
│ │ ├── scratch/
│ │ │ └── test.txt
│ │ ├── utf16.env
│ │ ├── utf16be.env
│ │ ├── utf8.env
│ │ ├── valid.env
│ │ └── valid.label
│ ├── util.go
│ ├── util_openbsd_mips64.go
│ ├── util_plan9.go
│ └── util_windows.go
├── exprparser/
│ ├── functions.go
│ ├── functions_test.go
│ ├── interpreter.go
│ ├── interpreter_test.go
│ └── testdata/
│ ├── for-hashing-1.txt
│ ├── for-hashing-2.txt
│ └── for-hashing-3/
│ ├── data.txt
│ └── nested/
│ └── nested-data.txt
├── filecollector/
│ ├── file_collector.go
│ └── file_collector_test.go
├── gh/
│ ├── gh.go
│ └── gh_test.go
├── lookpath/
│ ├── LICENSE
│ ├── env.go
│ ├── error.go
│ ├── lp_js.go
│ ├── lp_plan9.go
│ ├── lp_unix.go
│ └── lp_windows.go
├── model/
│ ├── action.go
│ ├── anchors.go
│ ├── anchors_test.go
│ ├── github_context.go
│ ├── github_context_test.go
│ ├── job_context.go
│ ├── planner.go
│ ├── planner_test.go
│ ├── step_result.go
│ ├── testdata/
│ │ ├── container-volumes/
│ │ │ └── push.yml
│ │ ├── empty-workflow/
│ │ │ └── push.yml
│ │ ├── invalid-job-name/
│ │ │ ├── invalid-1.yml
│ │ │ ├── invalid-2.yml
│ │ │ ├── valid-1.yml
│ │ │ └── valid-2.yml
│ │ ├── nested/
│ │ │ ├── success.yml
│ │ │ └── workflows/
│ │ │ └── fail.yml
│ │ └── strategy/
│ │ └── push.yml
│ ├── workflow.go
│ └── workflow_test.go
├── runner/
│ ├── action.go
│ ├── action_cache.go
│ ├── action_cache_offline_mode.go
│ ├── action_cache_test.go
│ ├── action_composite.go
│ ├── action_test.go
│ ├── command.go
│ ├── command_test.go
│ ├── container_mock_test.go
│ ├── expression.go
│ ├── expression_test.go
│ ├── hashfiles/
│ │ └── index.js
│ ├── job_executor.go
│ ├── job_executor_test.go
│ ├── local_repository_cache.go
│ ├── logger.go
│ ├── res/
│ │ └── trampoline.js
│ ├── reusable_workflow.go
│ ├── run_context.go
│ ├── run_context_test.go
│ ├── runner.go
│ ├── runner_test.go
│ ├── step.go
│ ├── step_action_local.go
│ ├── step_action_local_test.go
│ ├── step_action_remote.go
│ ├── step_action_remote_test.go
│ ├── step_docker.go
│ ├── step_docker_test.go
│ ├── step_factory.go
│ ├── step_factory_test.go
│ ├── step_run.go
│ ├── step_run_test.go
│ ├── step_test.go
│ └── testdata/
│ ├── .github/
│ │ └── workflows/
│ │ ├── local-reusable-and-dispatch.yml
│ │ ├── local-reusable-workflow-no-inputs-array.yml
│ │ ├── local-reusable-workflow-no-inputs-string.yml
│ │ └── local-reusable-workflow.yml
│ ├── GITHUB_ENV-use-in-env-ctx/
│ │ └── push.yml
│ ├── GITHUB_STATE/
│ │ └── push.yml
│ ├── act-composite-env-test/
│ │ ├── action1/
│ │ │ └── action.yml
│ │ ├── action2/
│ │ │ └── action.yml
│ │ └── push.yml
│ ├── action-cache-v2-fetch-failure-is-job-error/
│ │ └── push.yml
│ ├── actions/
│ │ ├── action1/
│ │ │ ├── Dockerfile
│ │ │ └── action.yml
│ │ ├── composite-fail-with-output/
│ │ │ └── action.yml
│ │ ├── docker-local/
│ │ │ ├── Dockerfile
│ │ │ ├── action.yml
│ │ │ └── entrypoint.sh
│ │ ├── docker-local-noargs/
│ │ │ ├── Dockerfile
│ │ │ ├── action.yml
│ │ │ └── entrypoint.sh
│ │ ├── docker-url/
│ │ │ └── action.yml
│ │ ├── node12/
│ │ │ ├── README.md
│ │ │ ├── action.yml
│ │ │ ├── dist/
│ │ │ │ └── index.js
│ │ │ ├── index.js
│ │ │ └── package.json
│ │ ├── node16/
│ │ │ ├── README.md
│ │ │ ├── action.yml
│ │ │ ├── dist/
│ │ │ │ └── index.js
│ │ │ ├── index.js
│ │ │ └── package.json
│ │ └── node20/
│ │ ├── README.md
│ │ ├── action.yml
│ │ ├── dist/
│ │ │ └── index.js
│ │ ├── index.js
│ │ └── package.json
│ ├── actions-environment-and-context-tests/
│ │ ├── docker/
│ │ │ ├── Dockerfile
│ │ │ ├── action.yml
│ │ │ └── entrypoint.sh
│ │ ├── js/
│ │ │ ├── action.yml
│ │ │ └── index.js
│ │ └── push.yml
│ ├── basic/
│ │ └── push.yml
│ ├── checkout/
│ │ └── push.yml
│ ├── commands/
│ │ └── push.yml
│ ├── composite-fail-with-output/
│ │ └── push.yml
│ ├── container-hostname/
│ │ └── push.yml
│ ├── defaults-run/
│ │ └── main.yaml
│ ├── dir with spaces/
│ │ └── push.yml
│ ├── do-not-leak-step-env-in-composite/
│ │ └── push.yml
│ ├── docker-action-custom-path/
│ │ └── push.yml
│ ├── docker-action-host-env/
│ │ ├── action/
│ │ │ ├── Dockerfile
│ │ │ ├── action.yml
│ │ │ └── entrypoint.sh
│ │ └── push.yml
│ ├── ensure-post-steps/
│ │ ├── action-composite/
│ │ │ └── action.yml
│ │ ├── action-post/
│ │ │ ├── action.yml
│ │ │ ├── main.js
│ │ │ └── post.js
│ │ └── push.yml
│ ├── env-and-path/
│ │ └── push.yaml
│ ├── environment-files/
│ │ └── push.yaml
│ ├── environment-files-parser-bug/
│ │ └── push.yaml
│ ├── environment-variables/
│ │ └── push.yml
│ ├── evalenv/
│ │ └── push.yml
│ ├── evalmatrix/
│ │ └── push.yml
│ ├── evalmatrix-merge-array/
│ │ └── push.yml
│ ├── evalmatrix-merge-map/
│ │ └── push.yml
│ ├── evalmatrixneeds/
│ │ └── push.yml
│ ├── evalmatrixneeds2/
│ │ └── push.yml
│ ├── fail/
│ │ └── push.yml
│ ├── if-env-act/
│ │ └── push.yml
│ ├── if-expressions/
│ │ └── push.yml
│ ├── input-from-cli/
│ │ └── input.yml
│ ├── inputs-via-env-context/
│ │ ├── action/
│ │ │ └── action.yml
│ │ └── push.yml
│ ├── issue-104/
│ │ └── main.yaml
│ ├── issue-1195/
│ │ └── push.yml
│ ├── issue-122/
│ │ └── main.yaml
│ ├── issue-141/
│ │ └── main.yaml
│ ├── issue-1595/
│ │ ├── missing.yml
│ │ ├── no-event.yml
│ │ └── no-first.yml
│ ├── issue-597/
│ │ └── spelling.yaml
│ ├── issue-598/
│ │ └── spelling.yml
│ ├── job-container/
│ │ └── push.yml
│ ├── job-container-invalid-credentials/
│ │ └── push.yml
│ ├── job-container-non-root/
│ │ └── push.yml
│ ├── job-needs-context-contains-result/
│ │ └── push.yml
│ ├── job-nil-step/
│ │ └── push.yml
│ ├── job-status-check/
│ │ └── push.yml
│ ├── local-action-docker-url/
│ │ └── push.yml
│ ├── local-action-dockerfile/
│ │ └── push.yml
│ ├── local-action-js/
│ │ └── push.yml
│ ├── local-action-via-composite-dockerfile/
│ │ ├── action/
│ │ │ └── action.yml
│ │ └── push.yml
│ ├── local-remote-action-overrides/
│ │ ├── config/
│ │ │ └── config.yml
│ │ └── push.yml
│ ├── localdockerimagetest_/
│ │ └── Dockerfile
│ ├── mask-values/
│ │ ├── composite/
│ │ │ └── action.yml
│ │ └── push.yml
│ ├── matrix/
│ │ └── push.yml
│ ├── matrix-exitcode/
│ │ └── push.yml
│ ├── matrix-include-exclude/
│ │ └── push.yml
│ ├── matrix-with-user-inclusions/
│ │ └── push.yml
│ ├── mysql-service-container-with-health-check/
│ │ └── push.yml
│ ├── networking/
│ │ └── push.yml
│ ├── nix-prepend-path/
│ │ └── push.yml
│ ├── no-panic-on-invalid-composite-action/
│ │ └── push.yml
│ ├── node/
│ │ └── push.yml
│ ├── non-existent-action/
│ │ └── push.yml
│ ├── outputs/
│ │ └── push.yml
│ ├── parallel/
│ │ └── push.yml
│ ├── path-handling/
│ │ ├── action/
│ │ │ └── action.yml
│ │ └── push.yml
│ ├── post-step-failure-is-job-failure/
│ │ ├── post-step-failure/
│ │ │ ├── action.yml
│ │ │ ├── main.js
│ │ │ └── post.js
│ │ └── push.yml
│ ├── pull-request/
│ │ ├── event.json
│ │ └── main.yaml
│ ├── python/
│ │ └── main.yml
│ ├── remote-action-composite-action-ref/
│ │ └── push.yml
│ ├── remote-action-composite-js-pre-with-defaults/
│ │ └── push.yml
│ ├── remote-action-docker/
│ │ └── push.yml
│ ├── remote-action-docker-new-cache/
│ │ ├── config/
│ │ │ └── config.yml
│ │ └── push.yml
│ ├── remote-action-js/
│ │ └── push.yml
│ ├── remote-action-js-node-user/
│ │ └── push.yml
│ ├── runs-on/
│ │ └── push.yml
│ ├── secrets/
│ │ ├── .actrc
│ │ └── push.yml
│ ├── services/
│ │ └── push.yaml
│ ├── services-empty-image/
│ │ └── push.yaml
│ ├── services-host-network/
│ │ └── push.yml
│ ├── services-with-container/
│ │ └── push.yml
│ ├── set-env-new-env-file-per-step/
│ │ └── push.yml
│ ├── set-env-step-env-override/
│ │ └── push.yml
│ ├── shells/
│ │ ├── bash/
│ │ │ └── push.yml
│ │ ├── custom/
│ │ │ └── push.yml
│ │ ├── defaults/
│ │ │ └── push.yml
│ │ ├── pwsh/
│ │ │ └── push.yml
│ │ ├── python/
│ │ │ └── push.yml
│ │ └── sh/
│ │ └── push.yml
│ ├── steps-context/
│ │ ├── conclusion/
│ │ │ └── push.yml
│ │ └── outcome/
│ │ └── push.yml
│ ├── stepsummary/
│ │ └── push.yml
│ ├── uses-action-with-pre-and-post-step/
│ │ ├── last-action/
│ │ │ ├── action.yml
│ │ │ ├── main.js
│ │ │ └── post.js
│ │ └── push.yml
│ ├── uses-and-run-in-one-step/
│ │ └── push.yml
│ ├── uses-composite/
│ │ ├── composite_action/
│ │ │ └── action.yml
│ │ └── push.yml
│ ├── uses-composite-check-for-input-collision/
│ │ ├── action-with-pre-and-post/
│ │ │ ├── action.yml
│ │ │ ├── main.js
│ │ │ ├── post.js
│ │ │ └── pre.js
│ │ ├── composite_action/
│ │ │ └── action.yml
│ │ └── push.yml
│ ├── uses-composite-check-for-input-in-if-uses/
│ │ ├── composite_action/
│ │ │ └── action.yml
│ │ └── push.yml
│ ├── uses-composite-check-for-input-shadowing/
│ │ ├── action-with-pre-and-post/
│ │ │ ├── action.yml
│ │ │ ├── main.js
│ │ │ ├── post.js
│ │ │ └── pre.js
│ │ ├── composite_action/
│ │ │ └── action.yml
│ │ └── push.yml
│ ├── uses-composite-with-error/
│ │ ├── composite_action2/
│ │ │ └── action.yml
│ │ └── push.yml
│ ├── uses-composite-with-inputs/
│ │ ├── action/
│ │ │ └── action.yml
│ │ ├── composite/
│ │ │ └── action.yml
│ │ └── push.yml
│ ├── uses-composite-with-pre-and-post-steps/
│ │ ├── action-with-pre-and-post/
│ │ │ ├── action.yml
│ │ │ ├── main.js
│ │ │ ├── post.js
│ │ │ └── pre.js
│ │ ├── composite_action/
│ │ │ └── action.yml
│ │ ├── last-action/
│ │ │ ├── action.yml
│ │ │ ├── main.js
│ │ │ └── post.js
│ │ └── push.yml
│ ├── uses-docker-url/
│ │ └── push.yml
│ ├── uses-github-empty/
│ │ └── push.yml
│ ├── uses-github-full-sha/
│ │ └── main.yml
│ ├── uses-github-noref/
│ │ └── push.yml
│ ├── uses-github-path/
│ │ └── push.yml
│ ├── uses-github-root/
│ │ └── push.yml
│ ├── uses-github-short-sha/
│ │ └── main.yml
│ ├── uses-nested-composite/
│ │ ├── composite_action2/
│ │ │ └── action.yml
│ │ └── push.yml
│ ├── uses-workflow/
│ │ ├── local-workflow.yml
│ │ └── push.yml
│ ├── uses-workflow-defaults/
│ │ └── workflow_dispatch.yml
│ ├── windows-add-env/
│ │ ├── action/
│ │ │ └── action.yml
│ │ └── push.yml
│ ├── windows-add-env-powershell-5/
│ │ ├── action/
│ │ │ └── action.yml
│ │ └── push.yml
│ ├── windows-prepend-path/
│ │ └── push.yml
│ ├── windows-prepend-path-powershell-5/
│ │ └── push.yml
│ ├── windows-shell-cmd/
│ │ └── push.yml
│ ├── workdir/
│ │ ├── canary
│ │ └── push.yml
│ ├── workflow_call_inputs/
│ │ ├── event.json
│ │ └── workflow_call_inputs.yml
│ ├── workflow_dispatch/
│ │ ├── event.json
│ │ └── workflow_dispatch.yml
│ ├── workflow_dispatch-scalar/
│ │ └── workflow_dispatch.yml
│ ├── workflow_dispatch-scalar-composite-action/
│ │ └── workflow_dispatch.yml
│ └── workflow_dispatch_no_inputs_mapping/
│ └── workflow_dispatch.yml
├── schema/
│ ├── action_schema.json
│ ├── schema.go
│ ├── schema_test.go
│ └── workflow_schema.json
└── workflowpattern/
├── trace_writer.go
├── workflow_pattern.go
└── workflow_pattern_test.go
================================================
FILE CONTENTS
================================================
================================================
FILE: .actrc
================================================
================================================
FILE: .codespellrc
================================================
[codespell]
# Ref: https://github.com/codespell-project/codespell#using-a-config-file
skip = .git*,go.sum,package-lock.json,*.min.*,.codespellrc,testdata,./pkg/runner/hashfiles/index.js
check-hidden = true
ignore-regex = .*Te\{0\}st.*
# ignore-words-list =
================================================
FILE: .editorconfig
================================================
root = true
[*]
end_of_line = lf
charset = utf-8
insert_final_newline = true
trim_trailing_whitespace = true
indent_style = tab
indent_size = 4
[{*.md,*_test.go}]
indent_style = unset
indent_size = unset
[**/Dockerfile]
indent_style = space
indent_size = 2
[*.{yml,yaml,js,json,sh,nuspec}]
indent_style = space
indent_size = 2
================================================
FILE: .github/FUNDING.yml
================================================
github: cplee
================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.yml
================================================
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
================================================
FILE: .github/ISSUE_TEMPLATE/config.yml
================================================
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: Want to contribute to act?
url: https://github.com/nektos/act/blob/master/CONTRIBUTING.md
about: Be sure to read contributing guidelines!
================================================
FILE: .github/ISSUE_TEMPLATE/feature_template.yml
================================================
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
================================================
FILE: .github/ISSUE_TEMPLATE/wiki_issue.yml
================================================
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
================================================
FILE: .github/actions/choco/Dockerfile
================================================
FROM alpine:3.21
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/community 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"]
================================================
FILE: .github/actions/choco/action.yml
================================================
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'
================================================
FILE: .github/actions/choco/entrypoint.sh
================================================
#!/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
================================================
FILE: .github/dependabot.yml
================================================
# 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://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
version: 2
updates:
- package-ecosystem: 'github-actions'
directory: '/'
schedule:
interval: 'monthly'
groups:
dependencies:
patterns:
- '*'
- package-ecosystem: 'gomod'
directory: '/'
schedule:
interval: 'monthly'
groups:
dependencies:
patterns:
- '*'
================================================
FILE: .github/workflows/.gitignore
================================================
test-*.yml
================================================
FILE: .github/workflows/checks.yml
================================================
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@v4
with:
fetch-depth: 0
- uses: actions/setup-go@v5
with:
go-version-file: go.mod
- uses: golangci/golangci-lint-action@v6.5.0
with:
version: v1.64.8
- uses: megalinter/megalinter/flavors/go@v8.4.2
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@v4
with:
fetch-depth: 2
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- uses: actions/setup-go@v5
with:
go-version-file: go.mod
- name: Run Tests
run: go run gotest.tools/gotestsum@latest --junitfile unit-tests.xml --format pkgname -- -v -cover -coverpkg=./... -coverprofile=coverage.txt -covermode=atomic -timeout 20m ./...
- name: Test Summary
uses: test-summary/action@v2
with:
paths: "unit-tests.xml"
if: always()
- 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: Run act from cli without docker support
run: go run -tags WITHOUT_DOCKER main.go -P ubuntu-latest=-self-hosted -C ./pkg/runner/testdata/ -W ./local-action-js/push.yml
- name: Upload Codecov report
uses: codecov/codecov-action@v5
with:
files: coverage.txt
fail_ci_if_error: true # optional (default = false)
token: ${{ secrets.CODECOV_TOKEN }}
test-host:
strategy:
matrix:
os:
- windows-latest
- macos-latest
name: test-host-${{matrix.os}}
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 2
- uses: actions/setup-go@v5
with:
go-version-file: go.mod
- name: Run Tests
run: go run gotest.tools/gotestsum@latest --junitfile unit-tests.xml --format pkgname -- -v -cover -coverpkg=./... -coverprofile=coverage.txt -covermode=atomic -timeout 20m -run ^TestRunEventHostEnvironment$ ./...
shell: bash
- name: Test Summary
uses: test-summary/action@v2
with:
paths: "unit-tests.xml"
if: always()
snapshot:
name: snapshot
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version-file: go.mod
- name: GoReleaser
uses: goreleaser/goreleaser-action@v6
with:
version: latest
args: release --snapshot --clean
- name: Capture x86_64 (64-bit) Linux binary
if: ${{ !env.ACT }}
uses: actions/upload-artifact@v4
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@v4
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@v4
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@v4
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@v4
with:
name: act-linux-armv7
path: dist/act_linux_arm_7/act
- name: Capture riscv64 (64-bit) Linux binary
if: ${{ !env.ACT }}
uses: actions/upload-artifact@v4
with:
name: act-linux-riscv64
path: dist/act_linux_riscv64/act
- name: Capture x86_64 (64-bit) Windows binary
if: ${{ !env.ACT }}
uses: actions/upload-artifact@v4
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@v4
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@v4
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@v4
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@v4
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@v4
with:
name: act-macos-arm64
path: dist/act_darwin_arm64/act
- name: Chocolatey
uses: ./.github/actions/choco
with:
version: v0.0.0-pr
================================================
FILE: .github/workflows/codespell.yml
================================================
# Codespell configuration is within .codespellrc
---
name: Codespell
on:
push:
branches: [master]
pull_request:
branches: [master]
permissions:
contents: read
jobs:
codespell:
name: Check for spelling errors
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Codespell
uses: codespell-project/actions-codespell@v2
================================================
FILE: .github/workflows/promote.yml
================================================
name: promote
on:
schedule:
- cron: '0 2 1 * *'
workflow_dispatch: {}
jobs:
release:
name: promote
runs-on: ubuntu-latest
environment: promote
steps:
- uses: actions/checkout@v4
id: checkout
env:
has_promote_token: ${{ secrets.PROMOTE_TOKEN && '1' || '' }}
if: env.has_promote_token
with:
fetch-depth: 0
ref: master
token: ${{ secrets.PROMOTE_TOKEN }}
- uses: fregante/setup-git-user@v2
if: steps.checkout.conclusion != 'skipped'
- uses: actions/setup-go@v5
if: steps.checkout.conclusion != 'skipped'
with:
go-version-file: go.mod
- run: make promote
if: steps.checkout.conclusion != 'skipped'
================================================
FILE: .github/workflows/release.yml
================================================
name: release
on:
push:
tags:
- v*
permissions:
contents: write
actions: write
jobs:
release:
name: release
runs-on: ubuntu-latest
environment: release
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-go@v5
with:
go-version-file: go.mod
- name: GoReleaser
uses: goreleaser/goreleaser-action@v6
with:
version: latest
args: release --clean
env:
GITHUB_TOKEN: ${{ secrets.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@v7
with:
github-token: ${{ secrets.GH_ACT_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,
});
================================================
FILE: .github/workflows/stale.yml
================================================
name: 'Close stale issues'
on:
workflow_dispatch:
jobs:
stale:
name: Stale
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v9
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
================================================
FILE: .gitignore
================================================
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib
# Test binary, build with `go test -c`
*.test
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
/dist/
.todo
*.nupkg
.vscode/
.idea/
# Path for actions cache created when running tests
pkg/runner/act/
# act binary
dist/local/act
coverage.txt
unit-tests.xml
.env
.secrets
# megalinter
report/
================================================
FILE: .gitleaksignore
================================================
b910a42edfab7a02b08a52ecef203fd419725642:pkg/container/testdata/docker-pull-options/config.json:generic-api-key:4
710a3ac94c3dc0eaf680d417c87f37f92b4887f4:pkg/container/docker_pull_test.go:generic-api-key:45
================================================
FILE: .golangci.yml
================================================
# Minimum golangci-lint version required: v1.46.0
run:
timeout: 3m
issues:
exclude-dirs:
- report # megalinter results+fixes
max-issues-per-linter: 0
max-same-issues: 0
linters-settings:
gocyclo:
# minimal code complexity to report, 30 by default (but we recommend 10-20)
min-complexity: 20
gocritic:
disabled-checks:
- ifElseChain
importas:
alias:
- pkg: 'github.com/sirupsen/logrus'
alias: log
- pkg: 'github.com/stretchr/testify/assert'
alias: assert
depguard:
rules:
main:
deny:
- pkg: github.com/pkg/errors
desc: Please use "errors" package from standard library
- pkg: gotest.tools/v3
desc: Please keep tests unified using only github.com/stretchr/testify
- pkg: log
desc: Please keep logging unified using only github.com/sirupsen/logrus
linters:
enable:
- gosimple
- staticcheck
- unused
- govet
- revive
- gocyclo
- gosec
- unconvert
- dupl
- nakedret
- prealloc
- copyloopvar
- gocritic
- goimports
- whitespace
- misspell
- depguard
- importas
- contextcheck
- nolintlint
- revive
================================================
FILE: .goreleaser.yml
================================================
version: 2
before:
hooks:
- go mod tidy
builds:
- env:
- CGO_ENABLED=0
goos:
- darwin
- linux
- windows
goarch:
- amd64
- '386'
- arm64
- arm
- riscv64
goarm:
- '6'
- '7'
ignore:
- goos: windows
goarm: '6'
checksum:
name_template: 'checksums.txt'
archives:
- name_template: >-
{{ .ProjectName }}_
{{- title .Os }}_
{{- if eq .Arch "amd64" }}x86_64
{{- else if eq .Arch "386" }}i386
{{- else }}{{ .Arch }}{{ end }}
{{- if .Arm }}v{{ .Arm }}{{ end }}
format_overrides:
- goos: windows
formats: [zip]
changelog:
groups:
- title: 'New Features'
regexp: "^.*feat[(\\w)]*:+.*$"
order: 0
- title: 'Bug fixes'
regexp: "^.*fix[(\\w)]*:+.*$"
order: 1
- title: 'Documentation updates'
regexp: "^.*docs[(\\w)]*:+.*$"
order: 2
- title: 'Other'
order: 999
release:
prerelease: auto
mode: append
================================================
FILE: .markdownlint.yml
================================================
# Default state for all rules
default: true
# MD013/line-length - Line length
MD013:
line_length: 1024
# MD033/no-inline-html - Inline HTML
MD033: false
# MD041/first-line-heading/first-line-h1 - First line in a file should be a top-level heading
MD041: false
================================================
FILE: .mega-linter.yml
================================================
---
APPLY_FIXES: none
DISABLE:
- ACTION
- BASH
- COPYPASTE
- DOCKERFILE
- GO
- JAVASCRIPT
- SPELL
DISABLE_LINTERS:
- YAML_YAMLLINT
- MARKDOWN_MARKDOWN_TABLE_FORMATTER
- MARKDOWN_MARKDOWN_LINK_CHECK
- REPOSITORY_CHECKOV
- REPOSITORY_TRIVY
FILTER_REGEX_EXCLUDE: (.*testdata/*|install.sh|pkg/container/docker_cli.go|pkg/container/DOCKER_LICENSE|VERSION)
MARKDOWN_MARKDOWNLINT_CONFIG_FILE: .markdownlint.yml
PARALLEL: false
PRINT_ALPACA: false
================================================
FILE: .mergify.yml
================================================
merge_queue:
max_parallel_checks: 1
pull_request_rules:
- name: warn on conflicts
conditions:
- -draft
- -closed
- -merged
- conflict
actions:
label:
add:
- conflict
- name: remove conflict label if not needed
conditions:
- -conflict
actions:
label:
remove:
- conflict
- name: warn on needs-work
conditions:
- -draft
- -closed
- -merged
- or:
- check-failure=lint
- check-failure=test-linux
- check-failure=codecov/patch
- check-failure=codecov/project
- check-failure=snapshot
actions:
label:
add:
- needs-work
- name: remove needs-work label if not needed
conditions:
- check-success=lint
- check-success=test-linux
- check-success=codecov/patch
- check-success=codecov/project
- check-success=snapshot
actions:
label:
remove:
- needs-work
- name: Automatic merge on approval
conditions: []
actions:
queue:
queue_rules:
- name: default
batch_size: 1
queue_conditions: &queue_conditions
- '#changes-requested-reviews-by=0'
- or:
- 'approved-reviews-by=@nektos/act-committers'
- 'author~=^dependabot(|-preview)\[bot\]$'
- and:
- 'approved-reviews-by=@nektos/act-maintainers'
- '#approved-reviews-by>=2'
- and:
- 'author=@nektos/act-maintainers'
- 'approved-reviews-by=@nektos/act-maintainers'
- '#approved-reviews-by>=1'
- -draft
- -merged
- -closed
- check-success=lint
- check-success=test-linux
- check-success=codecov/patch
- check-success=codecov/project
- check-success=snapshot
merge_conditions: *queue_conditions
merge_method: squash
================================================
FILE: .prettierignore
================================================
**/testdata
pkg/runner/res
================================================
FILE: .prettierrc.yml
================================================
overrides:
- files: '*.yml'
options:
singleQuote: true
- files: '*.json'
options:
singleQuote: false
================================================
FILE: CONTRIBUTING.md
================================================
# Contributing to Act
Help wanted! We'd love your contributions to Act. Please review the following guidelines before contributing. Also, feel free to propose changes to these guidelines by updating this file and submitting a pull request.
- [I have a question...](#questions)
- [I found a bug...](#bugs)
- [I have a feature request...](#features)
- [I have a contribution to share...](#process)
## <a id="questions"></a> Have a Question?
Please don't open a GitHub issue for questions about how to use `act`, as the goal is to use issues for managing bugs and feature requests. Issues that are related to general support will be closed and redirected to [discussions](https://github.com/nektos/act/discussions).
For all support related questions, please [open a discussion post](https://github.com/nektos/act/discussions/new/choose).
## <a id="bugs"></a> Found a Bug?
If you've identified a bug in `act`, please [submit an issue](#issue) to our GitHub repo: [nektos/act](https://github.com/nektos/act/issues/new). Please also feel free to submit a [Pull Request](#pr) with a fix for the bug!
## <a id="features"></a> Have a Feature Request?
All feature requests should start with [submitting an issue](#issue) documenting the user story and acceptance criteria. Again, feel free to submit a [Pull Request](#pr) with a proposed implementation of the feature.
## <a id="process"></a> Ready to Contribute
### <a id="issue"></a> Create an issue
Before submitting a new issue, please search the issues to make sure there isn't a similar issue doesn't already exist.
Assuming no existing issues exist, please ensure you include required information when submitting the issue to ensure we can quickly reproduce your issue.
We may have additional questions and will communicate through the GitHub issue, so please respond back to our questions to help reproduce and resolve the issue as quickly as possible.
New issues can be created with in our [GitHub repo](https://github.com/nektos/act/issues/new).
### <a id="pr"></a>Pull Requests
Pull requests should target the `master` branch. Please also reference the issue from the description of the pull request using [special keyword syntax](https://help.github.com/articles/closing-issues-via-commit-messages/) to auto close the issue when the PR is merged. For example, include the phrase `fixes #14` in the PR description to have issue #14 auto close. Please send documentation updates for the [act user guide](https://nektosact.com) to [nektos/act-docs](https://github.com/nektos/act-docs).
### <a id="style"></a> Styleguide
When submitting code, please make every effort to follow existing conventions and style in order to keep the code as readable as possible. Here are a few points to keep in mind:
- Please run `go fmt ./...` before committing to ensure code aligns with go standards.
- We use [`golangci-lint`](https://golangci-lint.run/) for linting Go code, run `golangci-lint run --fix` before submitting PR. Editors such as Visual Studio Code or JetBrains IntelliJ; with Go support plugin will offer `golangci-lint` automatically.
- There are additional linters and formatters for files such as Markdown documents or YAML/JSON:
- Please refer to the [Makefile](Makefile) or [`lint` job in our workflow](.github/workflows/checks.yml) to see how to those linters/formatters work.
- You can lint codebase by running `go run main.go -j lint --env RUN_LOCAL=true` or `act -j lint --env RUN_LOCAL=true`
- In `Makefile`, there are tools that require `npx` which is shipped with `nodejs`.
- Our `Makefile` exports `GITHUB_TOKEN` from `~/.config/github/token`, you have been warned.
- You can run `make pr` to cleanup dependencies, format/lint code and run tests.
- All dependencies must be defined in the `go.mod` file.
- Advanced IDEs and code editors (like VSCode) will take care of that, but to be sure, run `go mod tidy` to validate dependencies.
- For details on the approved style, check out [Effective Go](https://golang.org/doc/effective_go.html).
- Before running tests, please be aware that they are multi-architecture so for them to not fail, you need to run `docker run --privileged --rm tonistiigi/binfmt --install amd64,arm64` before ([more info available in #765](https://github.com/nektos/act/issues/765)).
Also, consider the original design principles:
- **Polyglot** - There will be no prescribed language or framework for developing the microservices. The only requirement will be that the service will be run inside a container and exposed via an HTTP endpoint.
- **Cloud Provider** - At this point, the tool will assume AWS for the cloud provider and will not be written in a cloud agnostic manner. However, this does not preclude refactoring to add support for other providers at a later time.
- **Declarative** - All resource administration will be handled in a declarative vs. imperative manner. A file will be used to declared the desired state of the resources and the tool will simply assert the actual state matches the desired state. The tool will accomplish this by generating CloudFormation templates.
- **Stateless** - The tool will not maintain its own state. Rather, it will rely on the CloudFormation stacks to determine the state of the platform.
- **Secure** - All security will be managed by AWS IAM credentials. No additional authentication or authorization mechanisms will be introduced.
### License
By contributing your code, you agree to license your contribution under the terms of the [MIT License](LICENSE).
All files are released with the MIT license.
================================================
FILE: IMAGES.md
================================================
# List of Docker images for `act`
**Warning:** Below badges with size for each image are displaying size of **compressed image size in registry. After pulling the image, size can be drastically different due to Docker uncompressing the image layers.**
## Images based on [`buildpack-deps`][hub/_/buildpack-deps]
**Note 1: `node` images are based on Debian root filesystem, while it is extremely similar to Ubuntu, there might be some differences**
**Note 2: `node` `-slim` images don't have `python` installed, if you want to use actions or software that is depending on `python`, you need to specify image manually**
| Image | Size |
| ------------------------------------- | ---------------------------------------------------------- |
| [`node:16-bullseye`][hub/_/node] | ![`bullseye-size`][hub/_/node/16-bullseye/size] |
| [`node:16-bullseye-slim`][hub/_/node] | ![`micro-bullseye-size`][hub/_/node/16-bullseye-slim/size] |
| [`node:16-buster`][hub/_/node] | ![`buster-size`][hub/_/node/16-buster/size] |
| [`node:16-buster-slim`][hub/_/node] | ![`micro-buster-size`][hub/_/node/16-buster-slim/size] |
**Note: `catthehacker/ubuntu` images are based on Ubuntu root filesystem**
| Image | GitHub Repository |
| ------------------------------------------------------------ | ------------------------------------------------------------- |
| [`catthehacker/ubuntu:act-latest`][ghcr/catthehacker/ubuntu] | [`catthehacker/docker-images`][gh/catthehacker/docker_images] |
| [`catthehacker/ubuntu:act-22.04`][ghcr/catthehacker/ubuntu] | [`catthehacker/docker-images`][gh/catthehacker/docker_images] |
| [`catthehacker/ubuntu:act-20.04`][ghcr/catthehacker/ubuntu] | [`catthehacker/docker-images`][gh/catthehacker/docker_images] |
| [`catthehacker/ubuntu:act-18.04`][ghcr/catthehacker/ubuntu] | [`catthehacker/docker-images`][gh/catthehacker/docker_images] |
## Images based on [`actions/virtual-environments`][gh/actions/virtual-environments]
**Note: `nektos/act-environments-ubuntu` have been last updated in February, 2020. It's recommended to update the image manually after `docker pull` if you decide to use it.**
| Image | Size | GitHub Repository |
| --------------------------------------------------------------------------------- | -------------------------------------------------------------------------- | ------------------------------------------------------- |
| [`nektos/act-environments-ubuntu:18.04`][hub/nektos/act-environments-ubuntu] | ![`nektos:18.04`][hub/nektos/act-environments-ubuntu/18.04/size] | [`nektos/act-environments`][gh/nektos/act-environments] |
| [`nektos/act-environments-ubuntu:18.04-lite`][hub/nektos/act-environments-ubuntu] | ![`nektos:18.04-lite`][hub/nektos/act-environments-ubuntu/18.04-lite/size] | [`nektos/act-environments`][gh/nektos/act-environments] |
| [`nektos/act-environments-ubuntu:18.04-full`][hub/nektos/act-environments-ubuntu] | ![`nektos:18.04-full`][hub/nektos/act-environments-ubuntu/18.04-full/size] | [`nektos/act-environments`][gh/nektos/act-environments] |
| Image | GitHub Repository |
| ------------------------------------------------------------- | ------------------------------------------------------------------------------------- |
| [`catthehacker/ubuntu:full-latest`][ghcr/catthehacker/ubuntu] | [`catthehacker/virtual-environments-fork`][gh/catthehacker/virtual-environments-fork] |
| [`catthehacker/ubuntu:full-20.04`][ghcr/catthehacker/ubuntu] | [`catthehacker/virtual-environments-fork`][gh/catthehacker/virtual-environments-fork] |
| [`catthehacker/ubuntu:full-18.04`][ghcr/catthehacker/ubuntu] | [`catthehacker/virtual-environments-fork`][gh/catthehacker/virtual-environments-fork] |
Feel free to make a pull request with your image added here
[hub/_/buildpack-deps]: https://hub.docker.com/_/buildpack-deps
[hub/_/node]: https://hub.docker.com/r/_/node
[hub/_/node/16-bullseye/size]: https://img.shields.io/docker/image-size/_/node/16-bullseye
[hub/_/node/16-bullseye-slim/size]: https://img.shields.io/docker/image-size/_/node/16-bullseye-slim
[hub/_/node/16-buster/size]: https://img.shields.io/docker/image-size/_/node/16-buster
[hub/_/node/16-buster-slim/size]: https://img.shields.io/docker/image-size/_/node/16-buster-slim
[ghcr/catthehacker/ubuntu]: https://github.com/catthehacker/docker_images/pkgs/container/ubuntu
[hub/nektos/act-environments-ubuntu]: https://hub.docker.com/r/nektos/act-environments-ubuntu
[hub/nektos/act-environments-ubuntu/18.04/size]: https://img.shields.io/docker/image-size/nektos/act-environments-ubuntu/18.04
[hub/nektos/act-environments-ubuntu/18.04-lite/size]: https://img.shields.io/docker/image-size/nektos/act-environments-ubuntu/18.04-lite
[hub/nektos/act-environments-ubuntu/18.04-full/size]: https://img.shields.io/docker/image-size/nektos/act-environments-ubuntu/18.04-full
<!--
[hub/<username>/<image>]: https://hub.docker.com/r/[username]/[image]
[hub/<username>/<image>/<tag>/size]: https://img.shields.io/docker/image-size/[username]/[image]/[tag]
-->
<!-- GitHub repository links -->
[gh/nektos/act-environments]: https://github.com/nektos/act-environments
[gh/actions/virtual-environments]: https://github.com/actions/virtual-environments
[gh/catthehacker/docker_images]: https://github.com/catthehacker/docker_images
[gh/catthehacker/virtual-environments-fork]: https://github.com/catthehacker/virtual-environments-fork
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2019
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: Makefile
================================================
PREFIX ?= /usr/local
VERSION ?= $(shell git describe --tags --dirty --always | sed -e 's/^v//')
IS_SNAPSHOT = $(if $(findstring -, $(VERSION)),true,false)
MAJOR_VERSION = $(word 1, $(subst ., ,$(VERSION)))
MINOR_VERSION = $(word 2, $(subst ., ,$(VERSION)))
PATCH_VERSION = $(word 3, $(subst ., ,$(word 1,$(subst -, , $(VERSION)))))
NEW_VERSION ?= $(MAJOR_VERSION).$(MINOR_VERSION).$(shell echo $$(( $(PATCH_VERSION) + 1)) )
GOVULNCHECK_PACKAGE ?= golang.org/x/vuln/cmd/govulncheck@v1
fix = false
ifeq (true,$(fix))
FIX = --fix
endif
ACT ?= go run main.go
HAS_TOKEN = $(if $(test -e ~/.config/github/token),true,false)
ifeq (true,$(HAS_TOKEN))
export GITHUB_TOKEN := $(shell cat ~/.config/github/token)
endif
.PHONY: pr
pr: tidy format-all lint test
.PHONY: build
build:
go build -ldflags "-X main.version=$(VERSION)" -o dist/local/act main.go
.PHONY: format
format:
go fmt ./...
.PHONY: format-all
format-all:
go fmt ./...
npx prettier --write .
.PHONY: test
test:
go test ./...
$(ACT)
.PHONY: lint-go
lint-go:
golangci-lint run $(FIX)
.PHONY: lint-js
lint-js:
npx standard $(FIX)
.PHONY: lint-md
lint-md:
npx markdownlint . $(FIX)
.PHONY: lint-rest
lint-rest:
docker run --rm -it \
-v $(PWD):/tmp/lint \
-e GITHUB_STATUS_REPORTER=false \
-e GITHUB_COMMENT_REPORTER=false \
megalinter/megalinter-go:v5
.PHONY: lint
lint: lint-go lint-rest
.PHONY: lint-fix
lint-fix: lint-md lint-go
.PHONY: fix
fix:
make lint-fix fix=true
.PHONY: tidy
tidy:
go mod tidy
.PHONY: install
install: build
@cp dist/local/act $(PREFIX)/bin/act
@chmod 755 $(PREFIX)/bin/act
@act --version
.PHONY: installer
installer:
@GO111MODULE=off go get github.com/goreleaser/godownloader
godownloader -r nektos/act -o install.sh
.PHONY: promote
promote:
@git fetch --tags
@echo "VERSION:$(VERSION) IS_SNAPSHOT:$(IS_SNAPSHOT) NEW_VERSION:$(NEW_VERSION)"
ifeq (false,$(IS_SNAPSHOT))
@echo "Unable to promote a non-snapshot"
@exit 1
endif
ifneq ($(shell git status -s),)
@echo "Unable to promote a dirty workspace"
@exit 1
endif
echo -n $(NEW_VERSION) > VERSION
git add VERSION
git commit -m "chore: bump VERSION to $(NEW_VERSION)"
git tag -a -m "releasing v$(NEW_VERSION)" v$(NEW_VERSION)
git push origin master
git push origin v$(NEW_VERSION)
.PHONY: snapshot
snapshot:
goreleaser build \
--clean \
--single-target \
--snapshot
.PHONY: clean all
.PHONY: upgrade
upgrade:
go get -u
go mod tidy
# "$(shell go env GOROOT)/bin/go" allows us to use an outdated global go tool and use the build toolchain defined by the project
# go build auto upgrades to the same toolchain version as defined in the go.mod file
.PHONY: deps-tools
deps-tools: ## install tool dependencies
"$(shell go env GOROOT)/bin/go" install $(GOVULNCHECK_PACKAGE)
.PHONY: security-check
security-check: deps-tools
GOEXPERIMENT= "$(shell go env GOROOT)/bin/go" run $(GOVULNCHECK_PACKAGE) -show color ./...
================================================
FILE: README.md
================================================

# Overview [](https://github.com/nektos/act/actions) [](https://goreportcard.com/report/github.com/nektos/act) [](https://github.com/jonico/awesome-runners)
> "Think globally, `act` locally"
Run your [GitHub Actions](https://developer.github.com/actions/) locally! Why would you want to do this? Two reasons:
- **Fast Feedback** - Rather than having to commit/push every time you want to test out the changes you are making to your `.github/workflows/` files (or for any changes to embedded GitHub actions), you can use `act` to run the actions locally. The [environment variables](https://help.github.com/en/actions/configuring-and-managing-workflows/using-environment-variables#default-environment-variables) and [filesystem](https://help.github.com/en/actions/reference/virtual-environments-for-github-hosted-runners#filesystems-on-github-hosted-runners) are all configured to match what GitHub provides.
- **Local Task Runner** - I love [make](<https://en.wikipedia.org/wiki/Make_(software)>). However, I also hate repeating myself. With `act`, you can use the GitHub Actions defined in your `.github/workflows/` to replace your `Makefile`!
> [!TIP]
> **Now Manage and Run Act Directly From VS Code!**<br/>
> Check out the [GitHub Local Actions](https://sanjulaganepola.github.io/github-local-actions-docs/) Visual Studio Code extension which allows you to leverage the power of `act` to run and test workflows locally without leaving your editor.
# How Does It Work?
When you run `act` it reads in your GitHub Actions from `.github/workflows/` and determines the set of actions that need to be run. It uses the Docker API to either pull or build the necessary images, as defined in your workflow files and finally determines the execution path based on the dependencies that were defined. Once it has the execution path, it then uses the Docker API to run containers for each action based on the images prepared earlier. The [environment variables](https://help.github.com/en/actions/configuring-and-managing-workflows/using-environment-variables#default-environment-variables) and [filesystem](https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners#file-systems) are all configured to match what GitHub provides.
Let's see it in action with a [sample repo](https://github.com/cplee/github-actions-demo)!

# Act User Guide
Please look at the [act user guide](https://nektosact.com) for more documentation.
# Support
Need help? Ask in [discussions](https://github.com/nektos/act/discussions)!
# Contributing
Want to contribute to act? Awesome! Check out the [contributing guidelines](CONTRIBUTING.md) to get involved.
## Manually building from source
- Install Go tools 1.20+ - (<https://golang.org/doc/install>)
- Clone this repo `git clone git@github.com:nektos/act.git`
- Run unit tests with `make test`
- Build and install: `make install`
================================================
FILE: VERIFICATION
================================================
VERIFICATION
Verification is intended to assist the Chocolatey moderators and community
in verifying that this package's contents are trustworthy.
Checksums: https://github.com/nektos/act/releases, in the checksums.txt file
================================================
FILE: VERSION
================================================
0.2.84
================================================
FILE: act-cli.nuspec
================================================
<?xml version="1.0" encoding="utf-8"?>
<!-- Do not remove this test for UTF-8: if “Ω” doesn’t appear as greek uppercase omega letter enclosed in quotation marks, you should use an editor that supports UTF-8, not this one. -->
<package xmlns="http://schemas.microsoft.com/packaging/2015/06/nuspec.xsd">
<metadata>
<id>act-cli</id>
<version>0.0.0</version>
<packageSourceUrl>https://github.com/nektos/act</packageSourceUrl>
<owners>nektos</owners>
<title>act (GitHub Actions CLI)</title>
<authors>nektos</authors>
<projectUrl>https://github.com/nektos/act</projectUrl>
<iconUrl>https://raw.githubusercontent.com/wiki/nektos/act/img/logo-150.png</iconUrl>
<copyright>Nektos</copyright>
<licenseUrl>https://raw.githubusercontent.com/nektos/act/master/LICENSE</licenseUrl>
<requireLicenseAcceptance>true</requireLicenseAcceptance>
<projectSourceUrl>https://github.com/nektos/act</projectSourceUrl>
<docsUrl>https://raw.githubusercontent.com/nektos/act/master/README.md</docsUrl>
<bugTrackerUrl>https://github.com/nektos/act/issues</bugTrackerUrl>
<tags>act github-actions actions golang ci devops</tags>
<summary>Run your GitHub Actions locally 🚀</summary>
<description>Run your GitHub Actions locally 🚀</description>
</metadata>
<files>
<file src="tools/**" target="tools" />
</files>
</package>
================================================
FILE: cmd/dir.go
================================================
package cmd
import (
"os"
"path/filepath"
log "github.com/sirupsen/logrus"
)
var (
UserHomeDir string
CacheHomeDir string
)
func init() {
home, err := os.UserHomeDir()
if err != nil {
log.Fatal(err)
}
UserHomeDir = home
if v := os.Getenv("XDG_CACHE_HOME"); v != "" {
CacheHomeDir = v
} else {
CacheHomeDir = filepath.Join(UserHomeDir, ".cache")
}
}
================================================
FILE: cmd/execute_test.go
================================================
package cmd
import (
"context"
"os"
"testing"
)
// Helper function to test main with different os.Args
func testMain(args []string) (exitCode int) {
// Save original os.Args and defer restoring it
origArgs := os.Args
defer func() { os.Args = origArgs }()
// Save original os.Exit and defer restoring it
defer func() { exitFunc = os.Exit }()
// Mock os.Exit
fakeExit := func(code int) {
exitCode = code
}
exitFunc = fakeExit
// Mock os.Args
os.Args = args
// Run the main function
Execute(context.Background(), "")
return exitCode
}
func TestMainHelp(t *testing.T) {
exitCode := testMain([]string{"cmd", "--help"})
if exitCode != 0 {
t.Errorf("Expected exit code 0, got %d", exitCode)
}
}
func TestMainNoArgsError(t *testing.T) {
exitCode := testMain([]string{"cmd"})
if exitCode != 1 {
t.Errorf("Expected exit code 1, got %d", exitCode)
}
}
================================================
FILE: cmd/graph.go
================================================
package cmd
import (
"os"
"github.com/nektos/act/pkg/common"
"github.com/nektos/act/pkg/model"
)
func drawGraph(plan *model.Plan) error {
drawings := make([]*common.Drawing, 0)
jobPen := common.NewPen(common.StyleSingleLine, 96)
arrowPen := common.NewPen(common.StyleNoLine, 97)
for i, stage := range plan.Stages {
if i > 0 {
drawings = append(drawings, arrowPen.DrawArrow())
}
ids := make([]string, 0)
for _, r := range stage.Runs {
ids = append(ids, r.String())
}
drawings = append(drawings, jobPen.DrawBoxes(ids...))
}
maxWidth := 0
for _, d := range drawings {
if d.GetWidth() > maxWidth {
maxWidth = d.GetWidth()
}
}
for _, d := range drawings {
d.Draw(os.Stdout, maxWidth)
}
return nil
}
================================================
FILE: cmd/input.go
================================================
package cmd
import (
"path/filepath"
log "github.com/sirupsen/logrus"
)
// Input contains the input for the root command
type Input struct {
actor string
workdir string
workflowsPath string
autodetectEvent bool
eventPath string
reuseContainers bool
bindWorkdir bool
secrets []string
vars []string
envs []string
inputs []string
platforms []string
dryrun bool
forcePull bool
forceRebuild bool
noOutput bool
envfile string
inputfile string
secretfile string
varfile string
insecureSecrets bool
defaultBranch string
privileged bool
usernsMode string
containerArchitecture string
containerDaemonSocket string
containerOptions string
noWorkflowRecurse bool
useGitIgnore bool
githubInstance string
containerCapAdd []string
containerCapDrop []string
autoRemove bool
artifactServerPath string
artifactServerAddr string
artifactServerPort string
noCacheServer bool
cacheServerPath string
cacheServerExternalURL string
cacheServerAddr string
cacheServerPort uint16
jsonLogger bool
noSkipCheckout bool
remoteName string
replaceGheActionWithGithubCom []string
replaceGheActionTokenWithGithubCom string
matrix []string
actionCachePath string
actionOfflineMode bool
logPrefixJobID bool
networkName string
useNewActionCache bool
localRepository []string
listOptions bool
validate bool
strict bool
concurrentJobs int
}
func (i *Input) resolve(path string) string {
basedir, err := filepath.Abs(i.workdir)
if err != nil {
log.Fatal(err)
}
if path == "" {
return path
}
if !filepath.IsAbs(path) {
path = filepath.Join(basedir, path)
}
return path
}
// Envfile returns path to .env
func (i *Input) Envfile() string {
return i.resolve(i.envfile)
}
// Secretfile returns path to secrets
func (i *Input) Secretfile() string {
return i.resolve(i.secretfile)
}
func (i *Input) Varfile() string {
return i.resolve(i.varfile)
}
// Workdir returns path to workdir
func (i *Input) Workdir() string {
return i.resolve(".")
}
// WorkflowsPath returns path to workflow file(s)
func (i *Input) WorkflowsPath() string {
return i.resolve(i.workflowsPath)
}
// EventPath returns the path to events file
func (i *Input) EventPath() string {
return i.resolve(i.eventPath)
}
// Inputfile returns the path to the input file
func (i *Input) Inputfile() string {
return i.resolve(i.inputfile)
}
================================================
FILE: cmd/list.go
================================================
package cmd
import (
"fmt"
"strconv"
"strings"
"github.com/nektos/act/pkg/model"
)
func printList(plan *model.Plan) error {
type lineInfoDef struct {
jobID string
jobName string
stage string
wfName string
wfFile string
events string
}
lineInfos := []lineInfoDef{}
header := lineInfoDef{
jobID: "Job ID",
jobName: "Job name",
stage: "Stage",
wfName: "Workflow name",
wfFile: "Workflow file",
events: "Events",
}
jobs := map[string]bool{}
duplicateJobIDs := false
jobIDMaxWidth := len(header.jobID)
jobNameMaxWidth := len(header.jobName)
stageMaxWidth := len(header.stage)
wfNameMaxWidth := len(header.wfName)
wfFileMaxWidth := len(header.wfFile)
eventsMaxWidth := len(header.events)
for i, stage := range plan.Stages {
for _, r := range stage.Runs {
jobID := r.JobID
line := lineInfoDef{
jobID: jobID,
jobName: r.String(),
stage: strconv.Itoa(i),
wfName: r.Workflow.Name,
wfFile: r.Workflow.File,
events: strings.Join(r.Workflow.On(), `,`),
}
if _, ok := jobs[jobID]; ok {
duplicateJobIDs = true
} else {
jobs[jobID] = true
}
lineInfos = append(lineInfos, line)
if jobIDMaxWidth < len(line.jobID) {
jobIDMaxWidth = len(line.jobID)
}
if jobNameMaxWidth < len(line.jobName) {
jobNameMaxWidth = len(line.jobName)
}
if stageMaxWidth < len(line.stage) {
stageMaxWidth = len(line.stage)
}
if wfNameMaxWidth < len(line.wfName) {
wfNameMaxWidth = len(line.wfName)
}
if wfFileMaxWidth < len(line.wfFile) {
wfFileMaxWidth = len(line.wfFile)
}
if eventsMaxWidth < len(line.events) {
eventsMaxWidth = len(line.events)
}
}
}
jobIDMaxWidth += 2
jobNameMaxWidth += 2
stageMaxWidth += 2
wfNameMaxWidth += 2
wfFileMaxWidth += 2
fmt.Printf("%*s%*s%*s%*s%*s%*s\n",
-stageMaxWidth, header.stage,
-jobIDMaxWidth, header.jobID,
-jobNameMaxWidth, header.jobName,
-wfNameMaxWidth, header.wfName,
-wfFileMaxWidth, header.wfFile,
-eventsMaxWidth, header.events,
)
for _, line := range lineInfos {
fmt.Printf("%*s%*s%*s%*s%*s%*s\n",
-stageMaxWidth, line.stage,
-jobIDMaxWidth, line.jobID,
-jobNameMaxWidth, line.jobName,
-wfNameMaxWidth, line.wfName,
-wfFileMaxWidth, line.wfFile,
-eventsMaxWidth, line.events,
)
}
if duplicateJobIDs {
fmt.Print("\nDetected multiple jobs with the same job name, use `-W` to specify the path to the specific workflow.\n")
}
return nil
}
================================================
FILE: cmd/notices.go
================================================
package cmd
import (
"encoding/json"
"fmt"
"net/http"
"net/url"
"os"
"path/filepath"
"runtime"
"strings"
"time"
log "github.com/sirupsen/logrus"
)
type Notice struct {
Level string `json:"level"`
Message string `json:"message"`
}
func displayNotices(input *Input) {
// Avoid causing trouble parsing the json
if input.listOptions {
return
}
select {
case notices := <-noticesLoaded:
if len(notices) > 0 {
noticeLogger := log.New()
if input.jsonLogger {
noticeLogger.SetFormatter(&log.JSONFormatter{})
} else {
noticeLogger.SetFormatter(&log.TextFormatter{
DisableQuote: true,
DisableTimestamp: true,
PadLevelText: true,
})
}
fmt.Printf("\n")
for _, notice := range notices {
level, err := log.ParseLevel(notice.Level)
if err != nil {
level = log.InfoLevel
}
noticeLogger.Log(level, notice.Message)
}
}
case <-time.After(time.Second * 1):
log.Debugf("Timeout waiting for notices")
}
}
var noticesLoaded = make(chan []Notice)
func loadVersionNotices(version string) {
go func() {
noticesLoaded <- getVersionNotices(version)
}()
}
const NoticeURL = "https://api.nektosact.com/notices"
func getVersionNotices(version string) []Notice {
if os.Getenv("ACT_DISABLE_VERSION_CHECK") == "1" {
return nil
}
noticeURL, err := url.Parse(NoticeURL)
if err != nil {
log.Error(err)
return nil
}
query := noticeURL.Query()
query.Add("os", runtime.GOOS)
query.Add("arch", runtime.GOARCH)
query.Add("version", version)
noticeURL.RawQuery = query.Encode()
client := &http.Client{}
req, err := http.NewRequest("GET", noticeURL.String(), nil)
if err != nil {
log.Debug(err)
return nil
}
etag := loadNoticesEtag()
if etag != "" {
log.Debugf("Conditional GET for notices etag=%s", etag)
req.Header.Set("If-None-Match", etag)
}
resp, err := client.Do(req)
if err != nil {
log.Debug(err)
return nil
}
newEtag := resp.Header.Get("Etag")
if newEtag != "" {
log.Debugf("Saving notices etag=%s", newEtag)
saveNoticesEtag(newEtag)
}
defer resp.Body.Close()
notices := []Notice{}
if resp.StatusCode == 304 {
log.Debug("No new notices")
return nil
}
if err := json.NewDecoder(resp.Body).Decode(¬ices); err != nil {
log.Debug(err)
return nil
}
return notices
}
func loadNoticesEtag() string {
p := etagPath()
content, err := os.ReadFile(p)
if err != nil {
log.Debugf("Unable to load etag from %s: %e", p, err)
}
return strings.TrimSuffix(string(content), "\n")
}
func saveNoticesEtag(etag string) {
p := etagPath()
err := os.WriteFile(p, []byte(strings.TrimSuffix(etag, "\n")), 0o600)
if err != nil {
log.Debugf("Unable to save etag to %s: %e", p, err)
}
}
func etagPath() string {
dir := filepath.Join(CacheHomeDir, "act")
if err := os.MkdirAll(dir, 0o777); err != nil {
log.Fatal(err)
}
return filepath.Join(dir, ".notices.etag")
}
================================================
FILE: cmd/platforms.go
================================================
package cmd
import (
"strings"
)
func (i *Input) newPlatforms() map[string]string {
platforms := map[string]string{
"ubuntu-latest": "node:16-buster-slim",
"ubuntu-22.04": "node:16-bullseye-slim",
"ubuntu-20.04": "node:16-buster-slim",
"ubuntu-18.04": "node:16-buster-slim",
}
for _, p := range i.platforms {
pParts := strings.Split(p, "=")
if len(pParts) == 2 {
platforms[strings.ToLower(pParts[0])] = pParts[1]
}
}
return platforms
}
================================================
FILE: cmd/root.go
================================================
package cmd
import (
"bufio"
"bytes"
"context"
"encoding/json"
"fmt"
"os"
"path/filepath"
"regexp"
"runtime"
"runtime/debug"
"strings"
"github.com/AlecAivazis/survey/v2"
"github.com/adrg/xdg"
"github.com/andreaskoch/go-fswatch"
docker_container "github.com/docker/docker/api/types/container"
"github.com/joho/godotenv"
gitignore "github.com/sabhiram/go-gitignore"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/spf13/cobra/doc"
"github.com/spf13/pflag"
"gopkg.in/yaml.v3"
"github.com/nektos/act/pkg/artifactcache"
"github.com/nektos/act/pkg/artifacts"
"github.com/nektos/act/pkg/common"
"github.com/nektos/act/pkg/container"
"github.com/nektos/act/pkg/gh"
"github.com/nektos/act/pkg/model"
"github.com/nektos/act/pkg/runner"
)
type Flag struct {
Name string `json:"name"`
Default string `json:"default"`
Type string `json:"type"`
Description string `json:"description"`
}
var exitFunc = os.Exit
// Execute is the entry point to running the CLI
func Execute(ctx context.Context, version string) {
input := new(Input)
rootCmd := createRootCommand(ctx, input, version)
if err := rootCmd.Execute(); err != nil {
exitFunc(1)
}
}
func createRootCommand(ctx context.Context, input *Input, version string) *cobra.Command {
rootCmd := &cobra.Command{
Use: "act [event name to run] [flags]\n\nIf no event name passed, will default to \"on: push\"\nIf actions handles only one event it will be used as default instead of \"on: push\"",
Short: "Run GitHub actions locally by specifying the event name (e.g. `push`) or an action name directly.",
Args: cobra.MaximumNArgs(1),
RunE: newRunCommand(ctx, input),
PersistentPreRun: setup(input),
PersistentPostRun: cleanup(input),
Version: version,
SilenceUsage: true,
}
rootCmd.Flags().BoolP("watch", "w", false, "watch the contents of the local repo and run when files change")
rootCmd.Flags().BoolVar(&input.validate, "validate", false, "validate workflows")
rootCmd.Flags().BoolVar(&input.strict, "strict", false, "use strict workflow schema")
rootCmd.Flags().BoolP("list", "l", false, "list workflows")
rootCmd.Flags().BoolP("graph", "g", false, "draw workflows")
rootCmd.Flags().StringP("job", "j", "", "run a specific job ID")
rootCmd.Flags().BoolP("bug-report", "", false, "Display system information for bug report")
rootCmd.Flags().BoolP("man-page", "", false, "Print a generated manual page to stdout")
rootCmd.Flags().StringVar(&input.remoteName, "remote-name", "origin", "git remote name that will be used to retrieve url of git repo")
rootCmd.Flags().StringArrayVarP(&input.secrets, "secret", "s", []string{}, "secret to make available to actions with optional value (e.g. -s mysecret=foo or -s mysecret)")
rootCmd.Flags().StringArrayVar(&input.vars, "var", []string{}, "variable to make available to actions with optional value (e.g. --var myvar=foo or --var myvar)")
rootCmd.Flags().StringArrayVarP(&input.envs, "env", "", []string{}, "env to make available to actions with optional value (e.g. --env myenv=foo or --env myenv)")
rootCmd.Flags().StringArrayVarP(&input.inputs, "input", "", []string{}, "action input to make available to actions (e.g. --input myinput=foo)")
rootCmd.Flags().StringArrayVarP(&input.platforms, "platform", "P", []string{}, "custom image to use per platform (e.g. -P ubuntu-18.04=nektos/act-environments-ubuntu:18.04)")
rootCmd.Flags().BoolVarP(&input.reuseContainers, "reuse", "r", false, "don't remove container(s) on successfully completed workflow(s) to maintain state between runs")
rootCmd.Flags().BoolVarP(&input.bindWorkdir, "bind", "b", false, "bind working directory to container, rather than copy")
rootCmd.Flags().BoolVarP(&input.forcePull, "pull", "p", true, "pull docker image(s) even if already present")
rootCmd.Flags().BoolVarP(&input.forceRebuild, "rebuild", "", true, "rebuild local action docker image(s) even if already present")
rootCmd.Flags().BoolVarP(&input.autodetectEvent, "detect-event", "", false, "Use first event type from workflow as event that triggered the workflow")
rootCmd.Flags().StringVarP(&input.eventPath, "eventpath", "e", "", "path to event JSON file")
rootCmd.Flags().StringVar(&input.defaultBranch, "defaultbranch", "", "the name of the main branch")
rootCmd.Flags().BoolVar(&input.privileged, "privileged", false, "use privileged mode")
rootCmd.Flags().StringVar(&input.usernsMode, "userns", "", "user namespace to use")
rootCmd.Flags().BoolVar(&input.useGitIgnore, "use-gitignore", true, "Controls whether paths specified in .gitignore should be copied into container")
rootCmd.Flags().StringArrayVarP(&input.containerCapAdd, "container-cap-add", "", []string{}, "kernel capabilities to add to the workflow containers (e.g. --container-cap-add SYS_PTRACE)")
rootCmd.Flags().StringArrayVarP(&input.containerCapDrop, "container-cap-drop", "", []string{}, "kernel capabilities to remove from the workflow containers (e.g. --container-cap-drop SYS_PTRACE)")
rootCmd.Flags().BoolVar(&input.autoRemove, "rm", false, "automatically remove container(s)/volume(s) after a workflow(s) failure")
rootCmd.Flags().StringArrayVarP(&input.replaceGheActionWithGithubCom, "replace-ghe-action-with-github-com", "", []string{}, "If you are using GitHub Enterprise Server and allow specified actions from GitHub (github.com), you can set actions on this. (e.g. --replace-ghe-action-with-github-com =github/super-linter)")
rootCmd.Flags().StringVar(&input.replaceGheActionTokenWithGithubCom, "replace-ghe-action-token-with-github-com", "", "If you are using replace-ghe-action-with-github-com and you want to use private actions on GitHub, you have to set personal access token")
rootCmd.Flags().StringArrayVarP(&input.matrix, "matrix", "", []string{}, "specify which matrix configuration to include (e.g. --matrix java:13")
rootCmd.PersistentFlags().StringVarP(&input.actor, "actor", "a", "nektos/act", "user that triggered the event")
rootCmd.PersistentFlags().StringVarP(&input.workflowsPath, "workflows", "W", "./.github/workflows/", "path to workflow file(s)")
rootCmd.PersistentFlags().BoolVarP(&input.noWorkflowRecurse, "no-recurse", "", false, "Flag to disable running workflows from subdirectories of specified path in '--workflows'/'-W' flag")
rootCmd.PersistentFlags().StringVarP(&input.workdir, "directory", "C", ".", "working directory")
rootCmd.PersistentFlags().BoolP("verbose", "v", false, "verbose output")
rootCmd.PersistentFlags().BoolVar(&input.jsonLogger, "json", false, "Output logs in json format")
rootCmd.PersistentFlags().BoolVar(&input.logPrefixJobID, "log-prefix-job-id", false, "Output the job id within non-json logs instead of the entire name")
rootCmd.PersistentFlags().BoolVarP(&input.noOutput, "quiet", "q", false, "disable logging of output from steps")
rootCmd.PersistentFlags().BoolVarP(&input.dryrun, "dryrun", "n", false, "disable container creation, validates only workflow correctness")
rootCmd.PersistentFlags().StringVarP(&input.secretfile, "secret-file", "", ".secrets", "file with list of secrets to read from (e.g. --secret-file .secrets)")
rootCmd.PersistentFlags().StringVarP(&input.varfile, "var-file", "", ".vars", "file with list of vars to read from (e.g. --var-file .vars)")
rootCmd.PersistentFlags().BoolVarP(&input.insecureSecrets, "insecure-secrets", "", false, "NOT RECOMMENDED! Doesn't hide secrets while printing logs.")
rootCmd.PersistentFlags().StringVarP(&input.envfile, "env-file", "", ".env", "environment file to read and use as env in the containers")
rootCmd.PersistentFlags().StringVarP(&input.inputfile, "input-file", "", ".input", "input file to read and use as action input")
rootCmd.PersistentFlags().StringVarP(&input.containerArchitecture, "container-architecture", "", "", "Architecture which should be used to run containers, e.g.: linux/amd64. If not specified, will use host default architecture. Requires Docker server API Version 1.41+. Ignored on earlier Docker server platforms.")
rootCmd.PersistentFlags().StringVarP(&input.containerDaemonSocket, "container-daemon-socket", "", "", "URI to Docker Engine socket (e.g.: unix://~/.docker/run/docker.sock or - to disable bind mounting the socket)")
rootCmd.PersistentFlags().StringVarP(&input.containerOptions, "container-options", "", "", "Custom docker container options for the job container without an options property in the job definition")
rootCmd.PersistentFlags().StringVarP(&input.githubInstance, "github-instance", "", "github.com", "GitHub instance to use. Only use this when using GitHub Enterprise Server.")
rootCmd.PersistentFlags().StringVarP(&input.artifactServerPath, "artifact-server-path", "", "", "Defines the path where the artifact server stores uploads and retrieves downloads from. If not specified the artifact server will not start.")
rootCmd.PersistentFlags().StringVarP(&input.artifactServerAddr, "artifact-server-addr", "", common.GetOutboundIP().String(), "Defines the address to which the artifact server binds.")
rootCmd.PersistentFlags().StringVarP(&input.artifactServerPort, "artifact-server-port", "", "34567", "Defines the port where the artifact server listens.")
rootCmd.PersistentFlags().BoolVarP(&input.noSkipCheckout, "no-skip-checkout", "", false, "Use actions/checkout instead of copying local files into container")
rootCmd.PersistentFlags().BoolVarP(&input.noCacheServer, "no-cache-server", "", false, "Disable cache server")
rootCmd.PersistentFlags().StringVarP(&input.cacheServerPath, "cache-server-path", "", filepath.Join(CacheHomeDir, "actcache"), "Defines the path where the cache server stores caches.")
rootCmd.PersistentFlags().StringVarP(&input.cacheServerExternalURL, "cache-server-external-url", "", "", "Defines the external URL for if the cache server is behind a proxy. e.g.: https://act-cache-server.example.com. Be careful that there is no trailing slash.")
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().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.PersistentFlags().StringArrayVarP(&input.localRepository, "local-repository", "", []string{}, "Replaces the specified repository and ref with a local folder (e.g. https://github.com/test/test@v0=/home/act/test or test/test@v0=/home/act/test, the latter matches any hosts or protocols)")
rootCmd.PersistentFlags().BoolVar(&input.listOptions, "list-options", false, "Print a json structure of compatible options")
rootCmd.PersistentFlags().IntVar(&input.concurrentJobs, "concurrent-jobs", 0, "Maximum number of concurrent jobs to run. Default is the number of CPUs available.")
rootCmd.SetArgs(args())
return rootCmd
}
// Return locations where Act's config can be found in order: XDG spec, .actrc in HOME directory, .actrc in invocation directory
func configLocations() []string {
configFileName := ".actrc"
homePath := filepath.Join(UserHomeDir, configFileName)
invocationPath := filepath.Join(".", configFileName)
// Though named xdg, adrg's lib support macOS and Windows config paths as well
// It also takes cares of creating the parent folder so we don't need to bother later
specPath, err := xdg.ConfigFile("act/actrc")
if err != nil {
specPath = homePath
}
// This order should be enforced since the survey part relies on it
return []string{specPath, homePath, invocationPath}
}
func args() []string {
actrc := configLocations()
args := make([]string, 0)
for _, f := range actrc {
args = append(args, readArgsFile(f, true)...)
}
args = append(args, os.Args[1:]...)
return args
}
func bugReport(ctx context.Context, version string) error {
sprintf := func(key, val string) string {
return fmt.Sprintf("%-24s%s\n", key, val)
}
report := sprintf("act version:", version)
report += sprintf("GOOS:", runtime.GOOS)
report += sprintf("GOARCH:", runtime.GOARCH)
report += sprintf("NumCPU:", fmt.Sprint(runtime.NumCPU()))
var dockerHost string
var exists bool
if dockerHost, exists = os.LookupEnv("DOCKER_HOST"); !exists {
dockerHost = "DOCKER_HOST environment variable is not set"
} else if dockerHost == "" {
dockerHost = "DOCKER_HOST environment variable is empty."
}
report += sprintf("Docker host:", dockerHost)
report += fmt.Sprintln("Sockets found:")
for _, p := range container.CommonSocketLocations {
if _, err := os.Lstat(os.ExpandEnv(p)); err != nil {
continue
} else if _, err := os.Stat(os.ExpandEnv(p)); err != nil {
report += fmt.Sprintf("\t%s(broken)\n", p)
} else {
report += fmt.Sprintf("\t%s\n", p)
}
}
report += sprintf("Config files:", "")
for _, c := range configLocations() {
args := readArgsFile(c, false)
if len(args) > 0 {
report += fmt.Sprintf("\t%s:\n", c)
for _, l := range args {
report += fmt.Sprintf("\t\t%s\n", l)
}
}
}
vcs, ok := debug.ReadBuildInfo()
if ok && vcs != nil {
report += fmt.Sprintln("Build info:")
vcs := *vcs
report += sprintf("\tGo version:", vcs.GoVersion)
report += sprintf("\tModule path:", vcs.Path)
report += sprintf("\tMain version:", vcs.Main.Version)
report += sprintf("\tMain path:", vcs.Main.Path)
report += sprintf("\tMain checksum:", vcs.Main.Sum)
report += fmt.Sprintln("\tBuild settings:")
for _, set := range vcs.Settings {
report += sprintf(fmt.Sprintf("\t\t%s:", set.Key), set.Value)
}
}
info, err := container.GetHostInfo(ctx)
if err != nil {
fmt.Println(report)
return err
}
report += fmt.Sprintln("Docker Engine:")
report += sprintf("\tEngine version:", info.ServerVersion)
report += sprintf("\tEngine runtime:", info.DefaultRuntime)
report += sprintf("\tCgroup version:", info.CgroupVersion)
report += sprintf("\tCgroup driver:", info.CgroupDriver)
report += sprintf("\tStorage driver:", info.Driver)
report += sprintf("\tRegistry URI:", info.IndexServerAddress)
report += sprintf("\tOS:", info.OperatingSystem)
report += sprintf("\tOS type:", info.OSType)
report += sprintf("\tOS version:", info.OSVersion)
report += sprintf("\tOS arch:", info.Architecture)
report += sprintf("\tOS kernel:", info.KernelVersion)
report += sprintf("\tOS CPU:", fmt.Sprint(info.NCPU))
report += sprintf("\tOS memory:", fmt.Sprintf("%d MB", info.MemTotal/1024/1024))
report += fmt.Sprintln("\tSecurity options:")
for _, secopt := range info.SecurityOptions {
report += fmt.Sprintf("\t\t%s\n", secopt)
}
fmt.Println(report)
return nil
}
func generateManPage(cmd *cobra.Command) error {
header := &doc.GenManHeader{
Title: "act",
Section: "1",
Source: fmt.Sprintf("act %s", cmd.Version),
}
buf := new(bytes.Buffer)
cobra.CheckErr(doc.GenMan(cmd, header, buf))
fmt.Print(buf.String())
return nil
}
func listOptions(cmd *cobra.Command) error {
flags := []Flag{}
cmd.LocalFlags().VisitAll(func(f *pflag.Flag) {
flags = append(flags, Flag{Name: f.Name, Default: f.DefValue, Description: f.Usage, Type: f.Value.Type()})
})
a, err := json.Marshal(flags)
fmt.Println(string(a))
return err
}
func readArgsFile(file string, split bool) []string {
args := make([]string, 0)
f, err := os.Open(file)
if err != nil {
return args
}
defer func() {
err := f.Close()
if err != nil {
log.Errorf("Failed to close args file: %v", err)
}
}()
scanner := bufio.NewScanner(f)
scanner.Buffer(nil, 1024*1024*1024) // increase buffer to 1GB to avoid scanner buffer overflow
for scanner.Scan() {
arg := os.ExpandEnv(strings.TrimSpace(scanner.Text()))
if strings.HasPrefix(arg, "-") && split {
args = append(args, regexp.MustCompile(`\s`).Split(arg, 2)...)
} else if !split {
args = append(args, arg)
}
}
return args
}
func setup(_ *Input) func(*cobra.Command, []string) {
return func(cmd *cobra.Command, _ []string) {
verbose, _ := cmd.Flags().GetBool("verbose")
if verbose {
log.SetLevel(log.DebugLevel)
}
loadVersionNotices(cmd.Version)
}
}
func cleanup(inputs *Input) func(*cobra.Command, []string) {
return func(_ *cobra.Command, _ []string) {
displayNotices(inputs)
}
}
func parseEnvs(env []string) map[string]string {
envs := make(map[string]string, len(env))
for _, envVar := range env {
e := strings.SplitN(envVar, `=`, 2)
if len(e) == 2 {
envs[e[0]] = e[1]
} else {
envs[e[0]] = ""
}
}
return envs
}
func readYamlFile(file string) (map[string]string, error) {
content, err := os.ReadFile(file)
if err != nil {
return nil, err
}
ret := map[string]string{}
if err = yaml.Unmarshal(content, &ret); err != nil {
return nil, err
}
return ret, nil
}
func readEnvs(path string, envs map[string]string) bool {
return readEnvsEx(path, envs, false)
}
func readEnvsEx(path string, envs map[string]string, caseInsensitive bool) bool {
if _, err := os.Stat(path); err == nil {
var env map[string]string
if ext := filepath.Ext(path); ext == ".yml" || ext == ".yaml" {
env, err = readYamlFile(path)
} else {
env, err = godotenv.Read(path)
}
if err != nil {
log.Fatalf("Error loading from %s: %v", path, err)
}
for k, v := range env {
if caseInsensitive {
k = strings.ToUpper(k)
}
if _, ok := envs[k]; !ok {
envs[k] = v
}
}
return true
}
return false
}
func parseMatrix(matrix []string) map[string]map[string]bool {
// each matrix entry should be of the form - string:string
r := regexp.MustCompile(":")
matrixes := make(map[string]map[string]bool)
for _, m := range matrix {
matrix := r.Split(m, 2)
if len(matrix) < 2 {
log.Fatalf("Invalid matrix format. Failed to parse %s", m)
}
if _, ok := matrixes[matrix[0]]; !ok {
matrixes[matrix[0]] = make(map[string]bool)
}
matrixes[matrix[0]][matrix[1]] = true
}
return matrixes
}
//nolint:gocyclo
func newRunCommand(ctx context.Context, input *Input) func(*cobra.Command, []string) error {
return func(cmd *cobra.Command, args []string) error {
if input.jsonLogger {
log.SetFormatter(&log.JSONFormatter{})
}
if ok, _ := cmd.Flags().GetBool("bug-report"); ok {
ctx, cancel := common.EarlyCancelContext(ctx)
defer cancel()
return bugReport(ctx, cmd.Version)
}
if ok, _ := cmd.Flags().GetBool("man-page"); ok {
return generateManPage(cmd)
}
if input.listOptions {
return listOptions(cmd)
}
if ret, err := container.GetSocketAndHost(input.containerDaemonSocket); err != nil {
log.Warnf("Couldn't get a valid docker connection: %+v", err)
} else {
os.Setenv("DOCKER_HOST", ret.Host)
input.containerDaemonSocket = ret.Socket
log.Infof("Using docker host '%s', and daemon socket '%s'", ret.Host, ret.Socket)
}
if runtime.GOOS == "darwin" && runtime.GOARCH == "arm64" && input.containerArchitecture == "" {
l := log.New()
l.SetFormatter(&log.TextFormatter{
DisableQuote: true,
DisableTimestamp: true,
})
l.Warnf(" \U000026A0 You are using Apple M-series chip and you have not specified container architecture, you might encounter issues while running act. If so, try running it with '--container-architecture linux/amd64'. \U000026A0 \n")
}
log.Debugf("Loading environment from %s", input.Envfile())
envs := parseEnvs(input.envs)
_ = readEnvs(input.Envfile(), envs)
log.Debugf("Loading action inputs from %s", input.Inputfile())
inputs := parseEnvs(input.inputs)
_ = readEnvs(input.Inputfile(), inputs)
log.Debugf("Loading secrets from %s", input.Secretfile())
secrets := newSecrets(input.secrets)
_ = readEnvsEx(input.Secretfile(), secrets, true)
if _, hasGitHubToken := secrets["GITHUB_TOKEN"]; !hasGitHubToken {
ctx, cancel := common.EarlyCancelContext(ctx)
defer cancel()
secrets["GITHUB_TOKEN"], _ = gh.GetToken(ctx, "")
}
log.Debugf("Loading vars from %s", input.Varfile())
vars := newSecrets(input.vars)
_ = readEnvs(input.Varfile(), vars)
matrixes := parseMatrix(input.matrix)
log.Debugf("Evaluated matrix inclusions: %v", matrixes)
planner, err := model.NewWorkflowPlanner(input.WorkflowsPath(), input.noWorkflowRecurse, input.strict)
if err != nil {
return err
}
jobID, err := cmd.Flags().GetString("job")
if err != nil {
return err
}
// check if we should just list the workflows
list, err := cmd.Flags().GetBool("list")
if err != nil {
return err
}
// check if we should just validate the workflows
if input.validate {
return err
}
// check if we should just draw the graph
graph, err := cmd.Flags().GetBool("graph")
if err != nil {
return err
}
// collect all events from loaded workflows
events := planner.GetEvents()
// plan with filtered jobs - to be used for filtering only
var filterPlan *model.Plan
// Determine the event name to be filtered
var filterEventName string
if len(args) > 0 {
log.Debugf("Using first passed in arguments event for filtering: %s", args[0])
filterEventName = args[0]
} else if input.autodetectEvent && len(events) > 0 && len(events[0]) > 0 {
// set default event type to first event from many available
// this way user dont have to specify the event.
log.Debugf("Using first detected workflow event for filtering: %s", events[0])
filterEventName = events[0]
}
var plannerErr error
if jobID != "" {
log.Debugf("Preparing plan with a job: %s", jobID)
filterPlan, plannerErr = planner.PlanJob(jobID)
} else if filterEventName != "" {
log.Debugf("Preparing plan for a event: %s", filterEventName)
filterPlan, plannerErr = planner.PlanEvent(filterEventName)
} else {
log.Debugf("Preparing plan with all jobs")
filterPlan, plannerErr = planner.PlanAll()
}
if filterPlan == nil && plannerErr != nil {
return plannerErr
}
if list {
err = printList(filterPlan)
if err != nil {
return err
}
return plannerErr
}
if graph {
err = drawGraph(filterPlan)
if err != nil {
return err
}
return plannerErr
}
// plan with triggered jobs
var plan *model.Plan
// Determine the event name to be triggered
var eventName string
if len(args) > 0 {
log.Debugf("Using first passed in arguments event: %s", args[0])
eventName = args[0]
} else if len(events) == 1 && len(events[0]) > 0 {
log.Debugf("Using the only detected workflow event: %s", events[0])
eventName = events[0]
} else if input.autodetectEvent && len(events) > 0 && len(events[0]) > 0 {
// set default event type to first event from many available
// this way user dont have to specify the event.
log.Debugf("Using first detected workflow event: %s", events[0])
eventName = events[0]
} else {
log.Debugf("Using default workflow event: push")
eventName = "push"
}
// build the plan for this run
if jobID != "" {
log.Debugf("Planning job: %s", jobID)
plan, plannerErr = planner.PlanJob(jobID)
} else {
log.Debugf("Planning jobs for event: %s", eventName)
plan, plannerErr = planner.PlanEvent(eventName)
}
if plan != nil {
if len(plan.Stages) == 0 {
plannerErr = fmt.Errorf("Could not find any stages to run. View the valid jobs with `act --list`. Use `act --help` to find how to filter by Job ID/Workflow/Event Name")
}
}
if plan == nil && plannerErr != nil {
return plannerErr
}
// check to see if the main branch was defined
defaultbranch, err := cmd.Flags().GetString("defaultbranch")
if err != nil {
return err
}
// Check if platforms flag is set, if not, run default image survey
if len(input.platforms) == 0 {
cfgFound := false
cfgLocations := configLocations()
for _, v := range cfgLocations {
_, err := os.Stat(v)
if os.IsExist(err) {
cfgFound = true
}
}
if !cfgFound && len(cfgLocations) > 0 {
// The first config location refers to the global config folder one
if err := defaultImageSurvey(cfgLocations[0]); err != nil {
log.Fatal(err)
}
input.platforms = readArgsFile(cfgLocations[0], true)
}
}
deprecationWarning := "--%s is deprecated and will be removed soon, please switch to cli: `--container-options \"%[2]s\"` or `.actrc`: `--container-options %[2]s`."
if input.privileged {
log.Warnf(deprecationWarning, "privileged", "--privileged")
}
if len(input.usernsMode) > 0 {
log.Warnf(deprecationWarning, "userns", fmt.Sprintf("--userns=%s", input.usernsMode))
}
if len(input.containerCapAdd) > 0 {
log.Warnf(deprecationWarning, "container-cap-add", fmt.Sprintf("--cap-add=%s", input.containerCapAdd))
}
if len(input.containerCapDrop) > 0 {
log.Warnf(deprecationWarning, "container-cap-drop", fmt.Sprintf("--cap-drop=%s", input.containerCapDrop))
}
// run the plan
config := &runner.Config{
Actor: input.actor,
EventName: eventName,
EventPath: input.EventPath(),
DefaultBranch: defaultbranch,
ForcePull: !input.actionOfflineMode && input.forcePull,
ForceRebuild: input.forceRebuild,
ReuseContainers: input.reuseContainers,
Workdir: input.Workdir(),
ActionCacheDir: input.actionCachePath,
ActionOfflineMode: input.actionOfflineMode,
BindWorkdir: input.bindWorkdir,
LogOutput: !input.noOutput,
JSONLogger: input.jsonLogger,
LogPrefixJobID: input.logPrefixJobID,
Env: envs,
Secrets: secrets,
Vars: vars,
Inputs: inputs,
Token: secrets["GITHUB_TOKEN"],
InsecureSecrets: input.insecureSecrets,
Platforms: input.newPlatforms(),
Privileged: input.privileged,
UsernsMode: input.usernsMode,
ContainerArchitecture: input.containerArchitecture,
ContainerDaemonSocket: input.containerDaemonSocket,
ContainerOptions: input.containerOptions,
UseGitIgnore: input.useGitIgnore,
GitHubInstance: input.githubInstance,
ContainerCapAdd: input.containerCapAdd,
ContainerCapDrop: input.containerCapDrop,
AutoRemove: input.autoRemove,
ArtifactServerPath: input.artifactServerPath,
ArtifactServerAddr: input.artifactServerAddr,
ArtifactServerPort: input.artifactServerPort,
NoSkipCheckout: input.noSkipCheckout,
RemoteName: input.remoteName,
ReplaceGheActionWithGithubCom: input.replaceGheActionWithGithubCom,
ReplaceGheActionTokenWithGithubCom: input.replaceGheActionTokenWithGithubCom,
Matrix: matrixes,
ContainerNetworkMode: docker_container.NetworkMode(input.networkName),
ConcurrentJobs: input.concurrentJobs,
}
if input.useNewActionCache || len(input.localRepository) > 0 {
if input.actionOfflineMode {
config.ActionCache = &runner.GoGitActionCacheOfflineMode{
Parent: runner.GoGitActionCache{
Path: config.ActionCacheDir,
},
}
} else {
config.ActionCache = &runner.GoGitActionCache{
Path: config.ActionCacheDir,
}
}
if len(input.localRepository) > 0 {
localRepositories := map[string]string{}
for _, l := range input.localRepository {
k, v, _ := strings.Cut(l, "=")
localRepositories[k] = v
}
config.ActionCache = &runner.LocalRepositoryCache{
Parent: config.ActionCache,
LocalRepositories: localRepositories,
CacheDirCache: map[string]string{},
}
}
}
r, err := runner.New(config)
if err != nil {
return err
}
cancel := artifacts.Serve(ctx, input.artifactServerPath, input.artifactServerAddr, input.artifactServerPort)
const cacheURLKey = "ACTIONS_CACHE_URL"
var cacheHandler *artifactcache.Handler
if !input.noCacheServer && envs[cacheURLKey] == "" {
var err error
cacheHandler, err = artifactcache.StartHandler(input.cacheServerPath, input.cacheServerExternalURL, input.cacheServerAddr, input.cacheServerPort, common.Logger(ctx))
if err != nil {
return err
}
envs[cacheURLKey] = cacheHandler.ExternalURL() + "/"
}
ctx = common.WithDryrun(ctx, input.dryrun)
if watch, err := cmd.Flags().GetBool("watch"); err != nil {
return err
} else if watch {
err = watchAndRun(ctx, r.NewPlanExecutor(plan))
if err != nil {
return err
}
return plannerErr
}
executor := r.NewPlanExecutor(plan).Finally(func(_ context.Context) error {
cancel()
_ = cacheHandler.Close()
return nil
})
err = executor(ctx)
if err != nil {
return err
}
return plannerErr
}
}
func defaultImageSurvey(actrc string) error {
var answer string
confirmation := &survey.Select{
Message: "Please choose the default image you want to use with act:\n - Large size image: ca. 17GB download + 53.1GB storage, you will need 75GB of free disk space, snapshots of GitHub Hosted Runners without snap and pulled docker images\n - Medium size image: ~500MB, includes only necessary tools to bootstrap actions and aims to be compatible with most actions\n - Micro size image: <200MB, contains only NodeJS required to bootstrap actions, doesn't work with all actions\n\nDefault image and other options can be changed manually in " + configLocations()[0] + " (please refer to https://nektosact.com/usage/index.html?highlight=configur#configuration-file for additional information about file structure)",
Help: "If you want to know why act asks you that, please go to https://github.com/nektos/act/issues/107",
Default: "Medium",
Options: []string{"Large", "Medium", "Micro"},
}
err := survey.AskOne(confirmation, &answer)
if err != nil {
return err
}
var option string
switch answer {
case "Large":
option = "-P ubuntu-latest=catthehacker/ubuntu:full-latest\n-P ubuntu-22.04=catthehacker/ubuntu:full-22.04\n-P ubuntu-20.04=catthehacker/ubuntu:full-20.04\n-P ubuntu-18.04=catthehacker/ubuntu:full-18.04\n"
case "Medium":
option = "-P ubuntu-latest=catthehacker/ubuntu:act-latest\n-P ubuntu-22.04=catthehacker/ubuntu:act-22.04\n-P ubuntu-20.04=catthehacker/ubuntu:act-20.04\n-P ubuntu-18.04=catthehacker/ubuntu:act-18.04\n"
case "Micro":
option = "-P ubuntu-latest=node:16-buster-slim\n-P ubuntu-22.04=node:16-bullseye-slim\n-P ubuntu-20.04=node:16-buster-slim\n-P ubuntu-18.04=node:16-buster-slim\n"
}
f, err := os.Create(actrc)
if err != nil {
return err
}
_, err = f.WriteString(option)
if err != nil {
_ = f.Close()
return err
}
err = f.Close()
if err != nil {
return err
}
return nil
}
func watchAndRun(ctx context.Context, fn common.Executor) error {
dir, err := os.Getwd()
if err != nil {
return err
}
ignoreFile := filepath.Join(dir, ".gitignore")
ignore := &gitignore.GitIgnore{}
if info, err := os.Stat(ignoreFile); err == nil && !info.IsDir() {
ignore, err = gitignore.CompileIgnoreFile(ignoreFile)
if err != nil {
return fmt.Errorf("compile %q: %w", ignoreFile, err)
}
}
folderWatcher := fswatch.NewFolderWatcher(
dir,
true,
ignore.MatchesPath,
2, // 2 seconds
)
folderWatcher.Start()
defer folderWatcher.Stop()
// run once before watching
if err := fn(ctx); err != nil {
return err
}
earlyCancelCtx, cancel := common.EarlyCancelContext(ctx)
defer cancel()
for folderWatcher.IsRunning() {
log.Debugf("Watching %s for changes", dir)
select {
case <-earlyCancelCtx.Done():
return nil
case changes := <-folderWatcher.ChangeDetails():
log.Debugf("%s", changes.String())
if err := fn(ctx); err != nil {
return err
}
}
}
return nil
}
================================================
FILE: cmd/root_test.go
================================================
package cmd
import (
"context"
"path"
"testing"
"github.com/stretchr/testify/assert"
)
func TestReadSecrets(t *testing.T) {
secrets := map[string]string{}
ret := readEnvsEx(path.Join("testdata", "secrets.yml"), secrets, true)
assert.True(t, ret)
assert.Equal(t, `line1
line2
line3
`, secrets["MYSECRET"])
}
func TestReadEnv(t *testing.T) {
secrets := map[string]string{}
ret := readEnvs(path.Join("testdata", "secrets.yml"), secrets)
assert.True(t, ret)
assert.Equal(t, `line1
line2
line3
`, secrets["mysecret"])
}
func TestListOptions(t *testing.T) {
rootCmd := createRootCommand(context.Background(), &Input{}, "")
err := newRunCommand(context.Background(), &Input{
listOptions: true,
})(rootCmd, []string{})
assert.NoError(t, err)
}
func TestRun(t *testing.T) {
rootCmd := createRootCommand(context.Background(), &Input{}, "")
err := newRunCommand(context.Background(), &Input{
platforms: []string{"ubuntu-latest=node:16-buster-slim"},
workdir: "../pkg/runner/testdata/",
workflowsPath: "./basic/push.yml",
})(rootCmd, []string{})
assert.NoError(t, err)
}
func TestRunPush(t *testing.T) {
rootCmd := createRootCommand(context.Background(), &Input{}, "")
err := newRunCommand(context.Background(), &Input{
platforms: []string{"ubuntu-latest=node:16-buster-slim"},
workdir: "../pkg/runner/testdata/",
workflowsPath: "./basic/push.yml",
})(rootCmd, []string{"push"})
assert.NoError(t, err)
}
func TestRunPushJsonLogger(t *testing.T) {
rootCmd := createRootCommand(context.Background(), &Input{}, "")
err := newRunCommand(context.Background(), &Input{
platforms: []string{"ubuntu-latest=node:16-buster-slim"},
workdir: "../pkg/runner/testdata/",
workflowsPath: "./basic/push.yml",
jsonLogger: true,
})(rootCmd, []string{"push"})
assert.NoError(t, err)
}
func TestFlags(t *testing.T) {
for _, f := range []string{"graph", "list", "bug-report", "man-page"} {
t.Run("TestFlag-"+f, func(t *testing.T) {
rootCmd := createRootCommand(context.Background(), &Input{}, "")
err := rootCmd.Flags().Set(f, "true")
assert.NoError(t, err)
err = newRunCommand(context.Background(), &Input{
platforms: []string{"ubuntu-latest=node:16-buster-slim"},
workdir: "../pkg/runner/testdata/",
workflowsPath: "./basic/push.yml",
})(rootCmd, []string{})
assert.NoError(t, err)
})
}
}
func TestReadArgsFile(t *testing.T) {
tables := []struct {
path string
split bool
args []string
env map[string]string
}{
{
path: path.Join("testdata", "simple.actrc"),
split: true,
args: []string{"--container-architecture=linux/amd64", "--action-offline-mode"},
},
{
path: path.Join("testdata", "env.actrc"),
split: true,
env: map[string]string{
"FAKEPWD": "/fake/test/pwd",
"FOO": "foo",
},
args: []string{
"--artifact-server-path", "/fake/test/pwd/.artifacts",
"--env", "FOO=prefix/foo/suffix",
},
},
{
path: path.Join("testdata", "split.actrc"),
split: true,
args: []string{"--container-options", "--volume /foo:/bar --volume /baz:/qux --volume /tmp:/tmp"},
},
}
for _, table := range tables {
t.Run(table.path, func(t *testing.T) {
for k, v := range table.env {
t.Setenv(k, v)
}
args := readArgsFile(table.path, table.split)
assert.Equal(t, table.args, args)
})
}
}
================================================
FILE: cmd/secrets.go
================================================
package cmd
import (
"fmt"
"os"
"strings"
log "github.com/sirupsen/logrus"
"golang.org/x/term"
)
type secrets map[string]string
func newSecrets(secretList []string) secrets {
s := make(map[string]string)
for _, secretPair := range secretList {
secretPairParts := strings.SplitN(secretPair, "=", 2)
secretPairParts[0] = strings.ToUpper(secretPairParts[0])
if strings.ToUpper(s[secretPairParts[0]]) == secretPairParts[0] {
log.Errorf("Secret %s is already defined (secrets are case insensitive)", secretPairParts[0])
}
if len(secretPairParts) == 2 {
s[secretPairParts[0]] = secretPairParts[1]
} else if env, ok := os.LookupEnv(secretPairParts[0]); ok && env != "" {
s[secretPairParts[0]] = env
} else {
fmt.Printf("Provide value for '%s': ", secretPairParts[0])
val, err := term.ReadPassword(int(os.Stdin.Fd()))
fmt.Println()
if err != nil {
log.Errorf("failed to read input: %v", err)
os.Exit(1)
}
s[secretPairParts[0]] = string(val)
}
}
return s
}
func (s secrets) AsMap() map[string]string {
return s
}
================================================
FILE: cmd/testdata/env.actrc
================================================
--artifact-server-path $FAKEPWD/.artifacts
--env FOO=prefix/${FOO}/suffix
================================================
FILE: cmd/testdata/secrets.yml
================================================
mysecret: |
line1
line2
line3
================================================
FILE: cmd/testdata/simple.actrc
================================================
--container-architecture=linux/amd64
--action-offline-mode
================================================
FILE: cmd/testdata/split.actrc
================================================
--container-options --volume /foo:/bar --volume /baz:/qux --volume /tmp:/tmp
================================================
FILE: codecov.yml
================================================
coverage:
status:
project:
default:
target: auto # auto compares coverage to the previous base commit
threshold: 1%
patch:
default:
target: 50%
informational: true
ignore:
# Files generated by Google Protobuf do not require coverage
- '**/*.pb.go'
================================================
FILE: go.mod
================================================
module github.com/nektos/act
go 1.24.0
require (
github.com/AlecAivazis/survey/v2 v2.3.7
github.com/Masterminds/semver v1.5.0
github.com/adrg/xdg v0.5.3
github.com/andreaskoch/go-fswatch v1.0.0
github.com/creack/pty v1.1.24
github.com/docker/cli v28.4.0+incompatible
github.com/docker/docker v28.4.0+incompatible
github.com/docker/go-connections v0.6.0
github.com/go-git/go-billy/v5 v5.6.2
github.com/go-git/go-git/v5 v5.16.5
github.com/joho/godotenv v1.5.1
github.com/julienschmidt/httprouter v1.3.0
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51
github.com/mattn/go-isatty v0.0.20
github.com/moby/patternmatcher v0.6.0
github.com/opencontainers/image-spec v1.1.1
github.com/opencontainers/selinux v1.13.1
github.com/pkg/errors v0.9.1
github.com/rhysd/actionlint v1.7.7
github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06
github.com/sirupsen/logrus v1.9.3
github.com/spf13/cobra v1.10.1
github.com/spf13/pflag v1.0.9
github.com/stretchr/testify v1.11.1
github.com/timshannon/bolthold v0.0.0-20240314194003-30aac6950928
go.etcd.io/bbolt v1.4.3
golang.org/x/term v0.38.0
gopkg.in/yaml.v3 v3.0.1
gotest.tools/v3 v3.5.2
)
require (
dario.cat/mergo v1.0.2
github.com/containerd/errdefs v1.0.0
github.com/distribution/reference v0.6.0
github.com/golang-jwt/jwt/v5 v5.3.0
github.com/moby/go-archive v0.1.0
google.golang.org/protobuf v1.36.9
)
require (
github.com/Microsoft/go-winio v0.6.2 // indirect
github.com/ProtonMail/go-crypto v1.1.6 // indirect
github.com/bmatcuk/doublestar/v4 v4.8.0 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/cloudflare/circl v1.6.3 // indirect
github.com/containerd/errdefs/pkg v0.3.0 // indirect
github.com/containerd/log v0.1.0 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.6 // indirect
github.com/cyphar/filepath-securejoin v0.5.1 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/docker/docker-credential-helpers v0.8.2 // indirect
github.com/docker/go-units v0.5.0 // indirect
github.com/emirpasic/gods v1.18.1 // indirect
github.com/fatih/color v1.18.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-logr/logr v1.4.3 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect
github.com/google/go-cmp v0.7.0 // indirect
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
github.com/kevinburke/ssh_config v1.2.0 // indirect
github.com/klauspost/compress v1.18.0 // indirect
github.com/mattn/go-colorable v0.1.14 // indirect
github.com/mattn/go-runewidth v0.0.16 // indirect
github.com/mattn/go-shellwords v1.0.12 // indirect
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect
github.com/moby/docker-image-spec v1.3.1 // indirect
github.com/moby/sys/atomicwriter v0.1.0 // indirect
github.com/moby/sys/sequential v0.6.0 // indirect
github.com/moby/sys/user v0.4.0 // indirect
github.com/moby/sys/userns v0.1.0 // indirect
github.com/moby/term v0.5.0 // indirect
github.com/morikuni/aec v1.0.0 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/pjbgf/sha1cd v0.3.2 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rivo/uniseg v0.4.7 // indirect
github.com/robfig/cron/v3 v3.0.1 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect
github.com/skeema/knownhosts v1.3.1 // indirect
github.com/stretchr/objx v0.5.2 // indirect
github.com/xanzy/ssh-agent v0.3.3 // indirect
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0 // indirect
go.opentelemetry.io/otel v1.40.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.28.0 // indirect
go.opentelemetry.io/otel/metric v1.40.0 // indirect
go.opentelemetry.io/otel/sdk v1.40.0 // indirect
go.opentelemetry.io/otel/trace v1.40.0 // indirect
golang.org/x/crypto v0.46.0 // indirect
golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 // indirect
golang.org/x/net v0.47.0 // indirect
golang.org/x/sync v0.19.0 // indirect
golang.org/x/sys v0.40.0 // indirect
golang.org/x/text v0.32.0 // indirect
golang.org/x/time v0.6.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 // indirect
gopkg.in/warnings.v0 v0.1.2 // indirect
)
================================================
FILE: go.sum
================================================
dario.cat/mergo v1.0.2 h1:85+piFYR1tMbRrLcDwR18y4UKJ3aH1Tbzi24VRW1TK8=
dario.cat/mergo v1.0.2/go.mod h1:E/hbnu0NxMFBjpMIE34DRGLWqDy0g5FuKDhCb31ngxA=
github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6 h1:He8afgbRMd7mFxO99hRNu+6tazq8nFF9lIwo9JFroBk=
github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8=
github.com/AlecAivazis/survey/v2 v2.3.7 h1:6I/u8FvytdGsgonrYsVn2t8t4QiRnh6QSTqkkhIiSjQ=
github.com/AlecAivazis/survey/v2 v2.3.7/go.mod h1:xUTIdE4KCOIjsBAE1JYsUPoCqYdZ1reCfTwbto0Fduo=
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8=
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=
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.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
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/ProtonMail/go-crypto v1.1.6 h1:ZcV+Ropw6Qn0AX9brlQLAUXfqLBc7Bl+f/DmNxpLfdw=
github.com/ProtonMail/go-crypto v1.1.6/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE=
github.com/adrg/xdg v0.5.3 h1:xRnxJXne7+oWDatRhR1JLnvuccuIeCoBu2rtuLqQB78=
github.com/adrg/xdg v0.5.3/go.mod h1:nlTsY+NNiCBGCK2tpm09vRqfVzrc2fLmXGpBLF0zlTQ=
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/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/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
github.com/bmatcuk/doublestar/v4 v4.8.0 h1:DSXtrypQddoug1459viM9X9D3dp1Z7993fw36I2kNcQ=
github.com/bmatcuk/doublestar/v4 v4.8.0/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cloudflare/circl v1.6.3 h1:9GPOhQGF9MCYUeXyMYlqTR6a5gTrgR/fBLXvUgtVcg8=
github.com/cloudflare/circl v1.6.3/go.mod h1:2eXP6Qfat4O/Yhh8BznvKnJ+uzEoTQ6jVKJRn81BiS4=
github.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI=
github.com/containerd/errdefs v1.0.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M=
github.com/containerd/errdefs/pkg v0.3.0 h1:9IKJ06FvyNlexW690DXuQNx2KA2cUJXx151Xdx3ZPPE=
github.com/containerd/errdefs/pkg v0.3.0/go.mod h1:NJw6s9HwNuRhnjJhM7pylWwMyAkmCQvQ4GpJHEqRLVk=
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.6 h1:XJtiaUW6dEEqVuZiMTn1ldk455QWwEIsMIJlo5vtkx0=
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
github.com/creack/pty v1.1.17/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
github.com/creack/pty v1.1.24 h1:bJrF4RRfyJnbTJqzRLHzcGaZK1NeM5kTC9jGgovnR1s=
github.com/creack/pty v1.1.24/go.mod h1:08sCNb52WyoAwi2QDyzUCTgcvVFhUzewun7wtTfvcwE=
github.com/cyphar/filepath-securejoin v0.5.1 h1:eYgfMq5yryL4fbWfkLpFFy2ukSELzaJOTaUTuh+oF48=
github.com/cyphar/filepath-securejoin v0.5.1/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
github.com/docker/cli v28.4.0+incompatible h1:RBcf3Kjw2pMtwui5V0DIMdyeab8glEw5QY0UUU4C9kY=
github.com/docker/cli v28.4.0+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/docker v28.4.0+incompatible h1:KVC7bz5zJY/4AZe/78BIvCnPsLaC9T/zh72xnlrTTOk=
github.com/docker/docker v28.4.0+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker-credential-helpers v0.8.2 h1:bX3YxiGzFP5sOXWc3bTPEXdEaZSeVMrFgOr3T+zrFAo=
github.com/docker/docker-credential-helpers v0.8.2/go.mod h1:P3ci7E3lwkZg6XiHdRKft1KckHiO9a2rNtyFbZ/ry9M=
github.com/docker/go-connections v0.6.0 h1:LlMG9azAe1TqfR7sO+NJttz1gy6KO7VJBh+pMmjSD94=
github.com/docker/go-connections v0.6.0/go.mod h1:AahvXYshr6JgfUJGdDCs2b5EZG/vmaMAntpSFH5BFKE=
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/elazarl/goproxy v1.7.2 h1:Y2o6urb7Eule09PjlhQRGNsqRfPmYI3KKQLFpCAV3+o=
github.com/elazarl/goproxy v1.7.2/go.mod h1:82vkLNir0ALaW14Rc399OTTjyNREgmdL2cVoIbS6XaE=
github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=
github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ=
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
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.8 h1:a4YXD1V7xMF9g5nTkdfnja3Sxy1PVDCj1Zg4Wb8vY6c=
github.com/gliderlabs/ssh v0.3.8/go.mod h1:xYoytBv1sV0aL3CavoDuJIQNURXkkfPA/wxQ1pL1fAU=
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/go-billy/v5 v5.6.2 h1:6Q86EsPXMa7c3YZ3aLAQsMA0VlWmy43r6FHqa/UNbRM=
github.com/go-git/go-billy/v5 v5.6.2/go.mod h1:rcFC2rAsp/erv7CMz9GczHcuD0D32fWzH+MJAU+jaUU=
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4=
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII=
github.com/go-git/go-git/v5 v5.16.5 h1:mdkuqblwr57kVfXri5TTH+nMFLNUxIj9Z7F5ykFbw5s=
github.com/go-git/go-git/v5 v5.16.5/go.mod h1:QOMLpNf1qxuSY4StA/ArOdfFR2TrKEjJiye2kel2m+M=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
github.com/go-logr/logr v1.4.3/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/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs=
github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo=
github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ=
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
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/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k=
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/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U=
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4=
github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
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/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
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.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mattn/go-shellwords v1.0.12 h1:M2zGm7EW6UQJvDeQxo4T51eKPurbeFbe8WtebGE2xrk=
github.com/mattn/go-shellwords v1.0.12/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y=
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d h1:5PJl274Y63IEHC+7izoQE9x6ikvDFZS2mDVS3drnohI=
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
github.com/moby/go-archive v0.1.0 h1:Kk/5rdW/g+H8NHdJW2gsXyZ7UnzvJNOy6VKJqueWdcQ=
github.com/moby/go-archive v0.1.0/go.mod h1:G9B+YoujNohJmrIYFBpSd54GTUB4lt9S+xVQvsJyFuo=
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/sys/atomicwriter v0.1.0 h1:kw5D/EqkBwsBFi0ss9v1VG3wIkVhzGvLklJ+w3A14Sw=
github.com/moby/sys/atomicwriter v0.1.0/go.mod h1:Ul8oqv2ZMNHOceF643P6FKPXeCmYtlQMvpizfsSoaWs=
github.com/moby/sys/sequential v0.6.0 h1:qrx7XFUd/5DxtqcoH1h438hF5TmOvzC/lspjy7zgvCU=
github.com/moby/sys/sequential v0.6.0/go.mod h1:uyv8EUTrca5PnDsdMGXhZe6CCe8U/UiTWd+lL+7b/Ko=
github.com/moby/sys/user v0.4.0 h1:jhcMKit7SA80hivmFJcbB1vqmw//wU61Zdui2eQXuMs=
github.com/moby/sys/user v0.4.0/go.mod h1:bG+tYYYJgaMtRKgEmuueC0hJEAZWwtIbZTB+85uoHjs=
github.com/moby/sys/userns v0.1.0 h1:tVLXkFOxVu9A64/yh59slHVv9ahO9UIev4JZusOLG/g=
github.com/moby/sys/userns v0.1.0/go.mod h1:IHUYgu/kao6N8YZlp9Cf444ySSvCmDlmzUcYfDHOl28=
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/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k=
github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY=
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/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040=
github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M=
github.com/opencontainers/selinux v1.13.1 h1:A8nNeceYngH9Ow++M+VVEwJVpdFmrlxsN22F+ISDCJE=
github.com/opencontainers/selinux v1.13.1/go.mod h1:S10WXZ/osk2kWOYKy1x2f/eXF5ZHJoUs8UU/2caNRbg=
github.com/pjbgf/sha1cd v0.3.2 h1:a9wb0bp1oC2TGwStyn0Umc/IGKQnEgF0vVaZ8QF8eo4=
github.com/pjbgf/sha1cd v0.3.2/go.mod h1:zQWigSxVmsHEZow5qaLtPYxpcKMMQpa09ixqBxuCS6A=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
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/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rhysd/actionlint v1.7.7 h1:0KgkoNTrYY7vmOCs9BW2AHxLvvpoY9nEUzgBHiPUr0k=
github.com/rhysd/actionlint v1.7.7/go.mod h1:AE6I6vJEkNaIfWqC2GNE5spIJNhxf8NCtLEKU4NnUXg=
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.7/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/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
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/go.mod h1:+ePHsJ1keEjQtpvf9HHw0f4ZeJ0TLRsxhunSI2hYJSs=
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8=
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4=
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/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/skeema/knownhosts v1.3.1 h1:X2osQ+RAjK76shCbvhHHHVl3ZlgDm8apHEHFqRjnBY8=
github.com/skeema/knownhosts v1.3.1/go.mod h1:r7KTdC8l4uxWRyK2TpQZ/1o5HaSzh06ePQNxPwTcfiY=
github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s=
github.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4XaB0=
github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY=
github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
github.com/timshannon/bolthold v0.0.0-20240314194003-30aac6950928 h1:zjNCuOOhh1TKRU0Ru3PPPJt80z7eReswCao91gBLk00=
github.com/timshannon/bolthold v0.0.0-20240314194003-30aac6950928/go.mod h1:PCFYfAEfKT+Nd6zWvUpsXduMR1bXFLf0uGSlEF05MCI=
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/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/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
go.etcd.io/bbolt v1.3.8/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw=
go.etcd.io/bbolt v1.4.3 h1:dEadXpI6G79deX5prL3QRNP6JB8UxVkqo4UPnHaNXJo=
go.etcd.io/bbolt v1.4.3/go.mod h1:tKQlpPaYCVFctUIgFKFnAlvbmB3tpy1vkTnDWohtc0E=
go.etcd.io/gofail v0.1.0/go.mod h1:VZBCXYGZhHAinaBiiqYvuDynvahNsAyLFwB3kEHKz1M=
go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0 h1:yd02MEjBdJkG3uabWP9apV+OuWRIXGDuJEUJbOHmCFU=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0/go.mod h1:umTcuxiv1n/s/S6/c2AT/g2CQ7u5C59sHDNmfSwgz7Q=
go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms=
go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 h1:3Q/xZUyC1BBkualc9ROb4G8qkH90LXEIICcs5zv1OYY=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0/go.mod h1:s75jGIWA9OfCMzF0xr+ZgfrB5FEbbV7UuYo32ahUiFI=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.28.0 h1:j9+03ymgYhPKmeXGk5Zu+cIZOlVzd9Zv7QIiyItjFBU=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.28.0/go.mod h1:Y5+XiUG4Emn1hTfciPzGPJaSI+RpDts6BnCIir0SLqk=
go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g=
go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc=
go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8=
go.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE=
go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw=
go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA=
go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0=
go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU=
golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0=
golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 h1:e66Fs6Z+fZTbFBAxKfP3PALWBtpfqks2bwGcexMxgtk=
golang.org/x/exp v0.0.0-20240909161429-701f63a606c0/go.mod h1:2TbTHSBQa924w8M6Xs1QcRcFwyucIwBGpK1p2f1YFFY=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/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.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
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-20191026070338-33540a1f6037/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-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-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-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ=
golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
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.38.0 h1:PQ5pkm/rLO6HnxFR7N2lJHOZX6Kez5Y1gDSJla6jo7Q=
golang.org/x/term v0.38.0/go.mod h1:bSEAKrOT1W+VSu9TSCMtoGEOUcKxOKgl3LE5QEF/xVg=
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.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU=
golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY=
golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U=
golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8=
google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 h1:pPJltXNxVzT4pK9yD8vR9X75DaWYYmLGMsEvBfFQZzQ=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU=
google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw=
google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA=
google.golang.org/protobuf v1.36.9 h1:w2gp2mA27hUeUzj9Ex9FBjsBm40zfaDtEWow293U7Iw=
google.golang.org/protobuf v1.36.9/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU=
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-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/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
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.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gotest.tools/v3 v3.5.2 h1:7koQfIKdy+I8UTetycgUqXWSDwpgv193Ka+qRsmBY8Q=
gotest.tools/v3 v3.5.2/go.mod h1:LtdLGcnqToBH83WByAAi/wiwSFCArdFIUV/xxN4pcjA=
================================================
FILE: install.sh
================================================
#!/bin/sh
set -e
# Code originally generated by godownloader on 2021-12-22T16:10:52Z. DO NOT EDIT.
# (godownloader is deprecated, so changes to this script are maintained in install.sh in https://github.com/nektos/act)
#
usage() {
this=$1
cat <<EOF
$this: download go binaries for nektos/act
Usage: $this [-b bindir] [-d] [-f] [tag]
-b sets bindir or installation directory, Defaults to ./bin
-d turns on debug logging
-f forces installation, bypassing version checks
[tag] is a tag from
https://github.com/nektos/act/releases
If tag is missing, then the latest will be used.
EOF
exit 2
}
parse_args() {
#BINDIR is ./bin unless set be ENV
# over-ridden by flag below
BINDIR=${BINDIR:-./bin}
while getopts "b:dfh?x" arg; do
case "$arg" in
b) BINDIR="$OPTARG" ;;
d) log_set_priority 10 ;;
f) FORCE_INSTALL="true" ;;
h | \?) usage "$0" ;;
x) set -x ;;
esac
done
shift $((OPTIND - 1))
TAG=$1
}
# this function wraps all the destructive operations
# if a curl|bash cuts off the end of the script due to
# network, either nothing will happen or will syntax error
# out preventing half-done work
execute() {
tmpdir=$(mktemp -d)
log_debug "downloading files into ${tmpdir}"
http_download "${tmpdir}/${TARBALL}" "${TARBALL_URL}"
http_download "${tmpdir}/${CHECKSUM}" "${CHECKSUM_URL}"
hash_sha256_verify "${tmpdir}/${TARBALL}" "${tmpdir}/${CHECKSUM}"
srcdir="${tmpdir}"
(cd "${tmpdir}" && untar "${TARBALL}")
test ! -d "${BINDIR}" && install -d "${BINDIR}"
for binexe in $BINARIES; do
if [ "$OS" = "windows" ]; then
binexe="${binexe}.exe"
fi
install "${srcdir}/${binexe}" "${BINDIR}/"
log_info "installed ${BINDIR}/${binexe}"
done
rm -rf "${tmpdir}"
}
get_binaries() {
case "$PLATFORM" in
darwin/386) BINARIES="act" ;;
darwin/amd64) BINARIES="act" ;;
darwin/arm64) BINARIES="act" ;;
darwin/armv6) BINARIES="act" ;;
darwin/armv7) BINARIES="act" ;;
linux/386) BINARIES="act" ;;
linux/amd64) BINARIES="act" ;;
linux/arm64) BINARIES="act" ;;
linux/armv6) BINARIES="act" ;;
linux/armv7) BINARIES="act" ;;
windows/386) BINARIES="act" ;;
windows/amd64) BINARIES="act" ;;
windows/arm64) BINARIES="act" ;;
windows/armv6) BINARIES="act" ;;
windows/armv7) BINARIES="act" ;;
*)
log_crit "platform $PLATFORM is not supported. Make sure this script is up-to-date and file request at https://github.com/${PREFIX}/issues/new"
exit 1
;;
esac
}
tag_to_version() {
if [ -z "${TAG}" ]; then
log_info "checking GitHub for latest tag"
else
log_info "checking GitHub for tag '${TAG}'"
fi
REALTAG=$(github_release "$OWNER/$REPO" "${TAG}") && true
if test -z "$REALTAG"; then
log_crit "unable to find '${TAG}' - use 'latest' or see https://github.com/${PREFIX}/releases for details"
exit 1
fi
# if version starts with 'v', remove it
TAG="$REALTAG"
VERSION=${TAG#v}
}
adjust_format() {
# change format (tar.gz or zip) based on OS
case ${OS} in
windows) FORMAT=zip ;;
esac
true
}
adjust_os() {
# adjust archive name based on OS
case ${OS} in
386) OS=i386 ;;
amd64) OS=x86_64 ;;
darwin) OS=Darwin ;;
linux) OS=Linux ;;
windows) OS=Windows ;;
esac
true
}
adjust_arch() {
# adjust archive name based on ARCH
case ${ARCH} in
386) ARCH=i386 ;;
amd64) ARCH=x86_64 ;;
darwin) ARCH=Darwin ;;
linux) ARCH=Linux ;;
windows) ARCH=Windows ;;
esac
true
}
check_installed_version() {
# Check if force install flag is set
if [ "${FORCE_INSTALL}" = "true" ]; then
log_info "force install enabled. Skipping version check."
return
fi
# Check if the binary exists
if is_command "$BINARY"; then
# Extract installed version using cut
INSTALLED_VERSION=$($BINARY --version | cut -d' ' -f3)
if [ -z "$INSTALLED_VERSION" ]; then
log_err "failed to detect installed version. Proceeding with installation."
return
fi
log_info "found installed version: $INSTALLED_VERSION"
# Compare versions
if [ "$INSTALLED_VERSION" = "$VERSION" ]; then
log_info "$BINARY version $INSTALLED_VERSION is already installed."
exit 0
else
log_debug "updating $BINARY from version $INSTALLED_VERSION to $VERSION..."
fi
else
log_debug "$BINARY is not installed. Proceeding with installation..."
fi
}
cat /dev/null <<EOF
------------------------------------------------------------------------
https://github.com/client9/shlib - portable posix shell functions
Public domain - http://unlicense.org
https://github.com/client9/shlib/blob/master/LICENSE.md
but credit (and pull requests) appreciated.
------------------------------------------------------------------------
EOF
is_command() {
command -v "$1" >/dev/null
}
echoerr() {
echo "$@" 1>&2
}
log_prefix() {
echo "$0"
}
_logp=6
log_set_priority() {
_logp="$1"
}
log_priority() {
if test -z "$1"; then
echo "$_logp"
return
fi
[ "$1" -le "$_logp" ]
}
log_tag() {
case $1 in
0) echo "emerg" ;;
1) echo "alert" ;;
2) echo "crit" ;;
3) echo "err" ;;
4) echo "warning" ;;
5) echo "notice" ;;
6) echo "info" ;;
7) echo "debug" ;;
*) echo "$1" ;;
esac
}
log_debug() {
log_priority 7 || return 0
echoerr "$(log_prefix)" "$(log_tag 7)" "$@"
}
log_info() {
log_priority 6 || return 0
echoerr "$(log_prefix)" "$(log_tag 6)" "$@"
}
log_err() {
log_priority 3 || return 0
echoerr "$(log_prefix)" "$(log_tag 3)" "$@"
}
log_crit() {
log_priority 2 || return 0
echoerr "$(log_prefix)" "$(log_tag 2)" "$@"
}
uname_os() {
os=$(uname -s | tr '[:upper:]' '[:lower:]')
case "$os" in
cygwin_nt*) os="windows" ;;
mingw*) os="windows" ;;
msys_nt*) os="windows" ;;
esac
echo "$os"
}
uname_arch() {
arch=$(uname -m)
case $arch in
x86_64) arch="amd64" ;;
x86) arch="386" ;;
i686) arch="386" ;;
i386) arch="386" ;;
aarch64) arch="arm64" ;;
armv5*) arch="armv5" ;;
armv6*) arch="armv6" ;;
armv7*) arch="armv7" ;;
esac
echo ${arch}
}
uname_os_check() {
os=$(uname_os)
case "$os" in
darwin) return 0 ;;
dragonfly) return 0 ;;
freebsd) return 0 ;;
linux) return 0 ;;
android) return 0 ;;
nacl) return 0 ;;
netbsd) return 0 ;;
openbsd) return 0 ;;
plan9) return 0 ;;
solaris) return 0 ;;
windows) return 0 ;;
esac
log_crit "uname_os_check '$(uname -s)' got converted to '$os' which is not a GOOS value. Please file bug at https://github.com/client9/shlib"
return 1
}
uname_arch_check() {
arch=$(uname_arch)
case "$arch" in
386) return 0 ;;
amd64) return 0 ;;
arm64) return 0 ;;
armv5) return 0 ;;
armv6) return 0 ;;
armv7) return 0 ;;
ppc64) return 0 ;;
ppc64le) return 0 ;;
mips) return 0 ;;
mipsle) return 0 ;;
mips64) return 0 ;;
mips64le) return 0 ;;
s390x) return 0 ;;
amd64p32) return 0 ;;
esac
log_crit "uname_arch_check '$(uname -m)' got converted to '$arch' which is not a GOARCH value. Please file bug report at https://github.com/client9/shlib"
return 1
}
untar() {
tarball=$1
case "${tarball}" in
*.tar.gz | *.tgz) tar --no-same-owner -xzf "${tarball}" ;;
*.tar) tar --no-same-owner -xf "${tarball}" ;;
*.zip) unzip "${tarball}" ;;
*)
log_err "untar unknown archive format for ${tarball}"
return 1
;;
esac
}
http_download_curl() {
local_file=$1
source_url=$2
header=$3
if [ -z "$header" ]; then
code=$(curl -w '%{http_code}' -sL -o "$local_file" "$source_url")
else
code=$(curl -w '%{http_code}' -sL -H "$header" -o "$local_file" "$source_url")
fi
if [ "$code" != "200" ]; then
log_debug "http_download_curl received HTTP status $code"
return 1
fi
return 0
}
http_download_wget() {
local_file=$1
source_url=$2
header=$3
if [ -z "$header" ]; then
wget -q -O "$local_file" "$source_url"
else
wget -q --header "$header" -O "$local_file" "$source_url"
fi
}
http_download() {
log_debug "http_download $2"
if is_command curl; then
http_download_curl "$@"
return
elif is_command wget; then
http_download_wget "$@"
return
fi
log_crit "http_download unable to find wget or curl"
return 1
}
http_copy() {
tmp=$(mktemp)
http_download "${tmp}" "$1" "$2" || return 1
body=$(cat "$tmp")
rm -f "${tmp}"
echo "$body"
}
github_release() {
owner_repo=$1
version=$2
test -z "$version" && version="latest"
giturl="https://github.com/${owner_repo}/releases/${version}"
json=$(http_copy "$giturl" "Accept:application/json")
test -z "$json" && return 1
version=$(echo "$json" | tr -s '\n' ' ' | sed 's/.*"tag_name":"//' | sed 's/".*//')
test -z "$version" && return 1
echo "$version"
}
hash_sha256() {
TARGET=${1:-/dev/stdin}
if is_command gsha256sum; then
hash=$(gsha256sum "$TARGET") || return 1
echo "$hash" | cut -d ' ' -f 1
elif is_command sha256sum; then
hash=$(sha256sum "$TARGET") || return 1
echo "$hash" | cut -d ' ' -f 1
elif is_command shasum; then
hash=$(shasum -a 256 "$TARGET" 2>/dev/null) || return 1
echo "$hash" | cut -d ' ' -f 1
elif is_command openssl; then
hash=$(openssl -dst openssl dgst -sha256 "$TARGET") || return 1
echo "$hash" | cut -d ' ' -f a
else
log_crit "hash_sha256 unable to find command to compute sha-256 hash"
return 1
fi
}
hash_sha256_verify() {
TARGET=$1
checksums=$2
if [ -z "$checksums" ]; then
log_err "hash_sha256_verify checksum file not specified in arg2"
return 1
fi
BASENAME=${TARGET##*/}
want=$(grep "${BASENAME}" "${checksums}" 2>/dev/null | tr '\t' ' ' | cut -d ' ' -f 1)
if [ -z "$want" ]; then
log_err "hash_sha256_verify unable to find checksum for '${TARGET}' in '${checksums}'"
return 1
fi
got=$(hash_sha256 "$TARGET")
if [ "$want" != "$got" ]; then
log_err "hash_sha256_verify checksum for '$TARGET' did not verify ${want} vs $got"
return 1
fi
}
cat /dev/null <<EOF
------------------------------------------------------------------------
End of functions from https://github.com/client9/shlib
------------------------------------------------------------------------
EOF
PROJECT_NAME="act"
OWNER=nektos
REPO="act"
BINARY=act
FORMAT=tar.gz
OS=$(uname_os)
ARCH=$(uname_arch)
PREFIX="$OWNER/$REPO"
# use in logging routines
log_prefix() {
echo "$PREFIX"
}
PLATFORM="${OS}/${ARCH}"
GITHUB_DOWNLOAD=https://github.com/${OWNER}/${REPO}/releases/download
uname_os_check "$OS"
uname_arch_check "$ARCH"
parse_args "$@"
get_binaries
tag_to_version
check_installed_version
adjust_format
adjust_os
adjust_arch
log_info "found version: ${VERSION} for ${TAG}/${OS}/${ARCH}"
NAME=${PROJECT_NAME}_${OS}_${ARCH}
TARBALL=${NAME}.${FORMAT}
TARBALL_URL=${GITHUB_DOWNLOAD}/${TAG}/${TARBALL}
CHECKSUM=checksums.txt
CHECKSUM_URL=${GITHUB_DOWNLOAD}/${TAG}/${CHECKSUM}
execute
================================================
FILE: main.go
================================================
package main
import (
_ "embed"
"github.com/nektos/act/cmd"
"github.com/nektos/act/pkg/common"
)
//go:embed VERSION
var version string
func main() {
ctx, cancel := common.CreateGracefulJobCancellationContext()
defer cancel()
// run the command
cmd.Execute(ctx, version)
}
================================================
FILE: main_test.go
================================================
package main
import (
"os"
"testing"
)
func TestMain(_ *testing.T) {
os.Args = []string{"act", "--help"}
main()
}
================================================
FILE: pkg/artifactcache/doc.go
================================================
// Package artifactcache provides a cache handler for the runner.
//
// Inspired by https://github.com/sp-ricard-valverde/github-act-cache-server
//
// TODO: Authorization
// TODO: Restrictions for accessing a cache, see https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows#restrictions-for-accessing-a-cache
// TODO: Force deleting cache entries, see https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows#force-deleting-cache-entries
package artifactcache
================================================
FILE: pkg/artifactcache/handler.go
================================================
package artifactcache
import (
"encoding/json"
"errors"
"fmt"
"io"
"net"
"net/http"
"os"
"path/filepath"
"regexp"
"strconv"
"strings"
"sync/atomic"
"time"
"github.com/julienschmidt/httprouter"
"github.com/sirupsen/logrus"
"github.com/timshannon/bolthold"
"go.etcd.io/bbolt"
"github.com/nektos/act/pkg/common"
)
const (
urlBase = "/_apis/artifactcache"
)
type Handler struct {
dir string
storage *Storage
router *httprouter.Router
listener net.Listener
server *http.Server
logger logrus.FieldLogger
gcing atomic.Bool
gcAt time.Time
outboundIP string
customExternalURL string
}
func StartHandler(dir, customExternalURL string, outboundIP string, port uint16, logger logrus.FieldLogger) (*Handler, error) {
h := &Handler{}
if logger == nil {
discard := logrus.New()
discard.Out = io.Discard
logger = discard
}
logger = logger.WithField("module", "artifactcache")
h.logger = logger
if dir == "" {
home, err := os.UserHomeDir()
if err != nil {
return nil, err
}
dir = filepath.Join(home, ".cache", "actcache")
}
if err := os.MkdirAll(dir, 0o755); err != nil {
return nil, err
}
h.dir = dir
storage, err := NewStorage(filepath.Join(dir, "cache"))
if err != nil {
return nil, err
}
h.storage = storage
if customExternalURL != "" {
h.customExternalURL = customExternalURL
}
if outboundIP != "" {
h.outboundIP = outboundIP
} else if ip := common.GetOutboundIP(); ip == nil {
return nil, fmt.Errorf("unable to determine outbound IP address")
} else {
h.outboundIP = ip.String()
}
router := httprouter.New()
router.GET(urlBase+"/cache", h.middleware(h.find))
router.POST(urlBase+"/caches", h.middleware(h.reserve))
router.PATCH(urlBase+"/caches/:id", h.middleware(h.upload))
router.POST(urlBase+"/caches/:id", h.middleware(h.commit))
router.GET(urlBase+"/artifacts/:id", h.middleware(h.get))
router.POST(urlBase+"/clean", h.middleware(h.clean))
h.router = router
h.gcCache()
listener, err := net.Listen("tcp", fmt.Sprintf(":%d", port)) // listen on all interfaces
if err != nil {
return nil, err
}
server := &http.Server{
ReadHeaderTimeout: 2 * time.Second,
Handler: router,
}
go func() {
if err := server.Serve(listener); err != nil && errors.Is(err, net.ErrClosed) {
logger.Errorf("http serve: %v", err)
}
}()
h.listener = listener
h.server = server
return h, nil
}
func (h *Handler) GetActualPort() int {
return h.listener.Addr().(*net.TCPAddr).Port
}
func (h *Handler) ExternalURL() string {
if h.customExternalURL != "" {
return h.customExternalURL
}
return fmt.Sprintf("http://%s:%d", h.outboundIP, h.GetActualPort())
}
func (h *Handler) Close() error {
if h == nil {
return nil
}
var retErr error
if h.server != nil {
err := h.server.Close()
if err != nil {
retErr = err
}
h.server = nil
}
if h.listener != nil {
err := h.listener.Close()
if errors.Is(err, net.ErrClosed) {
err = nil
}
if err != nil {
retErr = err
}
h.listener = nil
}
return retErr
}
func (h *Handler) openDB() (*bolthold.Store, error) {
return bolthold.Open(filepath.Join(h.dir, "bolt.db"), 0o644, &bolthold.Options{
Encoder: json.Marshal,
Decoder: json.Unmarshal,
Options: &bbolt.Options{
Timeout: 5 * time.Second,
NoGrowSync: bbolt.DefaultOptions.NoGrowSync,
FreelistType: bbolt.DefaultOptions.FreelistType,
},
})
}
// GET /_apis/artifactcache/cache
func (h *Handler) find(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
keys := strings.Split(r.URL.Query().Get("keys"), ",")
// cache keys are case insensitive
for i, key := range keys {
keys[i] = strings.ToLower(key)
}
version := r.URL.Query().Get("version")
db, err := h.openDB()
if err != nil {
h.responseJSON(w, r, 500, err)
return
}
defer db.Close()
cache, err := findCache(db, keys, version)
if err != nil {
h.responseJSON(w, r, 500, err)
return
}
if cache == nil {
h.responseJSON(w, r, 204)
return
}
if ok, err := h.storage.Exist(cache.ID); err != nil {
h.responseJSON(w, r, 500, err)
return
} else if !ok {
_ = db.Delete(cache.ID, cache)
h.responseJSON(w, r, 204)
return
}
h.responseJSON(w, r, 200, map[string]any{
"result": "hit",
"archiveLocation": fmt.Sprintf("%s%s/artifacts/%d", h.ExternalURL(), urlBase, cache.ID),
"cacheKey": cache.Key,
})
}
// POST /_apis/artifactcache/caches
func (h *Handler) reserve(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
api := &Request{}
if err := json.NewDecoder(r.Body).Decode(api); err != nil {
h.responseJSON(w, r, 400, err)
return
}
// cache keys are case insensitive
api.Key = strings.ToLower(api.Key)
cache := api.ToCache()
db, err := h.openDB()
if err != nil {
h.responseJSON(w, r, 500, err)
return
}
defer db.Close()
now := time.Now().Unix()
cache.CreatedAt = now
cache.UsedAt = now
if err := insertCache(db, cache); err != nil {
h.responseJSON(w, r, 500, err)
return
}
h.responseJSON(w, r, 200, map[string]any{
"cacheId": cache.ID,
})
}
// PATCH /_apis/artifactcache/caches/:id
func (h *Handler) upload(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
id, err := strconv.ParseUint(params.ByName("id"), 10, 64)
if err != nil {
h.responseJSON(w, r, 400, err)
return
}
cache := &Cache{}
db, err := h.openDB()
if err != nil {
h.responseJSON(w, r, 500, err)
return
}
defer db.Close()
if err := db.Get(id, cache); err != nil {
if errors.Is(err, bolthold.ErrNotFound) {
h.responseJSON(w, r, 400, fmt.Errorf("cache %d: not reserved", id))
return
}
h.responseJSON(w, r, 500, err)
return
}
if cache.Complete {
h.responseJSON(w, r, 400, fmt.Errorf("cache %v %q: already complete", cache.ID, cache.Key))
return
}
db.Close()
start, _, err := parseContentRange(r.Header.Get("Content-Range"))
if err != nil {
h.responseJSON(w, r, 400, err)
return
}
if err := h.storage.Write(cache.ID, start, r.Body); err != nil {
h.responseJSON(w, r, 500, err)
}
h.useCache(id)
h.responseJSON(w, r, 200)
}
// POST /_apis/artifactcache/caches/:id
func (h *Handler) commit(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
id, err := strconv.ParseInt(params.ByName("id"), 10, 64)
if err != nil {
h.responseJSON(w, r, 400, err)
return
}
cache := &Cache{}
db, err := h.openDB()
if err != nil {
h.responseJSON(w, r, 500, err)
return
}
defer db.Close()
if err := db.Get(id, cache); err != nil {
if errors.Is(err, bolthold.ErrNotFound) {
h.responseJSON(w, r, 400, fmt.Errorf("cache %d: not reserved", id))
return
}
h.responseJSON(w, r, 500, err)
return
}
if cache.Complete {
h.responseJSON(w, r, 400, fmt.Errorf("cache %v %q: already complete", cache.ID, cache.Key))
return
}
db.Close()
size, err := h.storage.Commit(cache.ID, cache.Size)
if err != nil {
h.responseJSON(w, r, 500, err)
return
}
// write real size back to cache, it may be different from the current value when the request doesn't specify it.
cache.Size = size
db, err = h.openDB()
if err != nil {
h.responseJSON(w, r, 500, err)
return
}
defer db.Close()
cache.Complete = true
if err := db.Update(cache.ID, cache); err != nil {
h.responseJSON(w, r, 500, err)
return
}
h.responseJSON(w, r, 200)
}
// GET /_apis/artifactcache/artifacts/:id
func (h *Handler) get(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
id, err := strconv.ParseUint(params.ByName("id"), 10, 64)
if err != nil {
h.responseJSON(w, r, 400, err)
return
}
h.useCache(id)
h.storage.Serve(w, r, id)
}
// POST /_apis/artifactcache/clean
func (h *Handler) clean(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
// TODO: don't support force deleting cache entries
// see: https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows#force-deleting-cache-entries
h.responseJSON(w, r, 200)
}
func (h *Handler) middleware(handler httprouter.Handle) httprouter.Handle {
return func(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
h.logger.Debugf("%s %s", r.Method, r.RequestURI)
handler(w, r, params)
go h.gcCache()
}
}
// if not found, return (nil, nil) instead of an error.
func findCache(db *bolthold.Store, keys []string, version string) (*Cache, error) {
cache := &Cache{}
for _, prefix := range keys {
// if a key in the list matches exactly, don't return partial matches
if err := db.FindOne(cache,
bolthold.Where("Key").Eq(prefix).
And("Version").Eq(version).
And("Complete").Eq(true).
SortBy("CreatedAt").Reverse()); err == nil || !errors.Is(err, bolthold.ErrNotFound) {
if err != nil {
return nil, fmt.Errorf("find cache: %w", err)
}
return cache, nil
}
prefixPattern := fmt.Sprintf("^%s", regexp.QuoteMeta(prefix))
re, err := regexp.Compile(prefixPattern)
if err != nil {
continue
}
if err := db.FindOne(cache,
bolthold.Where("Key").RegExp(re).
And("Version").Eq(version).
And("Complete").Eq(true).
SortBy("CreatedAt").Reverse()); err != nil {
if errors.Is(err, bolthold.ErrNotFound) {
continue
}
return nil, fmt.Errorf("find cache: %w", err)
}
return cache, nil
}
return nil, nil
}
func insertCache(db *bolthold.Store, cache *Cache) error {
if err := db.Insert(bolthold.NextSequence(), cache); err != nil {
return fmt.Errorf("insert cache: %w", err)
}
// write back id to db
if err := db.Update(cache.ID, cache); err != nil {
return fmt.Errorf("write back id to db: %w", err)
}
return nil
}
func (h *Handler) useCache(id uint64) {
db, err := h.openDB()
if err != nil {
return
}
defer db.Close()
cache := &Cache{}
if err := db.Get(id, cache); err != nil {
return
}
cache.UsedAt = time.Now().Unix()
_ = db.Update(cache.ID, cache)
}
const (
keepUsed = 30 * 24 * time.Hour
keepUnused = 7 * 24 * time.Hour
keepTemp = 5 * time.Minute
keepOld = 5 * time.Minute
)
func (h *Handler) gcCache() {
if h.gcing.Load() {
return
}
if !h.gcing.CompareAndSwap(false, true) {
return
}
defer h.gcing.Store(false)
if time.Since(h.gcAt) < time.Hour {
h.logger.Debugf("skip gc: %v", h.gcAt.String())
return
}
h.gcAt = time.Now()
h.logger.Debugf("gc: %v", h.gcAt.String())
db, err := h.openDB()
if err != nil {
return
}
defer db.Close()
// Remove the caches which are not completed for a while, they are most likely to be broken.
var caches []*Cache
if err := db.Find(&caches, bolthold.
Where("UsedAt").Lt(time.Now().Add(-keepTemp).Unix()).
And("Complete").Eq(false),
); err != nil {
h.logger.Warnf("find caches: %v", err)
} else {
for _, cache := range caches {
h.storage.Remove(cache.ID)
if err := db.Delete(cache.ID, cache); err != nil {
h.logger.Warnf("delete cache: %v", err)
continue
}
h.logger.Infof("deleted cache: %+v", cache)
}
}
// Remove the old caches which have not been used recently.
caches = caches[:0]
if err := db.Find(&caches, bolthold.
Where("UsedAt").Lt(time.Now().Add(-keepUnused).Unix()),
); err != nil {
h.logger.Warnf("find caches: %v", err)
} else {
for _, cache := range caches {
h.storage.Remove(cache.ID)
if err := db.Delete(cache.ID, cache); err != nil {
h.logger.Warnf("delete cache: %v", err)
continue
}
h.logger.Infof("deleted cache: %+v", cache)
}
}
// Remove the old caches which are too old.
caches = caches[:0]
if err := db.Find(&caches, bolthold.
Where("CreatedAt").Lt(time.Now().Add(-keepUsed).Unix()),
); err != nil {
h.logger.Warnf("find caches: %v", err)
} else {
for _, cache := range caches {
h.storage.Remove(cache.ID)
if err := db.Delete(cache.ID, cache); err != nil {
h.logger.Warnf("delete cache: %v", err)
continue
}
h.logger.Infof("deleted cache: %+v", cache)
}
}
// Remove the old caches with the same key and version, keep the latest one.
// Also keep the olds which have been used recently for a while in case of the cache is still in use.
if results, err := db.FindAggregate(
&Cache{},
bolthold.Where("Complete").Eq(true),
"Key", "Version",
); err != nil {
h.logger.Warnf("find aggregate caches: %v", err)
} else {
for _, result := range results {
if result.Count() <= 1 {
continue
}
result.Sort("CreatedAt")
caches = caches[:0]
result.Reduction(&caches)
for _, cache := range caches[:len(caches)-1] {
if time.Since(time.Unix(cache.UsedAt, 0)) < keepOld {
// Keep it since it has been used recently, even if it's old.
// Or it could break downloading in process.
continue
}
h.storage.Remove(cache.ID)
if err := db.Delete(cache.ID, cache); err != nil {
h.logger.Warnf("delete cache: %v", err)
continue
}
h.logger.Infof("deleted cache: %+v", cache)
}
}
}
}
func (h *Handler) responseJSON(w http.ResponseWriter, r *http.Request, code int, v ...any) {
w.Header().Set("Content-Type", "application/json; charset=utf-8")
var data []byte
if len(v) == 0 || v[0] == nil {
data, _ = json.Marshal(struct{}{})
} else if err, ok := v[0].(error); ok {
h.logger.Errorf("%v %v: %v", r.Method, r.RequestURI, err)
data, _ = json.Marshal(map[string]any{
"error": err.Error(),
})
} else {
data, _ = json.Marshal(v[0])
}
w.WriteHeader(code)
_, _ = w.Write(data)
}
func parseContentRange(s string) (int64, int64, error) {
// support the format like "bytes 11-22/*" only
s, _, _ = strings.Cut(strings.TrimPrefix(s, "bytes "), "/")
s1, s2, _ := strings.Cut(s, "-")
start, err := strconv.ParseInt(s1, 10, 64)
if err != nil {
return 0, 0, fmt.Errorf("parse %q: %w", s, err)
}
stop, err := strconv.ParseInt(s2, 10, 64)
if err != nil {
return 0, 0, fmt.Errorf("parse %q: %w", s, err)
}
return start, stop, nil
}
================================================
FILE: pkg/artifactcache/handler_test.go
================================================
package artifactcache
import (
"bytes"
"crypto/rand"
"encoding/json"
"fmt"
"io"
"net/http"
"path/filepath"
"strings"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/timshannon/bolthold"
"go.etcd.io/bbolt"
)
func TestHandler(t *testing.T) {
dir := filepath.Join(t.TempDir(), "artifactcache")
handler, err := StartHandler(dir, "", "", 0, nil)
require.NoError(t, err)
base := fmt.Sprintf("%s%s", handler.ExternalURL(), urlBase)
defer func() {
t.Run("inpect db", func(t *testing.T) {
db, err := handler.openDB()
require.NoError(t, err)
defer db.Close()
require.NoError(t, db.Bolt().View(func(tx *bbolt.Tx) error {
return tx.Bucket([]byte("Cache")).ForEach(func(k, v []byte) error {
t.Logf("%s: %s", k, v)
return nil
})
}))
})
t.Run("close", func(t *testing.T) {
require.NoError(t, handler.Close())
assert.Nil(t, handler.server)
assert.Nil(t, handler.listener)
_, err := http.Post(fmt.Sprintf("%s/caches/%d", base, 1), "", nil)
assert.Error(t, err)
})
}()
t.Run("get not exist", func(t *testing.T) {
key := strings.ToLower(t.Name())
version := "c19da02a2bd7e77277f1ac29ab45c09b7d46a4ee758284e26bb3045ad11d9d20"
resp, err := http.Get(fmt.Sprintf("%s/cache?keys=%s&version=%s", base, key, version))
require.NoError(t, err)
require.Equal(t, 204, resp.StatusCode)
})
t.Run("reserve and upload", func(t *testing.T) {
key := strings.ToLower(t.Name())
version := "c19da02a2bd7e77277f1ac29ab45c09b7d46a4ee758284e26bb3045ad11d9d20"
content := make([]byte, 100)
_, err := rand.Read(content)
require.NoError(t, err)
uploadCacheNormally(t, base, key, version, content)
})
t.Run("clean", func(t *testing.T) {
resp, err := http.Post(fmt.Sprintf("%s/clean", base), "", nil)
require.NoError(t, err)
assert.Equal(t, 200, resp.StatusCode)
})
t.Run("reserve with bad request", func(t *testing.T) {
body := []byte(`invalid json`)
require.NoError(t, err)
resp, err := http.Post(fmt.Sprintf("%s/caches", base), "application/json", bytes.NewReader(body))
require.NoError(t, err)
assert.Equal(t, 400, resp.StatusCode)
})
t.Run("duplicate reserve", func(t *testing.T) {
key := strings.ToLower(t.Name())
version := "c19da02a2bd7e77277f1ac29ab45c09b7d46a4ee758284e26bb3045ad11d9d20"
var first, second struct {
CacheID uint64 `json:"cacheId"`
}
{
body, err := json.Marshal(&Request{
Key: key,
Version: version,
Size: 100,
})
require.NoError(t, err)
resp, err := http.Post(fmt.Sprintf("%s/caches", base), "application/json", bytes.NewReader(body))
require.NoError(t, err)
assert.Equal(t, 200, resp.StatusCode)
require.NoError(t, json.NewDecoder(resp.Body).Decode(&first))
assert.NotZero(t, first.CacheID)
}
{
body, err := json.Marshal(&Request{
Key: key,
Version: version,
Size: 100,
})
require.NoError(t, err)
resp, err := http.Post(fmt.Sprintf("%s/caches", base), "application/json", bytes.NewReader(body))
require.NoError(t, err)
assert.Equal(t, 200, resp.StatusCode)
require.NoError(t, json.NewDecoder(resp.Body).Decode(&second))
assert.NotZero(t, second.CacheID)
}
assert.NotEqual(t, first.CacheID, second.CacheID)
})
t.Run("upload with bad id", func(t *testing.T) {
req, err := http.NewRequest(http.MethodPatch,
fmt.Sprintf("%s/caches/invalid_id", base), bytes.NewReader(nil))
require.NoError(t, err)
req.Header.Set("Content-Type", "application/octet-stream")
req.Header.Set("Content-Range", "bytes 0-99/*")
resp, err := http.DefaultClient.Do(req)
require.NoError(t, err)
assert.Equal(t, 400, resp.StatusCode)
})
t.Run("upload without reserve", func(t *testing.T) {
req, err := http.NewRequest(http.MethodPatch,
fmt.Sprintf("%s/caches/%d", base, 1000), bytes.NewReader(nil))
require.NoError(t, err)
req.Header.Set("Content-Type", "application/octet-stream")
req.Header.Set("Content-Range", "bytes 0-99/*")
resp, err := http.DefaultClient.Do(req)
require.NoError(t, err)
assert.Equal(t, 400, resp.StatusCode)
})
t.Run("upload with complete", func(t *testing.T) {
key := strings.ToLower(t.Name())
version := "c19da02a2bd7e77277f1ac29ab45c09b7d46a4ee758284e26bb3045ad11d9d20"
var id uint64
content := make([]byte, 100)
_, err := rand.Read(content)
require.NoError(t, err)
{
body, err := json.Marshal(&Request{
Key: key,
Version: version,
Size: 100,
})
require.NoError(t, err)
resp, err := http.Post(fmt.Sprintf("%s/caches", base), "application/json", bytes.NewReader(body))
require.NoError(t, err)
assert.Equal(t, 200, resp.StatusCode)
got := struct {
CacheID uint64 `json:"cacheId"`
}{}
require.NoError(t, json.NewDecoder(resp.Body).Decode(&got))
id = got.CacheID
}
{
req, err := http.NewRequest(http.MethodPatch,
fmt.Sprintf("%s/caches/%d", base, id), bytes.NewReader(content))
require.NoError(t, err)
req.Header.Set("Content-Type", "application/octet-stream")
req.Header.Set("Content-Range", "bytes 0-99/*")
resp, err := http.DefaultClient.Do(req)
require.NoError(t, err)
assert.Equal(t, 200, resp.StatusCode)
}
{
resp, err := http.Post(fmt.Sprintf("%s/caches/%d", base, id), "", nil)
require.NoError(t, err)
assert.Equal(t, 200, resp.StatusCode)
}
{
req, err := http.NewRequest(http.MethodPatch,
fmt.Sprintf("%s/caches/%d", base, id), bytes.NewReader(content))
require.NoError(t, err)
req.Header.Set("Content-Type", "application/octet-stream")
req.Header.Set("Content-Range", "bytes 0-99/*")
resp, err := http.DefaultClient.Do(req)
require.NoError(t, err)
assert.Equal(t, 400, resp.StatusCode)
}
})
t.Run("upload with invalid range", func(t *testing.T) {
key := strings.ToLower(t.Name())
version := "c19da02a2bd7e77277f1ac29ab45c09b7d46a4ee758284e26bb3045ad11d9d20"
var id uint64
content := make([]byte, 100)
_, err := rand.Read(content)
require.NoError(t, err)
{
body, err := json.Marshal(&Request{
Key: key,
Version: version,
Size: 100,
})
require.NoError(t, err)
resp, err := http.Post(fmt.Sprintf("%s/caches", base), "application/json", bytes.NewReader(body))
require.NoError(t, err)
assert.Equal(t, 200, resp.StatusCode)
got := struct {
CacheID uint64 `json:"cacheId"`
}{}
require.NoError(t, json.NewDecoder(resp.Body).Decode(&got))
id = got.CacheID
}
{
req, err := http.NewRequest(http.MethodPatch,
fmt.Sprintf("%s/caches/%d", base, id), bytes.NewReader(content))
require.NoError(t, err)
req.Header.Set("Content-Type", "application/octet-stream")
req.Header.Set("Content-Range", "bytes xx-99/*")
resp, err := http.DefaultClient.Do(req)
require.NoError(t, err)
assert.Equal(t, 400, resp.StatusCode)
}
})
t.Run("commit with bad id", func(t *testing.T) {
{
resp, err := http.Post(fmt.Sprintf("%s/caches/invalid_id", base), "", nil)
require.NoError(t, err)
assert.Equal(t, 400, resp.StatusCode)
}
})
t.Run("commit with not exist id", func(t *testing.T) {
{
resp, err := http.Post(fmt.Sprintf("%s/caches/%d", base, 100), "", nil)
require.NoError(t, err)
assert.Equal(t, 400, resp.StatusCode)
}
})
t.Run("duplicate commit", func(t *testing.T) {
key := strings.ToLower(t.Name())
version := "c19da02a2bd7e77277f1ac29ab45c09b7d46a4ee758284e26bb3045ad11d9d20"
var id uint64
content := make([]byte, 100)
_, err := rand.Read(content)
require.NoError(t, err)
{
body, err := json.Marshal(&Request{
Key: key,
Version: version,
Size: 100,
})
require.NoError(t, err)
resp, err := http.Post(fmt.Sprintf("%s/caches", base), "application/json", bytes.NewReader(body))
require.NoError(t, err)
assert.Equal(t, 200, resp.StatusCode)
got := struct {
CacheID uint64 `json:"cacheId"`
}{}
require.NoError(t, json.NewDecoder(resp.Body).Decode(&got))
id = got.CacheID
}
{
req, err := http.NewRequest(http.MethodPatch,
fmt.Sprintf("%s/caches/%d", base, id), bytes.NewReader(content))
require.NoError(t, err)
req.Header.Set("Content-Type", "application/octet-stream")
req.Header.Set("Content-Range", "bytes 0-99/*")
resp, err := http.DefaultClient.Do(req)
require.NoError(t, err)
assert.Equal(t, 200, resp.StatusCode)
}
{
resp, err := http.Post(fmt.Sprintf("%s/caches/%d", base, id), "", nil)
require.NoError(t, err)
assert.Equal(t, 200, resp.StatusCode)
}
{
resp, err := http.Post(fmt.Sprintf("%s/caches/%d", base, id), "", nil)
require.NoError(t, err)
assert.Equal(t, 400, resp.StatusCode)
}
})
t.Run("commit early", func(t *testing.T) {
key := strings.ToLower(t.Name())
version := "c19da02a2bd7e77277f1ac29ab45c09b7d46a4ee758284e26bb3045ad11d9d20"
var id uint64
content := make([]byte, 100)
_, err := rand.Read(content)
require.NoError(t, err)
{
body, err := json.Marshal(&Request{
Key: key,
Version: version,
Size: 100,
})
require.NoError(t, err)
resp, err := http.Post(fmt.Sprintf("%s/caches", base), "application/json", bytes.NewReader(body))
require.NoError(t, err)
assert.Equal(t, 200, resp.StatusCode)
got := struct {
CacheID uint64 `json:"cacheId"`
}{}
require.NoError(t, json.NewDecoder(resp.Body).Decode(&got))
id = got.CacheID
}
{
req, err := http.NewRequest(http.MethodPatch,
fmt.Sprintf("%s/caches/%d", base, id), bytes.NewReader(content[:50]))
require.NoError(t, err)
req.Header.Set("Content-Type", "application/octet-stream")
req.Header.Set("Content-Range", "bytes 0-59/*")
resp, err := http.DefaultClient.Do(req)
require.NoError(t, err)
assert.Equal(t, 200, resp.StatusCode)
}
{
resp, err := http.Post(fmt.Sprintf("%s/caches/%d", base, id), "", nil)
require.NoError(t, err)
assert.Equal(t, 500, resp.StatusCode)
}
})
t.Run("get with bad id", func(t *testing.T) {
resp, err := http.Get(fmt.Sprintf("%s/artifacts/invalid_id", base))
require.NoError(t, err)
require.Equal(t, 400, resp.StatusCode)
})
t.Run("get with not exist id", func(t *testing.T) {
resp, err := http.Get(fmt.Sprintf("%s/artifacts/%d", base, 100))
require.NoError(t, err)
require.Equal(t, 404, resp.StatusCode)
})
t.Run("get with not exist id", func(t *testing.T) {
resp, err := http.Get(fmt.Sprintf("%s/artifacts/%d", base, 100))
require.NoError(t, err)
require.Equal(t, 404, resp.StatusCode)
})
t.Run("get with multiple keys", func(t *testing.T) {
version := "c19da02a2bd7e77277f1ac29ab45c09b7d46a4ee758284e26bb3045ad11d9d20"
key := strings.ToLower(t.Name())
keys := [3]string{
key + "_a_b_c",
key + "_a_b",
key + "_a",
}
contents := [3][]byte{
make([]byte, 100),
make([]byte, 200),
make([]byte, 300),
}
for i := range contents {
_, err := rand.Read(contents[i])
require.NoError(t, err)
uploadCacheNormally(t, base, keys[i], version, contents[i])
time.Sleep(time.Second) // ensure CreatedAt of caches are different
}
reqKeys := strings.Join([]string{
key + "_a_b_x",
key + "_a_b",
key + "_a",
}, ",")
resp, err := http.Get(fmt.Sprintf("%s/cache?keys=%s&version=%s", base, reqKeys, version))
require.NoError(t, err)
require.Equal(t, 200, resp.StatusCode)
/*
Expect `key_a_b` because:
- `key_a_b_x" doesn't match any caches.
- `key_a_b" matches `key_a_b` and `key_a_b_c`, but `key_a_b` is newer.
*/
except := 1
got := struct {
Result string `json:"result"`
ArchiveLocation string `json:"archiveLocation"`
CacheKey string `json:"cacheKey"`
}{}
require.NoError(t, json.NewDecoder(resp.Body).Decode(&got))
assert.Equal(t, "hit", got.Result)
assert.Equal(t, keys[except], got.CacheKey)
contentResp, err := http.Get(got.ArchiveLocation)
require.NoError(t, err)
require.Equal(t, 200, contentResp.StatusCode)
content, err := io.ReadAll(contentResp.Body)
require.NoError(t, err)
assert.Equal(t, contents[except], content)
})
t.Run("case insensitive", func(t *testing.T) {
version := "c19da02a2bd7e77277f1ac29ab45c09b7d46a4ee758284e26bb3045ad11d9d20"
key := strings.ToLower(t.Name())
content := make([]byte, 100)
_, err := rand.Read(content)
require.NoError(t, err)
uploadCacheNormally(t, base, key+"_ABC", version, content)
{
reqKey := key + "_aBc"
resp, err := http.Get(fmt.Sprintf("%s/cache?keys=%s&version=%s", base, reqKey, version))
require.NoError(t, err)
require.Equal(t, 200, resp.StatusCode)
got := struct {
Result string `json:"result"`
ArchiveLocation string `json:"archiveLocation"`
CacheKey string `json:"cacheKey"`
}{}
require.NoError(t, json.NewDecoder(resp.Body).Decode(&got))
assert.Equal(t, "hit", got.Result)
assert.Equal(t, key+"_abc", got.CacheKey)
}
})
t.Run("exact keys are preferred (key 0)", func(t *testing.T) {
version := "c19da02a2bd7e77277f1ac29ab45c09b7d46a4ee758284e26bb3045ad11d9d20"
key := strings.ToLower(t.Name())
keys := [3]string{
key + "_a",
key + "_a_b_c",
key + "_a_b",
}
contents := [3][]byte{
make([]byte, 100),
make([]byte, 200),
make([]byte, 300),
}
for i := range contents {
_, err := rand.Read(contents[i])
require.NoError(t, err)
uploadCacheNormally(t, base, keys[i], version, contents[i])
time.Sleep(time.Second) // ensure CreatedAt of caches are different
}
reqKeys := strings.Join([]string{
key + "_a",
key + "_a_b",
}, ",")
resp, err := http.Get(fmt.Sprintf("%s/cache?keys=%s&version=%s", base, reqKeys, version))
require.NoError(t, err)
require.Equal(t, 200, resp.StatusCode)
/*
Expect `key_a` because:
- `key_a` matches `key_a`, `key_a_b` and `key_a_b_c`, but `key_a` is an exact match.
- `key_a_b` matches `key_a_b` and `key_a_b_c`, but previous key had a match
*/
expect := 0
got := struct {
ArchiveLocation string `json:"archiveLocation"`
CacheKey string `json:"cacheKey"`
}{}
require.NoError(t, json.NewDecoder(resp.Body).Decode(&got))
assert.Equal(t, keys[expect], got.CacheKey)
contentResp, err := http.Get(got.ArchiveLocation)
require.NoError(t, err)
require.Equal(t, 200, contentResp.StatusCode)
content, err := io.ReadAll(contentResp.Body)
require.NoError(t, err)
assert.Equal(t, contents[expect], content)
})
t.Run("exact keys are preferred (key 1)", func(t *testing.T) {
version := "c19da02a2bd7e77277f1ac29ab45c09b7d46a4ee758284e26bb3045ad11d9d20"
key := strings.ToLower(t.Name())
keys := [3]string{
key + "_a",
key + "_a_b_c",
key + "_a_b",
}
contents := [3][]byte{
make([]byte, 100),
make([]byte, 200),
make([]byte, 300),
}
for i := range contents {
_, err := rand.Read(contents[i])
require.NoError(t, err)
uploadCacheNormally(t, base, keys[i], version, contents[i])
time.Sleep(time.Second) // ensure CreatedAt of caches are different
}
reqKeys := strings.Join([]string{
"------------------------------------------------------",
key + "_a",
key + "_a_b",
}, ",")
resp, err := http.Get(fmt.Sprintf("%s/cache?keys=%s&version=%s", base, reqKeys, version))
require.NoError(t, err)
require.Equal(t, 200, resp.StatusCode)
/*
Expect `key_a` because:
- `------------------------------------------------------` doesn't match any caches.
- `key_a` matches `key_a`, `key_a_b` and `key_a_b_c`, but `key_a` is an exact match.
- `key_a_b` matches `key_a_b` and `key_a_b_c`, but previous key had a match
*/
expect := 0
got := struct {
ArchiveLocation string `json:"archiveLocation"`
CacheKey string `json:"cacheKey"`
}{}
require.NoError(t, json.NewDecoder(resp.Body).Decode(&got))
assert.Equal(t, keys[expect], got.CacheKey)
contentResp, err := http.Get(got.ArchiveLocation)
require.NoError(t, err)
require.Equal(t, 200, contentResp.StatusCode)
content, err := io.ReadAll(contentResp.Body)
require.NoError(t, err)
assert.Equal(t, contents[expect], content)
})
}
func uploadCacheNormally(t *testing.T, base, key, version string, content []byte) {
var id uint64
{
body, err := json.Marshal(&Request{
Key: key,
Version: version,
Size: int64(len(content)),
})
require.NoError(t, err)
resp, err := http.Post(fmt.Sprintf("%s/caches", base), "application/json", bytes.NewReader(body))
require.NoError(t, err)
assert.Equal(t, 200, resp.StatusCode)
got := struct {
CacheID uint64 `json:"cacheId"`
}{}
require.NoError(t, json.NewDecoder(resp.Body).Decode(&got))
id = got.CacheID
}
{
req, err := http.NewRequest(http.MethodPatch,
fmt.Sprintf("%s/caches/%d", base, id), bytes.NewReader(content))
require.NoError(t, err)
req.Header.Set("Content-Type", "application/octet-stream")
req.Header.Set("Content-Range", "bytes 0-99/*")
resp, err := http.DefaultClient.Do(req)
require.NoError(t, err)
assert.Equal(t, 200, resp.StatusCode)
}
{
resp, err := http.Post(fmt.Sprintf("%s/caches/%d", base, id), "", nil)
require.NoError(t, err)
assert.Equal(t, 200, resp.StatusCode)
}
var archiveLocation string
{
resp, err := http.Get(fmt.Sprintf("%s/cache?keys=%s&version=%s", base, key, version))
require.NoError(t, err)
require.Equal(t, 200, resp.StatusCode)
got := struct {
Result string `json:"result"`
ArchiveLocation string `json:"archiveLocation"`
CacheKey string `json:"cacheKey"`
}{}
require.NoError(t, json.NewDecoder(resp.Body).Decode(&got))
assert.Equal(t, "hit", got.Result)
assert.Equal(t, strings.ToLower(key), got.CacheKey)
archiveLocation = got.ArchiveLocation
}
{
resp, err := http.Get(archiveLocation) //nolint:gosec
require.NoError(t, err)
require.Equal(t, 200, resp.StatusCode)
got, err := io.ReadAll(resp.Body)
require.NoError(t, err)
assert.Equal(t, content, got)
}
}
func TestHandler_CustomExternalURL(t *testing.T) {
dir := filepath.Join(t.TempDir(), "artifactcache")
handler, err := StartHandler(dir, "", "", 0, nil)
require.NoError(t, err)
defer func() {
require.NoError(t, handler.Close())
}()
handler.customExternalURL = fmt.Sprintf("http://%s:%d", "127.0.0.1", handler.GetActualPort())
assert.Equal(t, fmt.Sprintf("http://%s:%d", "127.0.0.1", handler.GetActualPort()), handler.ExternalURL())
base := fmt.Sprintf("%s%s", handler.ExternalURL(), urlBase)
t.Run("advertise url set wrong", func(t *testing.T) {
original := handler.customExternalURL
defer func() {
handler.customExternalURL = original
}()
handler.customExternalURL = "http://127.0.0.999:1234"
assert.Equal(t, "http://127.0.0.999:1234", handler.ExternalURL())
})
t.Run("reserve and upload", func(t *testing.T) {
key := strings.ToLower(t.Name())
version := "c19da02a2bd7e77277f1ac29ab45c09b7d46a4ee758284e26bb3045ad11d9d20"
content := make([]byte, 100)
_, err := rand.Read(content)
require.NoError(t, err)
uploadCacheNormally(t, base, key, version, content)
})
}
func TestHandler_gcCache(t *testing.T) {
dir := filepath.Join(t.TempDir(), "artifactcache")
handler, err := StartHandler(dir, "", "", 0, nil)
require.NoError(t, err)
defer func() {
require.NoError(t, handler.Close())
}()
now := time.Now()
cases := []struct {
Cache *Cache
Kept bool
}{
{
// should be kept, since it's used recently and not too old.
Cache: &Cache{
Key: "test_key_1",
Version: "test_version",
Complete: true,
UsedAt: now.Unix(),
CreatedAt: now.Add(-time.Hour).Unix(),
},
Kept: true,
},
{
// should be removed, since it's not complete and not used for a while.
Cache: &Cache{
Key: "test_key_2",
Version: "test_version",
Complete: false,
UsedAt: now.Add(-(keepTemp + time.Second)).Unix(),
CreatedAt: now.Add(-(keepTemp + time.Hour)).Unix(),
},
Kept: false,
},
{
// should be removed, since it's not used for a while.
Cache: &Cache{
Key: "test_key_3",
Version: "test_version",
Complete: true,
UsedAt: now.Add(-(keepUnused + time.Second)).Unix(),
CreatedAt: now.Add(-(keepUnused + time.Hour)).Unix(),
},
Kept: false,
},
{
// should be removed, since it's used but too old.
Cache: &Cache{
Key: "test_key_3",
Version: "test_version",
Complete: true,
UsedAt: now.Unix(),
CreatedAt: now.Add(-(keepUsed + time.Second)).Unix(),
},
Kept: false,
},
{
// should be kept, since it has a newer edition but be used recently.
Cache: &Cache{
Key: "test_key_1",
Version: "test_version",
Complete: true,
UsedAt: now.Add(-(keepOld - time.Minute)).Unix(),
CreatedAt: now.Add(-(time.Hour + time.Second)).Unix(),
},
Kept: true,
},
{
// should be removed, since it has a newer edition and not be used recently.
Cache: &Cache{
Key: "test_key_1",
Version: "test_version",
Complete: true,
UsedAt: now.Add(-(keepOld + time.Second)).Unix(),
CreatedAt: now.Add(-(time.Hour + time.Second)).Unix(),
},
Kept: false,
},
}
db, err := handler.openDB()
require.NoError(t, err)
for _, c := range cases {
require.NoError(t, insertCache(db, c.Cache))
}
require.NoError(t, db.Close())
handler.gcAt = time.Time{} // ensure gcCache will not skip
handler.gcCache()
db, err = handler.openDB()
require.NoError(t, err)
for i, v := range cases {
t.Run(fmt.Sprintf("%d_%s", i, v.Cache.Key), func(t *testing.T) {
cache := &Cache{}
err = db.Get(v.Cache.ID, cache)
if v.Kept {
assert.NoError(t, err)
} else {
assert.ErrorIs(t, err, bolthold.ErrNotFound)
}
})
}
require.NoError(t, db.Close())
}
================================================
FILE: pkg/artifactcache/model.go
================================================
package artifactcache
type Request struct {
Key string `json:"key" `
Version string `json:"version"`
Size int64 `json:"cacheSize"`
}
func (c *Request) ToCache() *Cache {
if c == nil {
return nil
}
ret := &Cache{
Key: c.Key,
Version: c.Version,
Size: c.Size,
}
if c.Size == 0 {
// So the request comes from old versions of actions, like `actions/cache@v2`.
// It doesn't send cache size. Set it to -1 to indicate that.
ret.Size = -1
}
return ret
}
type Cache struct {
ID uint64 `json:"id" boltholdKey:"ID"`
Key string `json:"key" boltholdIndex:"Key"`
Version string `json:"version" boltholdIndex:"Version"`
Size int64 `json:"cacheSize"`
Complete bool `json:"complete" boltholdIndex:"Complete"`
UsedAt int64 `json:"usedAt" boltholdIndex:"UsedAt"`
CreatedAt int64 `json:"createdAt" boltholdIndex:"CreatedAt"`
}
================================================
FILE: pkg/artifactcache/storage.go
================================================
package artifactcache
import (
"fmt"
"io"
"net/http"
"os"
"path/filepath"
)
type Storage struct {
rootDir string
}
func NewStorage(rootDir string) (*Storage, error) {
if err := os.MkdirAll(rootDir, 0o755); err != nil {
return nil, err
}
return &Storage{
rootDir: rootDir,
}, nil
}
func (s *Storage) Exist(id uint64) (bool, error) {
name := s.filename(id)
if _, err := os.Stat(name); os.IsNotExist(err) {
return false, nil
} else if err != nil {
return false, err
}
return true, nil
}
func (s *Storage) Write(id uint64, offset int64, reader io.Reader) error {
name := s.tempName(id, offset)
if err := os.MkdirAll(filepath.Dir(name), 0o755); err != nil {
return err
}
file, err := os.Create(name)
if err != nil {
return err
}
defer file.Close()
_, err = io.Copy(file, reader)
return err
}
func (s *Storage) Commit(id uint64, size int64) (int64, error) {
defer func() {
_ = os.RemoveAll(s.tempDir(id))
}()
name := s.filename(id)
tempNames, err := s.tempNames(id)
if err != nil {
return 0, err
}
if err := os.MkdirAll(filepath.Dir(name), 0o755); err != nil {
return 0, err
}
file, err := os.Create(name)
if err != nil {
return 0, err
}
defer file.Close()
var written int64
for _, v := range tempNames {
f, err := os.Open(v)
if err != nil {
return 0, err
}
n, err := io.Copy(file, f)
_ = f.Close()
if err != nil {
return 0, err
}
written += n
}
// If size is less than 0, it means the size is unknown.
// We can't check the size of the file, just skip the check.
// It happens when the request comes from old versions of actions, like `actions/cache@v2`.
if size >= 0 && written != size {
_ = file.Close()
_ = os.Remove(name)
return 0, fmt.Errorf("broken file: %v != %v", written, size)
}
return written, nil
}
func (s *Storage) Serve(w http.ResponseWriter, r *http.Request, id uint64) {
name := s.filename(id)
http.ServeFile(w, r, name)
}
func (s *Storage) Remove(id uint64) {
_ = os.Remove(s.filename(id))
_ = os.RemoveAll(s.tempDir(id))
}
func (s *Storage) filename(id uint64) string {
return filepath.Join(s.rootDir, fmt.Sprintf("%02x", id%0xff), fmt.Sprint(id))
}
func (s *Storage) tempDir(id uint64) string {
return filepath.Join(s.rootDir, "tmp", fmt.Sprint(id))
}
func (s *Storage) tempName(id uint64, offset int64) string {
return filepath.Join(s.tempDir(id), fmt.Sprintf("%016x", offset))
}
func (s *Storage) tempNames(id uint64) ([]string, error) {
dir := s.tempDir(id)
files, err := os.ReadDir(dir)
if err != nil {
return nil, err
}
var names []string
for _, v := range files {
if !v.IsDir() {
names = append(names, filepath.Join(dir, v.Name()))
}
}
return names, nil
}
================================================
FILE: pkg/artifactcache/testdata/example/example.yaml
================================================
# Copied from https://github.com/actions/cache#example-cache-workflow
name: Caching Primes
on: push
jobs:
build:
runs-on: ubuntu-latest
steps:
- run: env
- uses: actions/checkout@v3
- name: Cache Primes
id: cache-primes
uses: actions/cache@v3
with:
path: prime-numbers
key: ${{ runner.os }}-primes-${{ github.run_id }}
restore-keys: |
${{ runner.os }}-primes
${{ runner.os }}
- name: Generate Prime Numbers
if: steps.cache-primes.outputs.cache-hit != 'true'
run: cat /proc/sys/kernel/random/uuid > prime-numbers
- name: Use Prime Numbers
run: cat prime-numbers
================================================
FILE: pkg/artifacts/artifact.pb.go
================================================
// Copyright 2024 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.32.0
// protoc v4.25.2
// source: artifact.proto
package artifacts
import (
reflect "reflect"
sync "sync"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
timestamppb "google.golang.org/protobuf/types/known/timestamppb"
wrapperspb "google.golang.org/protobuf/types/known/wrapperspb"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
type CreateArtifactRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
WorkflowRunBackendId string `protobuf:"bytes,1,opt,name=workflow_run_backend_id,json=workflowRunBackendId,proto3" json:"workflow_run_backend_id,omitempty"`
WorkflowJobRunBackendId string `protobuf:"bytes,2,opt,name=workflow_job_run_backend_id,json=workflowJobRunBackendId,proto3" json:"workflow_job_run_backend_id,omitempty"`
Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"`
ExpiresAt *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=expires_at,json=expiresAt,proto3" json:"expires_at,omitempty"`
Version int32 `protobuf:"varint,5,opt,name=version,proto3" json:"version,omitempty"`
}
func (x *CreateArtifactRequest) Reset() {
*x = CreateArtifactRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_artifact_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *CreateArtifactRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*CreateArtifactRequest) ProtoMessage() {}
func (x *CreateArtifactRequest) ProtoReflect() protoreflect.Message {
mi := &file_artifact_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use CreateArtifactRequest.ProtoReflect.Descriptor instead.
func (*CreateArtifactRequest) Descriptor() ([]byte, []int) {
return file_artifact_proto_rawDescGZIP(), []int{0}
}
func (x *CreateArtifactRequest) GetWorkflowRunBackendId() string {
if x != nil {
return x.WorkflowRunBackendId
}
return ""
}
func (x *CreateArtifactRequest) GetWorkflowJobRunBackendId() string {
if x != nil {
return x.WorkflowJobRunBackendId
}
return ""
}
func (x *CreateArtifactRequest) GetName() string {
if x != nil {
return x.Name
}
return ""
}
func (x *CreateArtifactRequest) GetExpiresAt() *timestamppb.Timestamp {
if x != nil {
return x.ExpiresAt
}
return nil
}
func (x *CreateArtifactRequest) GetVersion() int32 {
if x != nil {
return x.Version
}
return 0
}
type CreateArtifactResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Ok bool `protobuf:"varint,1,opt,name=ok,proto3" json:"ok,omitempty"`
SignedUploadUrl string `protobuf:"bytes,2,opt,name=signed_upload_url,json=signedUploadUrl,proto3" json:"signed_upload_url,omitempty"`
}
func (x *CreateArtifactResponse) Reset() {
*x = CreateArtifactResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_artifact_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *CreateArtifactResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*CreateArtifactResponse) ProtoMessage() {}
func (x *CreateArtifactResponse) ProtoReflect() protoreflect.Message {
mi := &file_artifact_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use CreateArtifactResponse.ProtoReflect.Descriptor instead.
func (*CreateArtifactResponse) Descriptor() ([]byte, []int) {
return file_artifact_proto_rawDescGZIP(), []int{1}
}
func (x *CreateArtifactResponse) GetOk() bool {
if x != nil {
return x.Ok
}
return false
}
func (x *CreateArtifactResponse) GetSignedUploadUrl() string {
if x != nil {
return x.SignedUploadUrl
}
return ""
}
type FinalizeArtifactRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
WorkflowRunBackendId string `protobuf:"bytes,1,opt,name=workflow_run_backend_id,json=workflowRunBackendId,proto3" json:"workflow_run_backend_id,omitempty"`
WorkflowJobRunBackendId string `protobuf:"bytes,2,opt,name=workflow_job_run_backend_id,json=workflowJobRunBackendId,proto3" json:"workflow_job_run_backend_id,omitempty"`
Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"`
Size int64 `protobuf:"varint,4,opt,name=size,proto3" json:"size,omitempty"`
Hash *wrapperspb.StringValue `protobuf:"bytes,5,opt,name=hash,proto3" json:"hash,omitempty"`
}
func (x *FinalizeArtifactRequest) Reset() {
*x = FinalizeArtifactRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_artifact_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *FinalizeArtifactRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*FinalizeArtifactRequest) ProtoMessage() {}
func (x *FinalizeArtifactRequest) ProtoReflect() protoreflect.Message {
mi := &file_artifact_proto_msgTypes[2]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use FinalizeArtifactRequest.ProtoReflect.Descriptor instead.
func (*FinalizeArtifactRequest) Descriptor() ([]byte, []int) {
return file_artifact_proto_rawDescGZIP(), []int{2}
}
func (x *FinalizeArtifactRequest) GetWorkflowRunBackendId() string {
if x != nil {
return x.WorkflowRunBackendId
}
return ""
}
func (x *FinalizeArtifactRequest) GetWorkflowJobRunBackendId() string {
if x != nil {
return x.WorkflowJobRunBackendId
}
return ""
}
func (x *FinalizeArtifactRequest) GetName() string {
if x != nil {
return x.Name
}
return ""
}
func (x *FinalizeArtifactRequest) GetSize() int64 {
if x != nil {
return x.Size
}
return 0
}
func (x *FinalizeArtifactRequest) GetHash() *wrapperspb.StringValue {
if x != nil {
return x.Hash
}
return nil
}
type FinalizeArtifactResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Ok bool `protobuf:"varint,1,opt,name=ok,proto3" json:"ok,omitempty"`
ArtifactId int64 `protobuf:"varint,2,opt,name=artifact_id,json=artifactId,proto3" json:"artifact_id,omitempty"`
}
func (x *FinalizeArtifactResponse) Reset() {
*x = FinalizeArtifactResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_artifact_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *FinalizeArtifactResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*FinalizeArtifactResponse) ProtoMessage() {}
func (x *FinalizeArtifactResponse) ProtoReflect() protoreflect.Message {
mi := &file_artifact_proto_msgTypes[3]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use FinalizeArtifactResponse.ProtoReflect.Descriptor instead.
func (*FinalizeArtifactResponse) Descriptor() ([]byte, []int) {
return file_artifact_proto_rawDescGZIP(), []int{3}
}
func (x *FinalizeArtifactResponse) GetOk() bool {
if x != nil {
return x.Ok
}
return false
}
func (x *FinalizeArtifactResponse) GetArtifactId() int64 {
if x != nil {
return x.ArtifactId
}
return 0
}
type ListArtifactsRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
WorkflowRunBackendId string `protobuf:"bytes,1,opt,name=workflow_run_backend_id,json=workflowRunBackendId,proto3" json:"workflow_run_backend_id,omitempty"`
WorkflowJobRunBackendId string `protobuf:"bytes,2,opt,name=workflow_job_run_backend_id,json=workflowJobRunBackendId,proto3" json:"workflow_job_run_backend_id,omitempty"`
NameFilter *wrapperspb.StringValue `protobuf:"bytes,3,opt,name=name_filter,json=nameFilter,proto3" json:"name_filter,omitempty"`
IdFilter *wrapperspb.Int64Value `protobuf:"bytes,4,opt,name=id_filter,json=idFilter,proto3" json:"id_filter,omitempty"`
}
func (x *ListArtifactsRequest) Reset() {
*x = ListArtifactsRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_artifact_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ListArtifactsRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ListArtifactsRequest) ProtoMessage() {}
func (x *ListArtifactsRequest) ProtoReflect() protoreflect.Message {
mi := &file_artifact_proto_msgTypes[4]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ListArtifactsRequest.ProtoReflect.Descriptor instead.
func (*ListArtifactsRequest) Descriptor() ([]byte, []int) {
return file_artifact_proto_rawDescGZIP(), []int{4}
}
func (x *ListArtifactsRequest) GetWorkflowRunBackendId() string {
if x != nil {
return x.WorkflowRunBackendId
}
return ""
}
func (x *ListArtifactsRequest) GetWorkflowJobRunBackendId() string {
if x != nil {
return x.WorkflowJobRunBackendId
}
return ""
}
func (x *ListArtifactsRequest) GetNameFilter() *wrapperspb.StringValue {
if x != nil {
return x.NameFilter
}
return nil
}
func (x *ListArtifactsRequest) GetIdFilter() *wrapperspb.Int64Value {
if x != nil {
return x.IdFilter
}
return nil
}
type ListArtifactsResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Artifacts []*ListArtifactsResponse_MonolithArtifact `protobuf:"bytes,1,rep,name=artifacts,proto3" json:"artifacts,omitempty"`
}
func (x *ListArtifactsResponse) Reset() {
*x = ListArtifactsResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_artifact_proto_msgTypes[5]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ListArtifactsResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ListArtifactsResponse) ProtoMessage() {}
func (x *ListArtifactsResponse) ProtoReflect() protoreflect.Message {
mi := &file_artifact_proto_msgTypes[5]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ListArtifactsResponse.ProtoReflect.Descriptor instead.
func (*ListArtifactsResponse) Descriptor() ([]byte, []int) {
return file_artifact_proto_rawDescGZIP(), []int{5}
}
func (x *ListArtifactsResponse) GetArtifacts() []*ListArtifactsResponse_MonolithArtifact {
if x != nil {
return x.Artifacts
}
return nil
}
type ListArtifactsResponse_MonolithArtifact struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
WorkflowRunBackendId string `protobuf:"bytes,1,opt,name=workflow_run_backend_id,json=workflowRunBackendId,proto3" json:"workflow_run_backend_id,omitempty"`
WorkflowJobRunBackendId string `protobuf:"bytes,2,opt,name=workflow_job_run_backend_id,json=workflowJobRunBackendId,proto3" json:"workflow_job_run_backend_id,omitempty"`
DatabaseId int64 `protobuf:"varint,3,opt,name=database_id,json=databaseId,proto3" json:"database_id,omitempty"`
Name string `protobuf:"bytes,4,opt,name=name,proto3" json:"name,omitempty"`
Size int64 `protobuf:"varint,5,opt,name=size,proto3" json:"size,omitempty"`
CreatedAt *timestamppb.Timestamp `protobuf:"bytes,6,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"`
}
func (x *ListArtifactsResponse_MonolithArtifact) Reset() {
*x = ListArtifactsResponse_MonolithArtifact{}
if protoimpl.UnsafeEnabled {
mi := &file_artifact_proto_msgTypes[6]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ListArtifactsResponse_MonolithArtifact) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ListArtifactsResponse_MonolithArtifact) ProtoMessage() {}
func (x *ListArtifactsResponse_MonolithArtifact) ProtoReflect() protoreflect.Message {
mi := &file_artifact_proto_msgTypes[6]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ListArtifactsResponse_MonolithArtifact.ProtoReflect.Descriptor instead.
func (*ListArtifactsResponse_MonolithArtifact) Descriptor() ([]byte, []int) {
return file_artifact_proto_rawDescGZIP(), []int{6}
}
func (x *ListArtifactsResponse_MonolithArtifact) GetWorkflowRunBackendId() string {
if x != nil {
return x.WorkflowRunBackendId
}
return ""
}
func (x *ListArtifactsResponse_MonolithArtifact) GetWorkflowJobRunBackendId() string {
if x != nil {
return x.WorkflowJobRunBackendId
}
return ""
}
func (x *ListArtifactsResponse_MonolithArtifact) GetDatabaseId() int64 {
if x != nil {
return x.DatabaseId
}
return 0
}
func (x *ListArtifactsResponse_MonolithArtifact) GetName() string {
if x != nil {
return x.Name
}
return ""
}
func (x *ListArtifactsResponse_MonolithArtifact) GetSize() int64 {
if x != nil {
return x.Size
}
return 0
}
func (x *ListArtifactsResponse_MonolithArtifact) GetCreatedAt() *timestamppb.Timestamp {
if x != nil {
return x.CreatedAt
}
return nil
}
type GetSignedArtifactURLRequest struct {
state protoimpl.MessageState
sizeCache
gitextract_bc5cehu6/
├── .actrc
├── .codespellrc
├── .editorconfig
├── .github/
│ ├── FUNDING.yml
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug_report.yml
│ │ ├── config.yml
│ │ ├── feature_template.yml
│ │ └── wiki_issue.yml
│ ├── actions/
│ │ └── choco/
│ │ ├── Dockerfile
│ │ ├── action.yml
│ │ └── entrypoint.sh
│ ├── dependabot.yml
│ └── workflows/
│ ├── .gitignore
│ ├── checks.yml
│ ├── codespell.yml
│ ├── promote.yml
│ ├── release.yml
│ └── stale.yml
├── .gitignore
├── .gitleaksignore
├── .golangci.yml
├── .goreleaser.yml
├── .markdownlint.yml
├── .mega-linter.yml
├── .mergify.yml
├── .prettierignore
├── .prettierrc.yml
├── CONTRIBUTING.md
├── IMAGES.md
├── LICENSE
├── Makefile
├── README.md
├── VERIFICATION
├── VERSION
├── act-cli.nuspec
├── cmd/
│ ├── dir.go
│ ├── execute_test.go
│ ├── graph.go
│ ├── input.go
│ ├── list.go
│ ├── notices.go
│ ├── platforms.go
│ ├── root.go
│ ├── root_test.go
│ ├── secrets.go
│ └── testdata/
│ ├── env.actrc
│ ├── secrets.yml
│ ├── simple.actrc
│ └── split.actrc
├── codecov.yml
├── go.mod
├── go.sum
├── install.sh
├── main.go
├── main_test.go
└── pkg/
├── artifactcache/
│ ├── doc.go
│ ├── handler.go
│ ├── handler_test.go
│ ├── model.go
│ ├── storage.go
│ └── testdata/
│ └── example/
│ └── example.yaml
├── artifacts/
│ ├── artifact.pb.go
│ ├── artifacts_v4.go
│ ├── server.go
│ ├── server_test.go
│ └── testdata/
│ ├── GHSL-2023-004/
│ │ └── artifacts.yml
│ ├── upload-and-download/
│ │ └── artifacts.yml
│ └── v4/
│ └── artifacts.yml
├── common/
│ ├── auth.go
│ ├── auth_test.go
│ ├── cartesian.go
│ ├── cartesian_test.go
│ ├── context.go
│ ├── context_test.go
│ ├── draw.go
│ ├── dryrun.go
│ ├── executor.go
│ ├── executor_test.go
│ ├── file.go
│ ├── git/
│ │ ├── git.go
│ │ └── git_test.go
│ ├── job_error.go
│ ├── line_writer.go
│ ├── line_writer_test.go
│ ├── logger.go
│ └── outbound_ip.go
├── container/
│ ├── DOCKER_LICENSE
│ ├── container_types.go
│ ├── docker_auth.go
│ ├── docker_build.go
│ ├── docker_cli.go
│ ├── docker_cli_test.go
│ ├── docker_images.go
│ ├── docker_images_test.go
│ ├── docker_logger.go
│ ├── docker_network.go
│ ├── docker_pull.go
│ ├── docker_pull_test.go
│ ├── docker_run.go
│ ├── docker_run_test.go
│ ├── docker_socket.go
│ ├── docker_socket_test.go
│ ├── docker_stub.go
│ ├── docker_volume.go
│ ├── executions_environment.go
│ ├── host_environment.go
│ ├── host_environment_test.go
│ ├── linux_container_environment_extensions.go
│ ├── linux_container_environment_extensions_test.go
│ ├── parse_env_file.go
│ ├── testdata/
│ │ ├── Dockerfile
│ │ ├── docker-pull-options/
│ │ │ └── config.json
│ │ ├── scratch/
│ │ │ └── test.txt
│ │ ├── utf16.env
│ │ ├── utf16be.env
│ │ ├── utf8.env
│ │ ├── valid.env
│ │ └── valid.label
│ ├── util.go
│ ├── util_openbsd_mips64.go
│ ├── util_plan9.go
│ └── util_windows.go
├── exprparser/
│ ├── functions.go
│ ├── functions_test.go
│ ├── interpreter.go
│ ├── interpreter_test.go
│ └── testdata/
│ ├── for-hashing-1.txt
│ ├── for-hashing-2.txt
│ └── for-hashing-3/
│ ├── data.txt
│ └── nested/
│ └── nested-data.txt
├── filecollector/
│ ├── file_collector.go
│ └── file_collector_test.go
├── gh/
│ ├── gh.go
│ └── gh_test.go
├── lookpath/
│ ├── LICENSE
│ ├── env.go
│ ├── error.go
│ ├── lp_js.go
│ ├── lp_plan9.go
│ ├── lp_unix.go
│ └── lp_windows.go
├── model/
│ ├── action.go
│ ├── anchors.go
│ ├── anchors_test.go
│ ├── github_context.go
│ ├── github_context_test.go
│ ├── job_context.go
│ ├── planner.go
│ ├── planner_test.go
│ ├── step_result.go
│ ├── testdata/
│ │ ├── container-volumes/
│ │ │ └── push.yml
│ │ ├── empty-workflow/
│ │ │ └── push.yml
│ │ ├── invalid-job-name/
│ │ │ ├── invalid-1.yml
│ │ │ ├── invalid-2.yml
│ │ │ ├── valid-1.yml
│ │ │ └── valid-2.yml
│ │ ├── nested/
│ │ │ ├── success.yml
│ │ │ └── workflows/
│ │ │ └── fail.yml
│ │ └── strategy/
│ │ └── push.yml
│ ├── workflow.go
│ └── workflow_test.go
├── runner/
│ ├── action.go
│ ├── action_cache.go
│ ├── action_cache_offline_mode.go
│ ├── action_cache_test.go
│ ├── action_composite.go
│ ├── action_test.go
│ ├── command.go
│ ├── command_test.go
│ ├── container_mock_test.go
│ ├── expression.go
│ ├── expression_test.go
│ ├── hashfiles/
│ │ └── index.js
│ ├── job_executor.go
│ ├── job_executor_test.go
│ ├── local_repository_cache.go
│ ├── logger.go
│ ├── res/
│ │ └── trampoline.js
│ ├── reusable_workflow.go
│ ├── run_context.go
│ ├── run_context_test.go
│ ├── runner.go
│ ├── runner_test.go
│ ├── step.go
│ ├── step_action_local.go
│ ├── step_action_local_test.go
│ ├── step_action_remote.go
│ ├── step_action_remote_test.go
│ ├── step_docker.go
│ ├── step_docker_test.go
│ ├── step_factory.go
│ ├── step_factory_test.go
│ ├── step_run.go
│ ├── step_run_test.go
│ ├── step_test.go
│ └── testdata/
│ ├── .github/
│ │ └── workflows/
│ │ ├── local-reusable-and-dispatch.yml
│ │ ├── local-reusable-workflow-no-inputs-array.yml
│ │ ├── local-reusable-workflow-no-inputs-string.yml
│ │ └── local-reusable-workflow.yml
│ ├── GITHUB_ENV-use-in-env-ctx/
│ │ └── push.yml
│ ├── GITHUB_STATE/
│ │ └── push.yml
│ ├── act-composite-env-test/
│ │ ├── action1/
│ │ │ └── action.yml
│ │ ├── action2/
│ │ │ └── action.yml
│ │ └── push.yml
│ ├── action-cache-v2-fetch-failure-is-job-error/
│ │ └── push.yml
│ ├── actions/
│ │ ├── action1/
│ │ │ ├── Dockerfile
│ │ │ └── action.yml
│ │ ├── composite-fail-with-output/
│ │ │ └── action.yml
│ │ ├── docker-local/
│ │ │ ├── Dockerfile
│ │ │ ├── action.yml
│ │ │ └── entrypoint.sh
│ │ ├── docker-local-noargs/
│ │ │ ├── Dockerfile
│ │ │ ├── action.yml
│ │ │ └── entrypoint.sh
│ │ ├── docker-url/
│ │ │ └── action.yml
│ │ ├── node12/
│ │ │ ├── README.md
│ │ │ ├── action.yml
│ │ │ ├── dist/
│ │ │ │ └── index.js
│ │ │ ├── index.js
│ │ │ └── package.json
│ │ ├── node16/
│ │ │ ├── README.md
│ │ │ ├── action.yml
│ │ │ ├── dist/
│ │ │ │ └── index.js
│ │ │ ├── index.js
│ │ │ └── package.json
│ │ └── node20/
│ │ ├── README.md
│ │ ├── action.yml
│ │ ├── dist/
│ │ │ └── index.js
│ │ ├── index.js
│ │ └── package.json
│ ├── actions-environment-and-context-tests/
│ │ ├── docker/
│ │ │ ├── Dockerfile
│ │ │ ├── action.yml
│ │ │ └── entrypoint.sh
│ │ ├── js/
│ │ │ ├── action.yml
│ │ │ └── index.js
│ │ └── push.yml
│ ├── basic/
│ │ └── push.yml
│ ├── checkout/
│ │ └── push.yml
│ ├── commands/
│ │ └── push.yml
│ ├── composite-fail-with-output/
│ │ └── push.yml
│ ├── container-hostname/
│ │ └── push.yml
│ ├── defaults-run/
│ │ └── main.yaml
│ ├── dir with spaces/
│ │ └── push.yml
│ ├── do-not-leak-step-env-in-composite/
│ │ └── push.yml
│ ├── docker-action-custom-path/
│ │ └── push.yml
│ ├── docker-action-host-env/
│ │ ├── action/
│ │ │ ├── Dockerfile
│ │ │ ├── action.yml
│ │ │ └── entrypoint.sh
│ │ └── push.yml
│ ├── ensure-post-steps/
│ │ ├── action-composite/
│ │ │ └── action.yml
│ │ ├── action-post/
│ │ │ ├── action.yml
│ │ │ ├── main.js
│ │ │ └── post.js
│ │ └── push.yml
│ ├── env-and-path/
│ │ └── push.yaml
│ ├── environment-files/
│ │ └── push.yaml
│ ├── environment-files-parser-bug/
│ │ └── push.yaml
│ ├── environment-variables/
│ │ └── push.yml
│ ├── evalenv/
│ │ └── push.yml
│ ├── evalmatrix/
│ │ └── push.yml
│ ├── evalmatrix-merge-array/
│ │ └── push.yml
│ ├── evalmatrix-merge-map/
│ │ └── push.yml
│ ├── evalmatrixneeds/
│ │ └── push.yml
│ ├── evalmatrixneeds2/
│ │ └── push.yml
│ ├── fail/
│ │ └── push.yml
│ ├── if-env-act/
│ │ └── push.yml
│ ├── if-expressions/
│ │ └── push.yml
│ ├── input-from-cli/
│ │ └── input.yml
│ ├── inputs-via-env-context/
│ │ ├── action/
│ │ │ └── action.yml
│ │ └── push.yml
│ ├── issue-104/
│ │ └── main.yaml
│ ├── issue-1195/
│ │ └── push.yml
│ ├── issue-122/
│ │ └── main.yaml
│ ├── issue-141/
│ │ └── main.yaml
│ ├── issue-1595/
│ │ ├── missing.yml
│ │ ├── no-event.yml
│ │ └── no-first.yml
│ ├── issue-597/
│ │ └── spelling.yaml
│ ├── issue-598/
│ │ └── spelling.yml
│ ├── job-container/
│ │ └── push.yml
│ ├── job-container-invalid-credentials/
│ │ └── push.yml
│ ├── job-container-non-root/
│ │ └── push.yml
│ ├── job-needs-context-contains-result/
│ │ └── push.yml
│ ├── job-nil-step/
│ │ └── push.yml
│ ├── job-status-check/
│ │ └── push.yml
│ ├── local-action-docker-url/
│ │ └── push.yml
│ ├── local-action-dockerfile/
│ │ └── push.yml
│ ├── local-action-js/
│ │ └── push.yml
│ ├── local-action-via-composite-dockerfile/
│ │ ├── action/
│ │ │ └── action.yml
│ │ └── push.yml
│ ├── local-remote-action-overrides/
│ │ ├── config/
│ │ │ └── config.yml
│ │ └── push.yml
│ ├── localdockerimagetest_/
│ │ └── Dockerfile
│ ├── mask-values/
│ │ ├── composite/
│ │ │ └── action.yml
│ │ └── push.yml
│ ├── matrix/
│ │ └── push.yml
│ ├── matrix-exitcode/
│ │ └── push.yml
│ ├── matrix-include-exclude/
│ │ └── push.yml
│ ├── matrix-with-user-inclusions/
│ │ └── push.yml
│ ├── mysql-service-container-with-health-check/
│ │ └── push.yml
│ ├── networking/
│ │ └── push.yml
│ ├── nix-prepend-path/
│ │ └── push.yml
│ ├── no-panic-on-invalid-composite-action/
│ │ └── push.yml
│ ├── node/
│ │ └── push.yml
│ ├── non-existent-action/
│ │ └── push.yml
│ ├── outputs/
│ │ └── push.yml
│ ├── parallel/
│ │ └── push.yml
│ ├── path-handling/
│ │ ├── action/
│ │ │ └── action.yml
│ │ └── push.yml
│ ├── post-step-failure-is-job-failure/
│ │ ├── post-step-failure/
│ │ │ ├── action.yml
│ │ │ ├── main.js
│ │ │ └── post.js
│ │ └── push.yml
│ ├── pull-request/
│ │ ├── event.json
│ │ └── main.yaml
│ ├── python/
│ │ └── main.yml
│ ├── remote-action-composite-action-ref/
│ │ └── push.yml
│ ├── remote-action-composite-js-pre-with-defaults/
│ │ └── push.yml
│ ├── remote-action-docker/
│ │ └── push.yml
│ ├── remote-action-docker-new-cache/
│ │ ├── config/
│ │ │ └── config.yml
│ │ └── push.yml
│ ├── remote-action-js/
│ │ └── push.yml
│ ├── remote-action-js-node-user/
│ │ └── push.yml
│ ├── runs-on/
│ │ └── push.yml
│ ├── secrets/
│ │ ├── .actrc
│ │ └── push.yml
│ ├── services/
│ │ └── push.yaml
│ ├── services-empty-image/
│ │ └── push.yaml
│ ├── services-host-network/
│ │ └── push.yml
│ ├── services-with-container/
│ │ └── push.yml
│ ├── set-env-new-env-file-per-step/
│ │ └── push.yml
│ ├── set-env-step-env-override/
│ │ └── push.yml
│ ├── shells/
│ │ ├── bash/
│ │ │ └── push.yml
│ │ ├── custom/
│ │ │ └── push.yml
│ │ ├── defaults/
│ │ │ └── push.yml
│ │ ├── pwsh/
│ │ │ └── push.yml
│ │ ├── python/
│ │ │ └── push.yml
│ │ └── sh/
│ │ └── push.yml
│ ├── steps-context/
│ │ ├── conclusion/
│ │ │ └── push.yml
│ │ └── outcome/
│ │ └── push.yml
│ ├── stepsummary/
│ │ └── push.yml
│ ├── uses-action-with-pre-and-post-step/
│ │ ├── last-action/
│ │ │ ├── action.yml
│ │ │ ├── main.js
│ │ │ └── post.js
│ │ └── push.yml
│ ├── uses-and-run-in-one-step/
│ │ └── push.yml
│ ├── uses-composite/
│ │ ├── composite_action/
│ │ │ └── action.yml
│ │ └── push.yml
│ ├── uses-composite-check-for-input-collision/
│ │ ├── action-with-pre-and-post/
│ │ │ ├── action.yml
│ │ │ ├── main.js
│ │ │ ├── post.js
│ │ │ └── pre.js
│ │ ├── composite_action/
│ │ │ └── action.yml
│ │ └── push.yml
│ ├── uses-composite-check-for-input-in-if-uses/
│ │ ├── composite_action/
│ │ │ └── action.yml
│ │ └── push.yml
│ ├── uses-composite-check-for-input-shadowing/
│ │ ├── action-with-pre-and-post/
│ │ │ ├── action.yml
│ │ │ ├── main.js
│ │ │ ├── post.js
│ │ │ └── pre.js
│ │ ├── composite_action/
│ │ │ └── action.yml
│ │ └── push.yml
│ ├── uses-composite-with-error/
│ │ ├── composite_action2/
│ │ │ └── action.yml
│ │ └── push.yml
│ ├── uses-composite-with-inputs/
│ │ ├── action/
│ │ │ └── action.yml
│ │ ├── composite/
│ │ │ └── action.yml
│ │ └── push.yml
│ ├── uses-composite-with-pre-and-post-steps/
│ │ ├── action-with-pre-and-post/
│ │ │ ├── action.yml
│ │ │ ├── main.js
│ │ │ ├── post.js
│ │ │ └── pre.js
│ │ ├── composite_action/
│ │ │ └── action.yml
│ │ ├── last-action/
│ │ │ ├── action.yml
│ │ │ ├── main.js
│ │ │ └── post.js
│ │ └── push.yml
│ ├── uses-docker-url/
│ │ └── push.yml
│ ├── uses-github-empty/
│ │ └── push.yml
│ ├── uses-github-full-sha/
│ │ └── main.yml
│ ├── uses-github-noref/
│ │ └── push.yml
│ ├── uses-github-path/
│ │ └── push.yml
│ ├── uses-github-root/
│ │ └── push.yml
│ ├── uses-github-short-sha/
│ │ └── main.yml
│ ├── uses-nested-composite/
│ │ ├── composite_action2/
│ │ │ └── action.yml
│ │ └── push.yml
│ ├── uses-workflow/
│ │ ├── local-workflow.yml
│ │ └── push.yml
│ ├── uses-workflow-defaults/
│ │ └── workflow_dispatch.yml
│ ├── windows-add-env/
│ │ ├── action/
│ │ │ └── action.yml
│ │ └── push.yml
│ ├── windows-add-env-powershell-5/
│ │ ├── action/
│ │ │ └── action.yml
│ │ └── push.yml
│ ├── windows-prepend-path/
│ │ └── push.yml
│ ├── windows-prepend-path-powershell-5/
│ │ └── push.yml
│ ├── windows-shell-cmd/
│ │ └── push.yml
│ ├── workdir/
│ │ ├── canary
│ │ └── push.yml
│ ├── workflow_call_inputs/
│ │ ├── event.json
│ │ └── workflow_call_inputs.yml
│ ├── workflow_dispatch/
│ │ ├── event.json
│ │ └── workflow_dispatch.yml
│ ├── workflow_dispatch-scalar/
│ │ └── workflow_dispatch.yml
│ ├── workflow_dispatch-scalar-composite-action/
│ │ └── workflow_dispatch.yml
│ └── workflow_dispatch_no_inputs_mapping/
│ └── workflow_dispatch.yml
├── schema/
│ ├── action_schema.json
│ ├── schema.go
│ ├── schema_test.go
│ └── workflow_schema.json
└── workflowpattern/
├── trace_writer.go
├── workflow_pattern.go
└── workflow_pattern_test.go
Showing preview only (201K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (2450 symbols across 132 files)
FILE: cmd/dir.go
function init (line 15) | func init() {
FILE: cmd/execute_test.go
function testMain (line 10) | func testMain(args []string) (exitCode int) {
function TestMainHelp (line 33) | func TestMainHelp(t *testing.T) {
function TestMainNoArgsError (line 40) | func TestMainNoArgsError(t *testing.T) {
FILE: cmd/graph.go
function drawGraph (line 10) | func drawGraph(plan *model.Plan) error {
FILE: cmd/input.go
type Input (line 10) | type Input struct
method resolve (line 70) | func (i *Input) resolve(path string) string {
method Envfile (line 85) | func (i *Input) Envfile() string {
method Secretfile (line 90) | func (i *Input) Secretfile() string {
method Varfile (line 94) | func (i *Input) Varfile() string {
method Workdir (line 99) | func (i *Input) Workdir() string {
method WorkflowsPath (line 104) | func (i *Input) WorkflowsPath() string {
method EventPath (line 109) | func (i *Input) EventPath() string {
method Inputfile (line 114) | func (i *Input) Inputfile() string {
FILE: cmd/list.go
function printList (line 11) | func printList(plan *model.Plan) error {
FILE: cmd/notices.go
type Notice (line 17) | type Notice struct
function displayNotices (line 22) | func displayNotices(input *Input) {
function loadVersionNotices (line 57) | func loadVersionNotices(version string) {
constant NoticeURL (line 63) | NoticeURL = "https://api.nektosact.com/notices"
function getVersionNotices (line 65) | func getVersionNotices(version string) []Notice {
function loadNoticesEtag (line 121) | func loadNoticesEtag() string {
function saveNoticesEtag (line 130) | func saveNoticesEtag(etag string) {
function etagPath (line 138) | func etagPath() string {
FILE: cmd/platforms.go
method newPlatforms (line 7) | func (i *Input) newPlatforms() map[string]string {
FILE: cmd/root.go
type Flag (line 37) | type Flag struct
function Execute (line 47) | func Execute(ctx context.Context, version string) {
function createRootCommand (line 56) | func createRootCommand(ctx context.Context, input *Input, version string...
function configLocations (line 138) | func configLocations() []string {
function args (line 155) | func args() []string {
function bugReport (line 167) | func bugReport(ctx context.Context, version string) error {
function generateManPage (line 256) | func generateManPage(cmd *cobra.Command) error {
function listOptions (line 268) | func listOptions(cmd *cobra.Command) error {
function readArgsFile (line 278) | func readArgsFile(file string, split bool) []string {
function setup (line 304) | func setup(_ *Input) func(*cobra.Command, []string) {
function cleanup (line 314) | func cleanup(inputs *Input) func(*cobra.Command, []string) {
function parseEnvs (line 320) | func parseEnvs(env []string) map[string]string {
function readYamlFile (line 333) | func readYamlFile(file string) (map[string]string, error) {
function readEnvs (line 345) | func readEnvs(path string, envs map[string]string) bool {
function readEnvsEx (line 349) | func readEnvsEx(path string, envs map[string]string, caseInsensitive boo...
function parseMatrix (line 373) | func parseMatrix(matrix []string) map[string]map[string]bool {
function newRunCommand (line 391) | func newRunCommand(ctx context.Context, input *Input) func(*cobra.Comman...
function defaultImageSurvey (line 716) | func defaultImageSurvey(actrc string) error {
function watchAndRun (line 759) | func watchAndRun(ctx context.Context, fn common.Executor) error {
FILE: cmd/root_test.go
function TestReadSecrets (line 11) | func TestReadSecrets(t *testing.T) {
function TestReadEnv (line 21) | func TestReadEnv(t *testing.T) {
function TestListOptions (line 31) | func TestListOptions(t *testing.T) {
function TestRun (line 39) | func TestRun(t *testing.T) {
function TestRunPush (line 49) | func TestRunPush(t *testing.T) {
function TestRunPushJsonLogger (line 59) | func TestRunPushJsonLogger(t *testing.T) {
function TestFlags (line 70) | func TestFlags(t *testing.T) {
function TestReadArgsFile (line 86) | func TestReadArgsFile(t *testing.T) {
FILE: cmd/secrets.go
type secrets (line 12) | type secrets
method AsMap (line 40) | func (s secrets) AsMap() map[string]string {
function newSecrets (line 14) | func newSecrets(secretList []string) secrets {
FILE: main.go
function main (line 13) | func main() {
FILE: main_test.go
function TestMain (line 8) | func TestMain(_ *testing.T) {
FILE: pkg/artifactcache/handler.go
constant urlBase (line 27) | urlBase = "/_apis/artifactcache"
type Handler (line 30) | type Handler struct
method GetActualPort (line 119) | func (h *Handler) GetActualPort() int {
method ExternalURL (line 123) | func (h *Handler) ExternalURL() string {
method Close (line 130) | func (h *Handler) Close() error {
method openDB (line 155) | func (h *Handler) openDB() (*bolthold.Store, error) {
method find (line 168) | func (h *Handler) find(w http.ResponseWriter, r *http.Request, _ httpr...
method reserve (line 209) | func (h *Handler) reserve(w http.ResponseWriter, r *http.Request, _ ht...
method upload (line 239) | func (h *Handler) upload(w http.ResponseWriter, r *http.Request, param...
method commit (line 280) | func (h *Handler) commit(w http.ResponseWriter, r *http.Request, param...
method get (line 335) | func (h *Handler) get(w http.ResponseWriter, r *http.Request, params h...
method clean (line 346) | func (h *Handler) clean(w http.ResponseWriter, r *http.Request, _ http...
method middleware (line 353) | func (h *Handler) middleware(handler httprouter.Handle) httprouter.Han...
method useCache (line 407) | func (h *Handler) useCache(id uint64) {
method gcCache (line 428) | func (h *Handler) gcCache() {
method responseJSON (line 535) | func (h *Handler) responseJSON(w http.ResponseWriter, r *http.Request,...
function StartHandler (line 45) | func StartHandler(dir, customExternalURL string, outboundIP string, port...
function findCache (line 362) | func findCache(db *bolthold.Store, keys []string, version string) (*Cach...
function insertCache (line 396) | func insertCache(db *bolthold.Store, cache *Cache) error {
constant keepUsed (line 422) | keepUsed = 30 * 24 * time.Hour
constant keepUnused (line 423) | keepUnused = 7 * 24 * time.Hour
constant keepTemp (line 424) | keepTemp = 5 * time.Minute
constant keepOld (line 425) | keepOld = 5 * time.Minute
function parseContentRange (line 552) | func parseContentRange(s string) (int64, int64, error) {
FILE: pkg/artifactcache/handler_test.go
function TestHandler (line 21) | func TestHandler(t *testing.T) {
function uploadCacheNormally (line 531) | func uploadCacheNormally(t *testing.T, base, key, version string, conten...
function TestHandler_CustomExternalURL (line 590) | func TestHandler_CustomExternalURL(t *testing.T) {
function TestHandler_gcCache (line 624) | func TestHandler_gcCache(t *testing.T) {
FILE: pkg/artifactcache/model.go
type Request (line 3) | type Request struct
method ToCache (line 9) | func (c *Request) ToCache() *Cache {
type Cache (line 26) | type Cache struct
FILE: pkg/artifactcache/storage.go
type Storage (line 11) | type Storage struct
method Exist (line 24) | func (s *Storage) Exist(id uint64) (bool, error) {
method Write (line 34) | func (s *Storage) Write(id uint64, offset int64, reader io.Reader) err...
method Commit (line 49) | func (s *Storage) Commit(id uint64, size int64) (int64, error) {
method Serve (line 95) | func (s *Storage) Serve(w http.ResponseWriter, r *http.Request, id uin...
method Remove (line 100) | func (s *Storage) Remove(id uint64) {
method filename (line 105) | func (s *Storage) filename(id uint64) string {
method tempDir (line 109) | func (s *Storage) tempDir(id uint64) string {
method tempName (line 113) | func (s *Storage) tempName(id uint64, offset int64) string {
method tempNames (line 117) | func (s *Storage) tempNames(id uint64) ([]string, error) {
function NewStorage (line 15) | func NewStorage(rootDir string) (*Storage, error) {
FILE: pkg/artifacts/artifact.pb.go
constant _ (line 24) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
constant _ (line 26) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
type CreateArtifactRequest (line 29) | type CreateArtifactRequest struct
method Reset (line 41) | func (x *CreateArtifactRequest) Reset() {
method String (line 50) | func (x *CreateArtifactRequest) String() string {
method ProtoMessage (line 54) | func (*CreateArtifactRequest) ProtoMessage() {}
method ProtoReflect (line 56) | func (x *CreateArtifactRequest) ProtoReflect() protoreflect.Message {
method Descriptor (line 69) | func (*CreateArtifactRequest) Descriptor() ([]byte, []int) {
method GetWorkflowRunBackendId (line 73) | func (x *CreateArtifactRequest) GetWorkflowRunBackendId() string {
method GetWorkflowJobRunBackendId (line 80) | func (x *CreateArtifactRequest) GetWorkflowJobRunBackendId() string {
method GetName (line 87) | func (x *CreateArtifactRequest) GetName() string {
method GetExpiresAt (line 94) | func (x *CreateArtifactRequest) GetExpiresAt() *timestamppb.Timestamp {
method GetVersion (line 101) | func (x *CreateArtifactRequest) GetVersion() int32 {
type CreateArtifactResponse (line 108) | type CreateArtifactResponse struct
method Reset (line 117) | func (x *CreateArtifactResponse) Reset() {
method String (line 126) | func (x *CreateArtifactResponse) String() string {
method ProtoMessage (line 130) | func (*CreateArtifactResponse) ProtoMessage() {}
method ProtoReflect (line 132) | func (x *CreateArtifactResponse) ProtoReflect() protoreflect.Message {
method Descriptor (line 145) | func (*CreateArtifactResponse) Descriptor() ([]byte, []int) {
method GetOk (line 149) | func (x *CreateArtifactResponse) GetOk() bool {
method GetSignedUploadUrl (line 156) | func (x *CreateArtifactResponse) GetSignedUploadUrl() string {
type FinalizeArtifactRequest (line 163) | type FinalizeArtifactRequest struct
method Reset (line 175) | func (x *FinalizeArtifactRequest) Reset() {
method String (line 184) | func (x *FinalizeArtifactRequest) String() string {
method ProtoMessage (line 188) | func (*FinalizeArtifactRequest) ProtoMessage() {}
method ProtoReflect (line 190) | func (x *FinalizeArtifactRequest) ProtoReflect() protoreflect.Message {
method Descriptor (line 203) | func (*FinalizeArtifactRequest) Descriptor() ([]byte, []int) {
method GetWorkflowRunBackendId (line 207) | func (x *FinalizeArtifactRequest) GetWorkflowRunBackendId() string {
method GetWorkflowJobRunBackendId (line 214) | func (x *FinalizeArtifactRequest) GetWorkflowJobRunBackendId() string {
method GetName (line 221) | func (x *FinalizeArtifactRequest) GetName() string {
method GetSize (line 228) | func (x *FinalizeArtifactRequest) GetSize() int64 {
method GetHash (line 235) | func (x *FinalizeArtifactRequest) GetHash() *wrapperspb.StringValue {
type FinalizeArtifactResponse (line 242) | type FinalizeArtifactResponse struct
method Reset (line 251) | func (x *FinalizeArtifactResponse) Reset() {
method String (line 260) | func (x *FinalizeArtifactResponse) String() string {
method ProtoMessage (line 264) | func (*FinalizeArtifactResponse) ProtoMessage() {}
method ProtoReflect (line 266) | func (x *FinalizeArtifactResponse) ProtoReflect() protoreflect.Message {
method Descriptor (line 279) | func (*FinalizeArtifactResponse) Descriptor() ([]byte, []int) {
method GetOk (line 283) | func (x *FinalizeArtifactResponse) GetOk() bool {
method GetArtifactId (line 290) | func (x *FinalizeArtifactResponse) GetArtifactId() int64 {
type ListArtifactsRequest (line 297) | type ListArtifactsRequest struct
method Reset (line 308) | func (x *ListArtifactsRequest) Reset() {
method String (line 317) | func (x *ListArtifactsRequest) String() string {
method ProtoMessage (line 321) | func (*ListArtifactsRequest) ProtoMessage() {}
method ProtoReflect (line 323) | func (x *ListArtifactsRequest) ProtoReflect() protoreflect.Message {
method Descriptor (line 336) | func (*ListArtifactsRequest) Descriptor() ([]byte, []int) {
method GetWorkflowRunBackendId (line 340) | func (x *ListArtifactsRequest) GetWorkflowRunBackendId() string {
method GetWorkflowJobRunBackendId (line 347) | func (x *ListArtifactsRequest) GetWorkflowJobRunBackendId() string {
method GetNameFilter (line 354) | func (x *ListArtifactsRequest) GetNameFilter() *wrapperspb.StringValue {
method GetIdFilter (line 361) | func (x *ListArtifactsRequest) GetIdFilter() *wrapperspb.Int64Value {
type ListArtifactsResponse (line 368) | type ListArtifactsResponse struct
method Reset (line 376) | func (x *ListArtifactsResponse) Reset() {
method String (line 385) | func (x *ListArtifactsResponse) String() string {
method ProtoMessage (line 389) | func (*ListArtifactsResponse) ProtoMessage() {}
method ProtoReflect (line 391) | func (x *ListArtifactsResponse) ProtoReflect() protoreflect.Message {
method Descriptor (line 404) | func (*ListArtifactsResponse) Descriptor() ([]byte, []int) {
method GetArtifacts (line 408) | func (x *ListArtifactsResponse) GetArtifacts() []*ListArtifactsRespons...
type ListArtifactsResponse_MonolithArtifact (line 415) | type ListArtifactsResponse_MonolithArtifact struct
method Reset (line 428) | func (x *ListArtifactsResponse_MonolithArtifact) Reset() {
method String (line 437) | func (x *ListArtifactsResponse_MonolithArtifact) String() string {
method ProtoMessage (line 441) | func (*ListArtifactsResponse_MonolithArtifact) ProtoMessage() {}
method ProtoReflect (line 443) | func (x *ListArtifactsResponse_MonolithArtifact) ProtoReflect() protor...
method Descriptor (line 456) | func (*ListArtifactsResponse_MonolithArtifact) Descriptor() ([]byte, [...
method GetWorkflowRunBackendId (line 460) | func (x *ListArtifactsResponse_MonolithArtifact) GetWorkflowRunBackend...
method GetWorkflowJobRunBackendId (line 467) | func (x *ListArtifactsResponse_MonolithArtifact) GetWorkflowJobRunBack...
method GetDatabaseId (line 474) | func (x *ListArtifactsResponse_MonolithArtifact) GetDatabaseId() int64 {
method GetName (line 481) | func (x *ListArtifactsResponse_MonolithArtifact) GetName() string {
method GetSize (line 488) | func (x *ListArtifactsResponse_MonolithArtifact) GetSize() int64 {
method GetCreatedAt (line 495) | func (x *ListArtifactsResponse_MonolithArtifact) GetCreatedAt() *times...
type GetSignedArtifactURLRequest (line 502) | type GetSignedArtifactURLRequest struct
method Reset (line 512) | func (x *GetSignedArtifactURLRequest) Reset() {
method String (line 521) | func (x *GetSignedArtifactURLRequest) String() string {
method ProtoMessage (line 525) | func (*GetSignedArtifactURLRequest) ProtoMessage() {}
method ProtoReflect (line 527) | func (x *GetSignedArtifactURLRequest) ProtoReflect() protoreflect.Mess...
method Descriptor (line 540) | func (*GetSignedArtifactURLRequest) Descriptor() ([]byte, []int) {
method GetWorkflowRunBackendId (line 544) | func (x *GetSignedArtifactURLRequest) GetWorkflowRunBackendId() string {
method GetWorkflowJobRunBackendId (line 551) | func (x *GetSignedArtifactURLRequest) GetWorkflowJobRunBackendId() str...
method GetName (line 558) | func (x *GetSignedArtifactURLRequest) GetName() string {
type GetSignedArtifactURLResponse (line 565) | type GetSignedArtifactURLResponse struct
method Reset (line 573) | func (x *GetSignedArtifactURLResponse) Reset() {
method String (line 582) | func (x *GetSignedArtifactURLResponse) String() string {
method ProtoMessage (line 586) | func (*GetSignedArtifactURLResponse) ProtoMessage() {}
method ProtoReflect (line 588) | func (x *GetSignedArtifactURLResponse) ProtoReflect() protoreflect.Mes...
method Descriptor (line 601) | func (*GetSignedArtifactURLResponse) Descriptor() ([]byte, []int) {
method GetSignedUrl (line 605) | func (x *GetSignedArtifactURLResponse) GetSignedUrl() string {
type DeleteArtifactRequest (line 612) | type DeleteArtifactRequest struct
method Reset (line 622) | func (x *DeleteArtifactRequest) Reset() {
method String (line 631) | func (x *DeleteArtifactRequest) String() string {
method ProtoMessage (line 635) | func (*DeleteArtifactRequest) ProtoMessage() {}
method ProtoReflect (line 637) | func (x *DeleteArtifactRequest) ProtoReflect() protoreflect.Message {
method Descriptor (line 650) | func (*DeleteArtifactRequest) Descriptor() ([]byte, []int) {
method GetWorkflowRunBackendId (line 654) | func (x *DeleteArtifactRequest) GetWorkflowRunBackendId() string {
method GetWorkflowJobRunBackendId (line 661) | func (x *DeleteArtifactRequest) GetWorkflowJobRunBackendId() string {
method GetName (line 668) | func (x *DeleteArtifactRequest) GetName() string {
type DeleteArtifactResponse (line 675) | type DeleteArtifactResponse struct
method Reset (line 684) | func (x *DeleteArtifactResponse) Reset() {
method String (line 693) | func (x *DeleteArtifactResponse) String() string {
method ProtoMessage (line 697) | func (*DeleteArtifactResponse) ProtoMessage() {}
method ProtoReflect (line 699) | func (x *DeleteArtifactResponse) ProtoReflect() protoreflect.Message {
method Descriptor (line 712) | func (*DeleteArtifactResponse) Descriptor() ([]byte, []int) {
method GetOk (line 716) | func (x *DeleteArtifactResponse) GetOk() bool {
method GetArtifactId (line 723) | func (x *DeleteArtifactResponse) GetArtifactId() int64 {
function file_artifact_proto_rawDescGZIP (line 860) | func file_artifact_proto_rawDescGZIP() []byte {
function init (line 901) | func init() { file_artifact_proto_init() }
function file_artifact_proto_init (line 902) | func file_artifact_proto_init() {
FILE: pkg/artifacts/artifacts_v4.go
constant ArtifactV4RouteBase (line 106) | ArtifactV4RouteBase = "/twirp/github.actions.results.api.v1.Artifa...
constant ArtifactV4ContentEncoding (line 107) | ArtifactV4ContentEncoding = "application/zip"
type artifactV4Routes (line 110) | type artifactV4Routes struct
method buildSignature (line 201) | func (r artifactV4Routes) buildSignature(endp, expires, artifactName s...
method buildArtifactURL (line 210) | func (r artifactV4Routes) buildArtifactURL(endp, artifactName string, ...
method verifySignature (line 217) | func (r artifactV4Routes) verifySignature(ctx *ArtifactContext, endp s...
method parseProtbufBody (line 240) | func (r *artifactV4Routes) parseProtbufBody(ctx *ArtifactContext, req ...
method sendProtbufBody (line 256) | func (r *artifactV4Routes) sendProtbufBody(ctx *ArtifactContext, req p...
method createArtifact (line 268) | func (r *artifactV4Routes) createArtifact(ctx *ArtifactContext) {
method uploadArtifact (line 298) | func (r *artifactV4Routes) uploadArtifact(ctx *ArtifactContext) {
method finalizeArtifact (line 339) | func (r *artifactV4Routes) finalizeArtifact(ctx *ArtifactContext) {
method listArtifacts (line 357) | func (r *artifactV4Routes) listArtifacts(ctx *ArtifactContext) {
method getSignedArtifactURL (line 402) | func (r *artifactV4Routes) getSignedArtifactURL(ctx *ArtifactContext) {
method downloadArtifact (line 421) | func (r *artifactV4Routes) downloadArtifact(ctx *ArtifactContext) {
method deleteArtifact (line 436) | func (r *artifactV4Routes) deleteArtifact(ctx *ArtifactContext) {
type ArtifactContext (line 118) | type ArtifactContext struct
method Error (line 129) | func (c ArtifactContext) Error(status int, _ ...interface{}) {
method JSON (line 133) | func (c ArtifactContext) JSON(status int, _ ...interface{}) {
function artifactNameToID (line 123) | func artifactNameToID(s string) int64 {
function validateRunIDV4 (line 137) | func validateRunIDV4(ctx *ArtifactContext, rawRunID string) (interface{}...
function RoutesV4 (line 147) | func RoutesV4(router *httprouter.Router, baseDir string, fsys WriteFS, r...
FILE: pkg/artifacts/server.go
type FileContainerResourceURL (line 21) | type FileContainerResourceURL struct
type NamedFileContainerResourceURL (line 25) | type NamedFileContainerResourceURL struct
type NamedFileContainerResourceURLResponse (line 30) | type NamedFileContainerResourceURLResponse struct
type ContainerItem (line 35) | type ContainerItem struct
type ContainerItemResponse (line 41) | type ContainerItemResponse struct
type ResponseMessage (line 45) | type ResponseMessage struct
type WritableFile (line 49) | type WritableFile interface
type WriteFS (line 53) | type WriteFS interface
type readWriteFSImpl (line 58) | type readWriteFSImpl struct
method Open (line 61) | func (fwfs readWriteFSImpl) Open(name string) (fs.File, error) {
method OpenWritable (line 65) | func (fwfs readWriteFSImpl) OpenWritable(name string) (WritableFile, e...
method OpenAppendable (line 72) | func (fwfs readWriteFSImpl) OpenAppendable(name string) (WritableFile,...
function safeResolve (line 91) | func safeResolve(baseDir string, relPath string) string {
function uploads (line 95) | func uploads(router *httprouter.Router, baseDir string, fsys WriteFS) {
function downloads (line 178) | func downloads(router *httprouter.Router, baseDir string, fsys fs.FS) {
function Serve (line 278) | func Serve(ctx context.Context, artifactPath string, addr string, port s...
FILE: pkg/artifacts/server_test.go
type writableMapFile (line 24) | type writableMapFile struct
method Write (line 28) | func (f *writableMapFile) Write(data []byte) (int, error) {
method Close (line 33) | func (f *writableMapFile) Close() error {
type writeMapFS (line 37) | type writeMapFS struct
method OpenWritable (line 41) | func (fsys writeMapFS) OpenWritable(name string) (WritableFile, error) {
method OpenAppendable (line 52) | func (fsys writeMapFS) OpenAppendable(name string) (WritableFile, erro...
function TestNewArtifactUploadPrepare (line 63) | func TestNewArtifactUploadPrepare(t *testing.T) {
function TestArtifactUploadBlob (line 89) | func TestArtifactUploadBlob(t *testing.T) {
function TestFinalizeArtifactUpload (line 116) | func TestFinalizeArtifactUpload(t *testing.T) {
function TestListArtifacts (line 142) | func TestListArtifacts(t *testing.T) {
function TestListArtifactContainer (line 174) | func TestListArtifactContainer(t *testing.T) {
function TestDownloadArtifactFile (line 207) | func TestDownloadArtifactFile(t *testing.T) {
type TestJobFileInfo (line 233) | type TestJobFileInfo struct
function TestArtifactFlow (line 248) | func TestArtifactFlow(t *testing.T) {
function runTestJobFile (line 274) | func runTestJobFile(ctx context.Context, t *testing.T, tjfi TestJobFileI...
function TestMkdirFsImplSafeResolve (line 320) | func TestMkdirFsImplSafeResolve(t *testing.T) {
function TestDownloadArtifactFileUnsafePath (line 344) | func TestDownloadArtifactFileUnsafePath(t *testing.T) {
function TestArtifactUploadBlobUnsafePath (line 370) | func TestArtifactUploadBlobUnsafePath(t *testing.T) {
FILE: pkg/common/auth.go
type actionsClaims (line 17) | type actionsClaims struct
type actionsCacheScope (line 26) | type actionsCacheScope struct
type actionsCachePermission (line 31) | type actionsCachePermission
constant actionsCachePermissionRead (line 34) | actionsCachePermissionRead = 1 << iota
constant actionsCachePermissionWrite (line 35) | actionsCachePermissionWrite
function CreateAuthorizationToken (line 38) | func CreateAuthorizationToken(taskID, runID, jobID int64) (string, error) {
function ParseAuthorizationToken (line 72) | func ParseAuthorizationToken(req *http.Request) (int64, error) {
FILE: pkg/common/auth_test.go
function TestCreateAuthorizationToken (line 15) | func TestCreateAuthorizationToken(t *testing.T) {
function TestParseAuthorizationToken (line 41) | func TestParseAuthorizationToken(t *testing.T) {
function TestParseAuthorizationTokenNoAuthHeader (line 55) | func TestParseAuthorizationTokenNoAuthHeader(t *testing.T) {
FILE: pkg/common/cartesian.go
function CartesianProduct (line 4) | func CartesianProduct(mapOfLists map[string][]interface{}) []map[string]...
function cartN (line 25) | func cartN(a ...[]interface{}) [][]interface{} {
FILE: pkg/common/cartesian_test.go
function TestCartesianProduct (line 9) | func TestCartesianProduct(t *testing.T) {
FILE: pkg/common/context.go
function createGracefulJobCancellationContext (line 10) | func createGracefulJobCancellationContext() (context.Context, func(), ch...
function CreateGracefulJobCancellationContext (line 42) | func CreateGracefulJobCancellationContext() (context.Context, func()) {
FILE: pkg/common/context_test.go
function TestGracefulJobCancellationViaSigint (line 13) | func TestGracefulJobCancellationViaSigint(t *testing.T) {
function TestForceCancellationViaSigterm (line 45) | func TestForceCancellationViaSigterm(t *testing.T) {
function TestCreateGracefulJobCancellationContext (line 74) | func TestCreateGracefulJobCancellationContext(t *testing.T) {
function TestCreateGracefulJobCancellationContextCancelFunc (line 84) | func TestCreateGracefulJobCancellationContextCancelFunc(t *testing.T) {
FILE: pkg/common/draw.go
type Style (line 11) | type Style
constant StyleDoubleLine (line 15) | StyleDoubleLine = iota
constant StyleSingleLine (line 16) | StyleSingleLine
constant StyleDashedLine (line 17) | StyleDashedLine
constant StyleNoLine (line 18) | StyleNoLine
function NewPen (line 22) | func NewPen(style Style, color int) *Pen {
type styleDef (line 35) | type styleDef struct
type Pen (line 52) | type Pen struct
method drawTopBars (line 64) | func (p *Pen) drawTopBars(buf io.Writer, labels ...string) {
method drawBottomBars (line 75) | func (p *Pen) drawBottomBars(buf io.Writer, labels ...string) {
method drawLabels (line 86) | func (p *Pen) drawLabels(buf io.Writer, labels ...string) {
method DrawArrow (line 98) | func (p *Pen) DrawArrow() *Drawing {
method DrawBoxes (line 110) | func (p *Pen) DrawBoxes(labels ...string) *Drawing {
type Drawing (line 59) | type Drawing struct
method Draw (line 127) | func (d *Drawing) Draw(writer io.Writer, centerOnWidth int) {
method GetWidth (line 141) | func (d *Drawing) GetWidth() int {
FILE: pkg/common/dryrun.go
type dryrunContextKey (line 7) | type dryrunContextKey
constant dryrunContextKeyVal (line 9) | dryrunContextKeyVal = dryrunContextKey("dryrun")
function Dryrun (line 12) | func Dryrun(ctx context.Context) bool {
function WithDryrun (line 23) | func WithDryrun(ctx context.Context, dryrun bool) context.Context {
FILE: pkg/common/executor.go
type Warning (line 12) | type Warning struct
method Error (line 17) | func (w Warning) Error() string {
function Warningf (line 22) | func Warningf(format string, args ...interface{}) Warning {
type Executor (line 30) | type Executor
method ThenError (line 141) | func (e Executor) ThenError(then func(ctx context.Context, err error) ...
method Then (line 160) | func (e Executor) Then(then Executor) Executor {
method OnError (line 179) | func (e Executor) OnError(then Executor) Executor {
method If (line 198) | func (e Executor) If(conditional Conditional) Executor {
method IfNot (line 208) | func (e Executor) IfNot(conditional Conditional) Executor {
method IfBool (line 218) | func (e Executor) IfBool(conditional bool) Executor {
method Finally (line 225) | func (e Executor) Finally(finally Executor) Executor {
type Conditional (line 33) | type Conditional
method Not (line 237) | func (c Conditional) Not() Conditional {
function NewInfoExecutor (line 36) | func NewInfoExecutor(format string, args ...interface{}) Executor {
function NewDebugExecutor (line 45) | func NewDebugExecutor(format string, args ...interface{}) Executor {
function NewPipelineExecutor (line 54) | func NewPipelineExecutor(executors ...Executor) Executor {
function NewConditionalExecutor (line 72) | func NewConditionalExecutor(conditional Conditional, trueExecutor Execut...
function NewErrorExecutor (line 88) | func NewErrorExecutor(err error) Executor {
function NewParallelExecutor (line 95) | func NewParallelExecutor(parallel int, executors ...Executor) Executor {
function NewFieldExecutor (line 134) | func NewFieldExecutor(name string, value interface{}, exec Executor) Exe...
FILE: pkg/common/executor_test.go
function TestNewWorkflow (line 12) | func TestNewWorkflow(t *testing.T) {
function TestNewConditionalExecutor (line 40) | func TestNewConditionalExecutor(t *testing.T) {
function TestNewParallelExecutor (line 77) | func TestNewParallelExecutor(t *testing.T) {
function TestNewParallelExecutorFailed (line 116) | func TestNewParallelExecutorFailed(t *testing.T) {
function TestNewParallelExecutorCanceled (line 132) | func TestNewParallelExecutorCanceled(t *testing.T) {
FILE: pkg/common/file.go
function CopyFile (line 10) | func CopyFile(source string, dest string) (err error) {
function CopyDir (line 37) | func CopyDir(source string, dest string) (err error) {
FILE: pkg/common/git/git.go
type Error (line 37) | type Error struct
method Error (line 42) | func (e *Error) Error() string {
method Unwrap (line 46) | func (e *Error) Unwrap() error {
method Commit (line 50) | func (e *Error) Commit() string {
function FindGitRevision (line 55) | func FindGitRevision(ctx context.Context, file string) (shortSha string,...
function FindGitRef (line 87) | func FindGitRef(ctx context.Context, file string) (string, error) {
function FindGithubRepo (line 164) | func FindGithubRepo(ctx context.Context, file, githubInstance, remoteNam...
function findGitRemoteURL (line 177) | func findGitRemoteURL(_ context.Context, file, remoteName string) (strin...
function findGitSlug (line 201) | func findGitSlug(url string, githubInstance string) (string, string, err...
type NewGitCloneExecutorInput (line 223) | type NewGitCloneExecutorInput struct
function CloneIfRequired (line 232) | func CloneIfRequired(ctx context.Context, refName plumbing.ReferenceName...
function gitOptions (line 281) | func gitOptions(token string) (fetchOptions git.FetchOptions, pullOption...
function NewGitCloneExecutor (line 300) | func NewGitCloneExecutor(input NewGitCloneExecutorInput) common.Executor {
FILE: pkg/common/git/git_test.go
function TestFindGitSlug (line 19) | func TestFindGitSlug(t *testing.T) {
function testDir (line 48) | func testDir(t *testing.T) string {
function cleanGitHooks (line 55) | func cleanGitHooks(dir string) error {
function TestFindGitRemoteURL (line 76) | func TestFindGitRemoteURL(t *testing.T) {
function TestGitFindRef (line 102) | func TestGitFindRef(t *testing.T) {
function TestGitCloneExecutor (line 180) | func TestGitCloneExecutor(t *testing.T) {
function gitConfig (line 224) | func gitConfig() {
function gitCmd (line 236) | func gitCmd(args ...string) error {
function TestCloneIfRequired (line 251) | func TestCloneIfRequired(t *testing.T) {
FILE: pkg/common/job_error.go
type jobErrorContextKey (line 7) | type jobErrorContextKey
constant jobErrorContextKeyVal (line 9) | jobErrorContextKeyVal = jobErrorContextKey("job.error")
type jobCancelCtx (line 11) | type jobCancelCtx
constant JobCancelCtxVal (line 13) | JobCancelCtxVal = jobCancelCtx("job.cancel")
function JobError (line 16) | func JobError(ctx context.Context) error {
function SetJobError (line 26) | func SetJobError(ctx context.Context, err error) {
function WithJobErrorContainer (line 31) | func WithJobErrorContainer(ctx context.Context) context.Context {
function WithJobCancelContext (line 36) | func WithJobCancelContext(ctx context.Context, cancelContext context.Con...
function JobCancelContext (line 40) | func JobCancelContext(ctx context.Context) context.Context {
function EarlyCancelContext (line 51) | func EarlyCancelContext(ctx context.Context) (context.Context, context.C...
FILE: pkg/common/line_writer.go
type LineHandler (line 9) | type LineHandler
type lineWriter (line 11) | type lineWriter struct
method Write (line 23) | func (lw *lineWriter) Write(p []byte) (n int, err error) {
method handleLine (line 43) | func (lw *lineWriter) handleLine(line string) {
function NewLineWriter (line 17) | func NewLineWriter(handlers ...LineHandler) io.Writer {
FILE: pkg/common/line_writer_test.go
function TestLineWriter (line 9) | func TestLineWriter(t *testing.T) {
FILE: pkg/common/logger.go
type loggerContextKey (line 9) | type loggerContextKey
constant loggerContextKeyVal (line 11) | loggerContextKeyVal = loggerContextKey("logrus.FieldLogger")
function Logger (line 14) | func Logger(ctx context.Context) logrus.FieldLogger {
function WithLogger (line 25) | func WithLogger(ctx context.Context, logger logrus.FieldLogger) context....
FILE: pkg/common/outbound_ip.go
function GetOutboundIP (line 13) | func GetOutboundIP() net.IP {
FILE: pkg/container/container_types.go
type NewContainerInput (line 12) | type NewContainerInput struct
type FileEntry (line 36) | type FileEntry struct
type Container (line 43) | type Container interface
type NewDockerBuildExecutorInput (line 61) | type NewDockerBuildExecutorInput struct
type NewDockerPullExecutorInput (line 70) | type NewDockerPullExecutorInput struct
type Health (line 78) | type Health
constant HealthStarting (line 81) | HealthStarting Health = iota
constant HealthHealthy (line 82) | HealthHealthy
constant HealthUnHealthy (line 83) | HealthUnHealthy
FILE: pkg/container/docker_auth.go
function LoadDockerAuthConfig (line 15) | func LoadDockerAuthConfig(ctx context.Context, image string) (registry.A...
function LoadDockerAuthConfigs (line 42) | func LoadDockerAuthConfigs(ctx context.Context) map[string]registry.Auth...
FILE: pkg/container/docker_build.go
function NewDockerBuildExecutor (line 21) | func NewDockerBuildExecutor(input NewDockerBuildExecutorInput) common.Ex...
function createBuildContext (line 71) | func createBuildContext(ctx context.Context, contextDir string, relDocke...
FILE: pkg/container/docker_cli.go
type containerOptions (line 45) | type containerOptions struct
function addFlags (line 144) | func addFlags(flags *pflag.FlagSet) *containerOptions {
type containerConfig (line 315) | type containerConfig struct
function parse (line 326) | func parse(flags *pflag.FlagSet, copts *containerOptions, serverOS strin...
function parseNetworkOpts (line 718) | func parseNetworkOpts(copts *containerOptions) (map[string]*networktypes...
function applyContainerOptions (line 764) | func applyContainerOptions(n *opts.NetworkAttachmentOpts, copts *contain...
function parseNetworkAttachmentOpt (line 802) | func parseNetworkAttachmentOpt(ep opts.NetworkAttachmentOpts) (*networkt...
function convertToStandardNotation (line 834) | func convertToStandardNotation(ports []string) ([]string, error) {
function parseLoggingOpts (line 855) | func parseLoggingOpts(loggingDriver string, loggingOpts []string) (map[s...
function parseSecurityOpts (line 864) | func parseSecurityOpts(securityOpts []string) ([]string, error) {
function parseSystemPaths (line 895) | func parseSystemPaths(securityOpts []string) (filtered, maskedPaths, rea...
function parseStorageOpts (line 910) | func parseStorageOpts(storageOpts []string) (map[string]string, error) {
function parseDevice (line 924) | func parseDevice(device, serverOS string) (container.DeviceMapping, erro...
function parseLinuxDevice (line 936) | func parseLinuxDevice(device string) (container.DeviceMapping, error) {
function parseWindowsDevice (line 971) | func parseWindowsDevice(device string) (container.DeviceMapping, error) {
function validateDeviceCgroupRule (line 979) | func validateDeviceCgroupRule(val string) (string, error) {
function validDeviceMode (line 989) | func validDeviceMode(mode string) bool {
function validateDevice (line 1008) | func validateDevice(val string, serverOS string) (string, error) {
function validateLinuxPath (line 1026) | func validateLinuxPath(val string, validator func(string) bool) (string,...
function validateAttach (line 1067) | func validateAttach(val string) (string, error) {
function validateAPIVersion (line 1077) | func validateAPIVersion(c *containerConfig, serverAPIVersion string) err...
FILE: pkg/container/docker_cli_test.go
function TestValidateAttach (line 31) | func TestValidateAttach(t *testing.T) {
function parseRun (line 55) | func parseRun(args []string) (*container.Config, *container.HostConfig, ...
function setupRunFlags (line 68) | func setupRunFlags() (*pflag.FlagSet, *containerOptions) {
function mustParse (line 76) | func mustParse(t *testing.T, args string) (*container.Config, *container...
function TestParseRunLinks (line 83) | func TestParseRunLinks(t *testing.T) {
function TestParseRunAttach (line 95) | func TestParseRunAttach(t *testing.T) {
function TestParseRunWithInvalidArgs (line 147) | func TestParseRunWithInvalidArgs(t *testing.T) {
function TestParseWithVolumes (line 194) | func TestParseWithVolumes(t *testing.T) {
function setupPlatformVolume (line 270) | func setupPlatformVolume(u []string, w []string) ([]string, string) {
function compareRandomizedStrings (line 286) | func compareRandomizedStrings(a, b, c, d string) error {
function TestParseWithMacAddress (line 297) | func TestParseWithMacAddress(t *testing.T) {
function TestRunFlagsParseWithMemory (line 308) | func TestRunFlagsParseWithMemory(t *testing.T) {
function TestParseWithMemorySwap (line 318) | func TestParseWithMemorySwap(t *testing.T) {
function TestParseHostname (line 331) | func TestParseHostname(t *testing.T) {
function TestParseHostnameDomainname (line 354) | func TestParseHostnameDomainname(t *testing.T) {
function TestParseWithExpose (line 375) | func TestParseWithExpose(t *testing.T) {
function TestParseDevice (line 428) | func TestParseDevice(t *testing.T) {
function TestParseNetworkConfig (line 467) | func TestParseNetworkConfig(t *testing.T) {
function TestParseModes (line 620) | func TestParseModes(t *testing.T) {
function TestRunFlagsParseShmSize (line 647) | func TestRunFlagsParseShmSize(t *testing.T) {
function TestParseRestartPolicy (line 663) | func TestParseRestartPolicy(t *testing.T) {
function TestParseRestartPolicyAutoRemove (line 695) | func TestParseRestartPolicyAutoRemove(t *testing.T) {
function TestParseHealth (line 703) | func TestParseHealth(t *testing.T) {
function TestParseLoggingOpts (line 742) | func TestParseLoggingOpts(t *testing.T) {
function TestParseEnvfileVariables (line 757) | func TestParseEnvfileVariables(t *testing.T) {
function TestParseEnvfileVariablesWithBOMUnicode (line 783) | func TestParseEnvfileVariablesWithBOMUnicode(t *testing.T) {
function TestParseLabelfileVariables (line 810) | func TestParseLabelfileVariables(t *testing.T) {
function TestParseEntryPoint (line 836) | func TestParseEntryPoint(t *testing.T) {
function TestValidateDevice (line 846) | func TestValidateDevice(t *testing.T) {
function TestParseSystemPaths (line 898) | func TestParseSystemPaths(t *testing.T) {
function TestConvertToStandardNotation (line 952) | func TestConvertToStandardNotation(t *testing.T) {
FILE: pkg/container/docker_images.go
function ImageExistsLocally (line 16) | func ImageExistsLocally(ctx context.Context, imageName string, platform ...
function RemoveImage (line 44) | func RemoveImage(ctx context.Context, imageName string, force bool, prun...
FILE: pkg/container/docker_images_test.go
function init (line 14) | func init() {
function TestImageExistsLocally (line 18) | func TestImageExistsLocally(t *testing.T) {
FILE: pkg/container/docker_logger.go
type dockerMessage (line 14) | type dockerMessage struct
constant logPrefix (line 25) | logPrefix = " \U0001F433 "
function logDockerResponse (line 27) | func logDockerResponse(logger logrus.FieldLogger, dockerResponse io.Read...
function writeLog (line 77) | func writeLog(logger logrus.FieldLogger, isError bool, format string, ar...
FILE: pkg/container/docker_network.go
function NewDockerNetworkCreateExecutor (line 12) | func NewDockerNetworkCreateExecutor(name string) common.Executor {
function NewDockerNetworkRemoveExecutor (line 45) | func NewDockerNetworkRemoveExecutor(name string) common.Executor {
FILE: pkg/container/docker_pull.go
function NewDockerPullExecutor (line 20) | func NewDockerPullExecutor(input NewDockerPullExecutorInput) common.Exec...
function getImagePullOptions (line 77) | func getImagePullOptions(ctx context.Context, input NewDockerPullExecuto...
function cleanImage (line 118) | func cleanImage(ctx context.Context, image string) string {
FILE: pkg/container/docker_pull_test.go
function init (line 13) | func init() {
function TestCleanImage (line 17) | func TestCleanImage(t *testing.T) {
function TestGetImagePullOptions (line 37) | func TestGetImagePullOptions(t *testing.T) {
FILE: pkg/container/docker_run.go
function NewContainer (line 43) | func NewContainer(input *NewContainerInput) ExecutionsEnvironment {
function supportsContainerImagePlatform (line 51) | func supportsContainerImagePlatform(ctx context.Context, cli client.APIC...
type containerReference (line 206) | type containerReference struct
method Create (line 67) | func (cr *containerReference) Create(capAdd []string, capDrop []string...
method Start (line 79) | func (cr *containerReference) Start(attach bool) common.Executor {
method Pull (line 102) | func (cr *containerReference) Pull(forcePull bool) common.Executor {
method Copy (line 116) | func (cr *containerReference) Copy(destPath string, files ...*FileEntr...
method CopyDir (line 124) | func (cr *containerReference) CopyDir(destPath string, srcPath string,...
method GetContainerArchive (line 138) | func (cr *containerReference) GetContainerArchive(ctx context.Context,...
method UpdateFromEnv (line 146) | func (cr *containerReference) UpdateFromEnv(srcPath string, env *map[s...
method UpdateFromImageEnv (line 150) | func (cr *containerReference) UpdateFromImageEnv(env *map[string]strin...
method Exec (line 154) | func (cr *containerReference) Exec(command []string, env map[string]st...
method Remove (line 163) | func (cr *containerReference) Remove() common.Executor {
method GetHealth (line 172) | func (cr *containerReference) GetHealth(ctx context.Context) Health {
method ReplaceLogWriter (line 196) | func (cr *containerReference) ReplaceLogWriter(stdout io.Writer, stder...
method connect (line 278) | func (cr *containerReference) connect() common.Executor {
method Close (line 292) | func (cr *containerReference) Close() common.Executor {
method find (line 305) | func (cr *containerReference) find() common.Executor {
method remove (line 331) | func (cr *containerReference) remove() common.Executor {
method mergeContainerConfigs (line 352) | func (cr *containerReference) mergeContainerConfigs(ctx context.Contex...
method create (line 410) | func (cr *containerReference) create(capAdd []string, capDrop []string...
method extractFromImageEnv (line 504) | func (cr *containerReference) extractFromImageEnv(env *map[string]stri...
method exec (line 542) | func (cr *containerReference) exec(cmd []string, env map[string]string...
method tryReadID (line 615) | func (cr *containerReference) tryReadID(opt string, cbk func(id int)) ...
method tryReadUID (line 648) | func (cr *containerReference) tryReadUID() common.Executor {
method tryReadGID (line 652) | func (cr *containerReference) tryReadGID() common.Executor {
method waitForCommand (line 656) | func (cr *containerReference) waitForCommand(ctx context.Context, isTe...
method CopyTarStream (line 701) | func (cr *containerReference) CopyTarStream(ctx context.Context, destP...
method copyDir (line 730) | func (cr *containerReference) copyDir(dstPath string, srcPath string, ...
method copyContent (line 801) | func (cr *containerReference) copyContent(dstPath string, files ...*Fi...
method attach (line 835) | func (cr *containerReference) attach() common.Executor {
method start (line 870) | func (cr *containerReference) start() common.Executor {
method wait (line 884) | func (cr *containerReference) wait() common.Executor {
function GetDockerClient (line 215) | func GetDockerClient(ctx context.Context) (cli client.APIClient, err err...
function GetHostInfo (line 240) | func GetHostInfo(ctx context.Context) (info system.Info, err error) {
function RunnerArch (line 259) | func RunnerArch(ctx context.Context) string {
FILE: pkg/container/docker_run_test.go
function TestDocker (line 22) | func TestDocker(t *testing.T) {
type mockDockerClient (line 62) | type mockDockerClient struct
method ContainerExecCreate (line 67) | func (m *mockDockerClient) ContainerExecCreate(ctx context.Context, id...
method ContainerExecAttach (line 72) | func (m *mockDockerClient) ContainerExecAttach(ctx context.Context, id...
method ContainerExecInspect (line 77) | func (m *mockDockerClient) ContainerExecInspect(ctx context.Context, e...
method CopyToContainer (line 82) | func (m *mockDockerClient) CopyToContainer(ctx context.Context, id str...
type endlessReader (line 87) | type endlessReader struct
method Read (line 91) | func (r endlessReader) Read(_ []byte) (n int, err error) {
type mockConn (line 95) | type mockConn struct
method Write (line 100) | func (m *mockConn) Write(b []byte) (n int, err error) {
method Close (line 105) | func (m *mockConn) Close() (err error) {
function TestDockerExecAbort (line 109) | func TestDockerExecAbort(t *testing.T) {
function TestDockerExecFailure (line 147) | func TestDockerExecFailure(t *testing.T) {
function TestDockerCopyTarStream (line 177) | func TestDockerCopyTarStream(t *testing.T) {
function TestDockerCopyTarStreamDryRun (line 199) | func TestDockerCopyTarStreamDryRun(t *testing.T) {
function TestDockerCopyTarStreamErrorInCopyFiles (line 221) | func TestDockerCopyTarStreamErrorInCopyFiles(t *testing.T) {
function TestDockerCopyTarStreamErrorInMkdir (line 246) | func TestDockerCopyTarStreamErrorInMkdir(t *testing.T) {
FILE: pkg/container/docker_socket.go
function socketLocation (line 23) | func socketLocation() (string, bool) {
function isDockerHostURI (line 45) | func isDockerHostURI(daemonPath string) bool {
type SocketAndHost (line 57) | type SocketAndHost struct
function GetSocketAndHost (line 62) | func GetSocketAndHost(containerSocket string) (SocketAndHost, error) {
FILE: pkg/container/docker_socket_test.go
function init (line 11) | func init() {
function TestGetSocketAndHostWithSocket (line 17) | func TestGetSocketAndHostWithSocket(t *testing.T) {
function TestGetSocketAndHostNoSocket (line 32) | func TestGetSocketAndHostNoSocket(t *testing.T) {
function TestGetSocketAndHostOnlySocket (line 45) | func TestGetSocketAndHostOnlySocket(t *testing.T) {
function TestGetSocketAndHostDontMount (line 62) | func TestGetSocketAndHostDontMount(t *testing.T) {
function TestGetSocketAndHostNoHostNoSocket (line 76) | func TestGetSocketAndHostNoHostNoSocket(t *testing.T) {
function TestGetSocketAndHostNoHostNoSocketDefaultLocation (line 94) | func TestGetSocketAndHostNoHostNoSocketDefaultLocation(t *testing.T) {
function TestGetSocketAndHostNoHostInvalidSocket (line 116) | func TestGetSocketAndHostNoHostInvalidSocket(t *testing.T) {
function TestGetSocketAndHostOnlySocketValidButUnusualLocation (line 133) | func TestGetSocketAndHostOnlySocketValidButUnusualLocation(t *testing.T) {
FILE: pkg/container/docker_stub.go
function ImageExistsLocally (line 16) | func ImageExistsLocally(ctx context.Context, imageName string, platform ...
function RemoveImage (line 22) | func RemoveImage(ctx context.Context, imageName string, force bool, prun...
function NewDockerBuildExecutor (line 27) | func NewDockerBuildExecutor(input NewDockerBuildExecutorInput) common.Ex...
function NewDockerPullExecutor (line 34) | func NewDockerPullExecutor(input NewDockerPullExecutorInput) common.Exec...
function NewContainer (line 41) | func NewContainer(input *NewContainerInput) ExecutionsEnvironment {
function RunnerArch (line 45) | func RunnerArch(ctx context.Context) string {
function GetHostInfo (line 49) | func GetHostInfo(ctx context.Context) (info system.Info, err error) {
function NewDockerVolumeRemoveExecutor (line 53) | func NewDockerVolumeRemoveExecutor(volume string, force bool) common.Exe...
function NewDockerNetworkCreateExecutor (line 59) | func NewDockerNetworkCreateExecutor(name string) common.Executor {
function NewDockerNetworkRemoveExecutor (line 65) | func NewDockerNetworkRemoveExecutor(name string) common.Executor {
FILE: pkg/container/docker_volume.go
function NewDockerVolumeRemoveExecutor (line 13) | func NewDockerVolumeRemoveExecutor(volumeName string, force bool) common...
function removeExecutor (line 37) | func removeExecutor(volume string, force bool) common.Executor {
FILE: pkg/container/executions_environment.go
type ExecutionsEnvironment (line 5) | type ExecutionsEnvironment interface
FILE: pkg/container/host_environment.go
type HostEnvironment (line 28) | type HostEnvironment struct
method Create (line 38) | func (e *HostEnvironment) Create(_ []string, _ []string) common.Execut...
method Close (line 44) | func (e *HostEnvironment) Close() common.Executor {
method Copy (line 50) | func (e *HostEnvironment) Copy(destPath string, files ...*FileEntry) c...
method CopyTarStream (line 64) | func (e *HostEnvironment) CopyTarStream(ctx context.Context, destPath ...
method CopyDir (line 91) | func (e *HostEnvironment) CopyDir(destPath string, srcPath string, use...
method GetContainerArchive (line 121) | func (e *HostEnvironment) GetContainerArchive(ctx context.Context, src...
method Pull (line 171) | func (e *HostEnvironment) Pull(_ bool) common.Executor {
method Start (line 177) | func (e *HostEnvironment) Start(_ bool) common.Executor {
method UpdateFromImageEnv (line 271) | func (e *HostEnvironment) UpdateFromImageEnv(_ *map[string]string) com...
method exec (line 285) | func (e *HostEnvironment) exec(ctx context.Context, command []string, ...
method Exec (line 356) | func (e *HostEnvironment) Exec(command []string /*cmdline string, */, ...
method ExecWithCmdLine (line 360) | func (e *HostEnvironment) ExecWithCmdLine(command []string, cmdline st...
method UpdateFromEnv (line 374) | func (e *HostEnvironment) UpdateFromEnv(srcPath string, env *map[strin...
method Remove (line 378) | func (e *HostEnvironment) Remove() common.Executor {
method ToContainerPath (line 387) | func (e *HostEnvironment) ToContainerPath(path string) string {
method GetActPath (line 396) | func (e *HostEnvironment) GetActPath() string {
method GetPathVariableName (line 404) | func (*HostEnvironment) GetPathVariableName() string {
method DefaultPathVariable (line 413) | func (e *HostEnvironment) DefaultPathVariable() string {
method JoinPathVariable (line 418) | func (*HostEnvironment) JoinPathVariable(paths ...string) string {
method GetRunnerContext (line 449) | func (e *HostEnvironment) GetRunnerContext(_ context.Context) map[stri...
method GetHealth (line 458) | func (e *HostEnvironment) GetHealth(_ context.Context) Health {
method ReplaceLogWriter (line 462) | func (e *HostEnvironment) ReplaceLogWriter(stdout io.Writer, _ io.Writ...
method IsEnvironmentCaseInsensitive (line 468) | func (*HostEnvironment) IsEnvironmentCaseInsensitive() bool {
type ptyWriter (line 183) | type ptyWriter struct
method Write (line 189) | func (w *ptyWriter) Write(buf []byte) (int, error) {
type localEnv (line 205) | type localEnv struct
method Getenv (line 209) | func (l *localEnv) Getenv(name string) string {
function lookupPathHost (line 221) | func lookupPathHost(cmd string, env map[string]string, writer io.Writer)...
function setupPty (line 233) | func setupPty(cmd *exec.Cmd, cmdline string) (*os.File, *os.File, error) {
function writeKeepAlive (line 253) | func writeKeepAlive(ppty io.Writer) {
function copyPtyOutput (line 262) | func copyPtyOutput(writer io.Writer, ppty io.Reader, finishLog context.C...
function getEnvListFromMap (line 277) | func getEnvListFromMap(env map[string]string) []string {
function goArchToActionArch (line 424) | func goArchToActionArch(arch string) string {
function goOsToActionOs (line 437) | func goOsToActionOs(os string) string {
FILE: pkg/container/host_environment_test.go
function TestCopyDir (line 18) | func TestCopyDir(t *testing.T) {
function TestGetContainerArchive (line 39) | func TestGetContainerArchive(t *testing.T) {
FILE: pkg/container/linux_container_environment_extensions.go
type LinuxContainerEnvironmentExtensions (line 13) | type LinuxContainerEnvironmentExtensions struct
method ToContainerPath (line 19) | func (*LinuxContainerEnvironmentExtensions) ToContainerPath(path strin...
method GetActPath (line 50) | func (*LinuxContainerEnvironmentExtensions) GetActPath() string {
method GetPathVariableName (line 54) | func (*LinuxContainerEnvironmentExtensions) GetPathVariableName() stri...
method DefaultPathVariable (line 58) | func (*LinuxContainerEnvironmentExtensions) DefaultPathVariable() stri...
method JoinPathVariable (line 62) | func (*LinuxContainerEnvironmentExtensions) JoinPathVariable(paths ......
method GetRunnerContext (line 66) | func (*LinuxContainerEnvironmentExtensions) GetRunnerContext(ctx conte...
method IsEnvironmentCaseInsensitive (line 75) | func (*LinuxContainerEnvironmentExtensions) IsEnvironmentCaseInsensiti...
FILE: pkg/container/linux_container_environment_extensions_test.go
function TestContainerPath (line 14) | func TestContainerPath(t *testing.T) {
type typeAssertMockContainer (line 65) | type typeAssertMockContainer struct
FILE: pkg/container/parse_env_file.go
function parseEnvFile (line 14) | func parseEnvFile(e Container, srcPath string, env *map[string]string) c...
FILE: pkg/container/util.go
function getSysProcAttr (line 12) | func getSysProcAttr(_ string, tty bool) *syscall.SysProcAttr {
function openPty (line 24) | func openPty() (*os.File, *os.File, error) {
FILE: pkg/container/util_openbsd_mips64.go
function getSysProcAttr (line 9) | func getSysProcAttr(cmdLine string, tty bool) *syscall.SysProcAttr {
function openPty (line 15) | func openPty() (*os.File, *os.File, error) {
FILE: pkg/container/util_plan9.go
function getSysProcAttr (line 9) | func getSysProcAttr(cmdLine string, tty bool) *syscall.SysProcAttr {
function openPty (line 15) | func openPty() (*os.File, *os.File, error) {
FILE: pkg/container/util_windows.go
function getSysProcAttr (line 9) | func getSysProcAttr(cmdLine string, tty bool) *syscall.SysProcAttr {
function openPty (line 13) | func openPty() (*os.File, *os.File, error) {
FILE: pkg/exprparser/functions.go
method contains (line 22) | func (impl *interperterImpl) contains(search, item reflect.Value) (bool,...
method startsWith (line 47) | func (impl *interperterImpl) startsWith(searchString, searchValue reflec...
method endsWith (line 54) | func (impl *interperterImpl) endsWith(searchString, searchValue reflect....
constant passThrough (line 62) | passThrough = iota
constant bracketOpen (line 63) | bracketOpen
constant bracketClose (line 64) | bracketClose
method format (line 67) | func (impl *interperterImpl) format(str reflect.Value, replaceValue ...r...
method join (line 140) | func (impl *interperterImpl) join(array reflect.Value, sep reflect.Value...
method toJSON (line 155) | func (impl *interperterImpl) toJSON(value reflect.Value) (string, error) {
method fromJSON (line 168) | func (impl *interperterImpl) fromJSON(value reflect.Value) (interface{},...
method hashFiles (line 183) | func (impl *interperterImpl) hashFiles(paths ...reflect.Value) (string, ...
method getNeedsTransitive (line 244) | func (impl *interperterImpl) getNeedsTransitive(job *model.Job) []string {
method always (line 255) | func (impl *interperterImpl) always() (bool, error) {
method jobSuccess (line 259) | func (impl *interperterImpl) jobSuccess() (bool, error) {
method stepSuccess (line 272) | func (impl *interperterImpl) stepSuccess() (bool, error) {
method jobFailure (line 276) | func (impl *interperterImpl) jobFailure() (bool, error) {
method stepFailure (line 289) | func (impl *interperterImpl) stepFailure() (bool, error) {
method cancelled (line 293) | func (impl *interperterImpl) cancelled() (bool, error) {
FILE: pkg/exprparser/functions_test.go
function TestFunctionContains (line 11) | func TestFunctionContains(t *testing.T) {
function TestFunctionStartsWith (line 55) | func TestFunctionStartsWith(t *testing.T) {
function TestFunctionEndsWith (line 84) | func TestFunctionEndsWith(t *testing.T) {
function TestFunctionJoin (line 113) | func TestFunctionJoin(t *testing.T) {
function TestFunctionToJSON (line 140) | func TestFunctionToJSON(t *testing.T) {
function TestFunctionFromJSON (line 166) | func TestFunctionFromJSON(t *testing.T) {
function TestFunctionHashFiles (line 189) | func TestFunctionHashFiles(t *testing.T) {
function TestFunctionFormat (line 219) | func TestFunctionFormat(t *testing.T) {
function TestMapContains (line 260) | func TestMapContains(t *testing.T) {
FILE: pkg/exprparser/interpreter.go
type EvaluationEnvironment (line 14) | type EvaluationEnvironment struct
type Needs (line 30) | type Needs struct
type Config (line 35) | type Config struct
type DefaultStatusCheck (line 41) | type DefaultStatusCheck
method String (line 51) | func (dsc DefaultStatusCheck) String() string {
constant DefaultStatusCheckNone (line 44) | DefaultStatusCheckNone DefaultStatusCheck = iota
constant DefaultStatusCheckSuccess (line 45) | DefaultStatusCheckSuccess
constant DefaultStatusCheckAlways (line 46) | DefaultStatusCheckAlways
constant DefaultStatusCheckCanceled (line 47) | DefaultStatusCheckCanceled
constant DefaultStatusCheckFailure (line 48) | DefaultStatusCheckFailure
type Interpreter (line 65) | type Interpreter interface
type interperterImpl (line 69) | type interperterImpl struct
method Evaluate (line 81) | func (impl *interperterImpl) Evaluate(input string, defaultStatusCheck...
method evaluateNode (line 120) | func (impl *interperterImpl) evaluateNode(exprNode actionlint.ExprNode...
method evaluateVariable (line 153) | func (impl *interperterImpl) evaluateVariable(variableNode *actionlint...
method evaluateIndexAccess (line 191) | func (impl *interperterImpl) evaluateIndexAccess(indexAccessNode *acti...
method evaluateObjectDeref (line 226) | func (impl *interperterImpl) evaluateObjectDeref(objectDerefNode *acti...
method evaluateArrayDeref (line 239) | func (impl *interperterImpl) evaluateArrayDeref(arrayDerefNode *action...
method getPropertyValue (line 248) | func (impl *interperterImpl) getPropertyValue(left reflect.Value, prop...
method getPropertyValueDereferenced (line 319) | func (impl *interperterImpl) getPropertyValueDereferenced(left reflect...
method getMapValue (line 347) | func (impl *interperterImpl) getMapValue(value reflect.Value) (interfa...
method evaluateNot (line 355) | func (impl *interperterImpl) evaluateNot(notNode *actionlint.NotOpNode...
method evaluateCompare (line 364) | func (impl *interperterImpl) evaluateCompare(compareNode *actionlint.C...
method compareValues (line 381) | func (impl *interperterImpl) compareValues(leftValue reflect.Value, ri...
method coerceToNumber (line 424) | func (impl *interperterImpl) coerceToNumber(value reflect.Value) refle...
method coerceToString (line 456) | func (impl *interperterImpl) coerceToString(value reflect.Value) refle...
method compareString (line 493) | func (impl *interperterImpl) compareString(left string, right string, ...
method compareNumber (line 512) | func (impl *interperterImpl) compareNumber(left float64, right float64...
method isNumber (line 558) | func (impl *interperterImpl) isNumber(value reflect.Value) bool {
method getSafeValue (line 567) | func (impl *interperterImpl) getSafeValue(value reflect.Value) interfa...
method evaluateLogicalCompare (line 581) | func (impl *interperterImpl) evaluateLogicalCompare(compareNode *actio...
method evaluateFuncCall (line 611) | func (impl *interperterImpl) evaluateFuncCall(funcCallNode *actionlint...
function NewInterpeter (line 74) | func NewInterpeter(env *EvaluationEnvironment, config Config) Interpreter {
function IsTruthy (line 531) | func IsTruthy(input interface{}) bool {
FILE: pkg/exprparser/interpreter_test.go
function TestLiterals (line 11) | func TestLiterals(t *testing.T) {
function TestOperators (line 40) | func TestOperators(t *testing.T) {
function TestOperatorsCompare (line 114) | func TestOperatorsCompare(t *testing.T) {
function TestOperatorsBooleanEvaluation (line 162) | func TestOperatorsBooleanEvaluation(t *testing.T) {
function TestContexts (line 529) | func TestContexts(t *testing.T) {
FILE: pkg/filecollector/file_collector.go
type Handler (line 20) | type Handler interface
type TarCollector (line 24) | type TarCollector struct
method WriteFile (line 31) | func (tc TarCollector) WriteFile(fpath string, fi fs.FileInfo, linkNam...
type CopyCollector (line 62) | type CopyCollector struct
method WriteFile (line 66) | func (cc *CopyCollector) WriteFile(fpath string, fi fs.FileInfo, linkN...
type FileCollector (line 85) | type FileCollector struct
method CollectFiles (line 128) | func (fc *FileCollector) CollectFiles(ctx context.Context, submodulePa...
type Fs (line 93) | type Fs interface
type DefaultFs (line 100) | type DefaultFs struct
method Walk (line 103) | func (*DefaultFs) Walk(root string, fn filepath.WalkFunc) error {
method OpenGitIndex (line 107) | func (*DefaultFs) OpenGitIndex(path string) (*index.Index, error) {
method Open (line 119) | func (*DefaultFs) Open(path string) (io.ReadCloser, error) {
method Readlink (line 123) | func (*DefaultFs) Readlink(path string) (string, error) {
FILE: pkg/filecollector/file_collector_test.go
type memoryFs (line 21) | type memoryFs struct
method walk (line 25) | func (mfs *memoryFs) walk(root string, fn filepath.WalkFunc) error {
method Walk (line 47) | func (mfs *memoryFs) Walk(root string, fn filepath.WalkFunc) error {
method OpenGitIndex (line 59) | func (mfs *memoryFs) OpenGitIndex(path string) (*index.Index, error) {
method Open (line 69) | func (mfs *memoryFs) Open(path string) (io.ReadCloser, error) {
method Readlink (line 73) | func (mfs *memoryFs) Readlink(path string) (string, error) {
function TestIgnoredTrackedfile (line 77) | func TestIgnoredTrackedfile(t *testing.T) {
function TestSymlinks (line 119) | func TestSymlinks(t *testing.T) {
FILE: pkg/gh/gh.go
function GetToken (line 10) | func GetToken(ctx context.Context, workingDirectory string) (string, err...
FILE: pkg/gh/gh_test.go
function TestGetToken (line 8) | func TestGetToken(t *testing.T) {
FILE: pkg/lookpath/env.go
type Env (line 5) | type Env interface
type defaultEnv (line 9) | type defaultEnv struct
method Getenv (line 12) | func (*defaultEnv) Getenv(name string) string {
function LookPath (line 16) | func LookPath(file string) (string, error) {
FILE: pkg/lookpath/error.go
type Error (line 3) | type Error struct
method Error (line 8) | func (e *Error) Error() string {
FILE: pkg/lookpath/lp_js.go
function LookPath2 (line 20) | func LookPath2(file string, lenv Env) (string, error) {
FILE: pkg/lookpath/lp_plan9.go
function findExecutable (line 18) | func findExecutable(file string) error {
function LookPath2 (line 34) | func LookPath2(file string, lenv Env) (string, error) {
FILE: pkg/lookpath/lp_unix.go
function findExecutable (line 20) | func findExecutable(file string) error {
function LookPath2 (line 35) | func LookPath2(file string, lenv Env) (string, error) {
FILE: pkg/lookpath/lp_windows.go
function chkStat (line 18) | func chkStat(file string) error {
function hasExt (line 29) | func hasExt(file string) bool {
function findExecutable (line 37) | func findExecutable(file string, exts []string) (string, error) {
function LookPath2 (line 60) | func LookPath2(file string, lenv Env) (string, error) {
FILE: pkg/model/action.go
type ActionRunsUsing (line 13) | type ActionRunsUsing
method UnmarshalYAML (line 15) | func (a *ActionRunsUsing) UnmarshalYAML(unmarshal func(interface{}) er...
method IsNode (line 54) | func (a ActionRunsUsing) IsNode() bool {
method IsDocker (line 63) | func (a ActionRunsUsing) IsDocker() bool {
method IsComposite (line 67) | func (a ActionRunsUsing) IsComposite() bool {
constant ActionRunsUsingNode12 (line 41) | ActionRunsUsingNode12 = "node12"
constant ActionRunsUsingNode16 (line 43) | ActionRunsUsingNode16 = "node16"
constant ActionRunsUsingNode20 (line 45) | ActionRunsUsingNode20 = "node20"
constant ActionRunsUsingNode24 (line 47) | ActionRunsUsingNode24 = "node24"
constant ActionRunsUsingDocker (line 49) | ActionRunsUsingDocker = "docker"
constant ActionRunsUsingComposite (line 51) | ActionRunsUsingComposite = "composite"
type ActionRuns (line 72) | type ActionRuns struct
type Action (line 89) | type Action struct
method UnmarshalYAML (line 102) | func (a *Action) UnmarshalYAML(node *yaml.Node) error {
type Input (line 120) | type Input struct
type Output (line 127) | type Output struct
function ReadAction (line 133) | func ReadAction(in io.Reader) (*Action, error) {
FILE: pkg/model/anchors.go
function resolveAliasesExt (line 9) | func resolveAliasesExt(node *yaml.Node, path map[*yaml.Node]bool, skipCh...
function resolveAliases (line 36) | func resolveAliases(node *yaml.Node) error {
FILE: pkg/model/anchors_test.go
function TestVerifyNilAliasError (line 10) | func TestVerifyNilAliasError(t *testing.T) {
function TestVerifyNoRecursion (line 25) | func TestVerifyNoRecursion(t *testing.T) {
FILE: pkg/model/github_context.go
type GithubContext (line 12) | type GithubContext struct
method SetRef (line 97) | func (ghc *GithubContext) SetRef(ctx context.Context, defaultBranch st...
method SetSha (line 142) | func (ghc *GithubContext) SetSha(ctx context.Context, repoPath string) {
method SetRepositoryAndOwner (line 168) | func (ghc *GithubContext) SetRepositoryAndOwner(ctx context.Context, g...
method SetRefTypeAndName (line 183) | func (ghc *GithubContext) SetRefTypeAndName() {
method SetBaseAndHeadRef (line 207) | func (ghc *GithubContext) SetBaseAndHeadRef() {
function asString (line 45) | func asString(v interface{}) string {
function nestedMapLookup (line 54) | func nestedMapLookup(m map[string]interface{}, ks ...string) (rval inter...
function withDefaultBranch (line 71) | func withDefaultBranch(ctx context.Context, b string, event map[string]i...
FILE: pkg/model/github_context_test.go
function TestSetRef (line 12) | func TestSetRef(t *testing.T) {
function TestSetSha (line 126) | func TestSetSha(t *testing.T) {
FILE: pkg/model/job_context.go
type JobContext (line 3) | type JobContext struct
FILE: pkg/model/planner.go
type WorkflowPlanner (line 17) | type WorkflowPlanner interface
type Plan (line 25) | type Plan struct
method MaxRunNameLen (line 304) | func (p *Plan) MaxRunNameLen() int {
method mergeStages (line 327) | func (p *Plan) mergeStages(stages []*Stage) {
type Stage (line 30) | type Stage struct
method GetJobIDs (line 318) | func (s *Stage) GetJobIDs() []string {
type Run (line 35) | type Run struct
method String (line 40) | func (r *Run) String() string {
method Job (line 49) | func (r *Run) Job() *Job {
type WorkflowFiles (line 53) | type WorkflowFiles struct
function NewWorkflowPlanner (line 59) | func NewWorkflowPlanner(path string, noWorkflowRecurse, strict bool) (Wo...
function NewSingleWorkflowPlanner (line 160) | func NewSingleWorkflowPlanner(name string, f io.Reader) (WorkflowPlanner...
function validateJobName (line 186) | func validateJobName(workflow *Workflow) error {
type workflowPlanner (line 196) | type workflowPlanner struct
method PlanEvent (line 201) | func (wp *workflowPlanner) PlanEvent(eventName string) (*Plan, error) {
method PlanJob (line 232) | func (wp *workflowPlanner) PlanJob(jobName string) (*Plan, error) {
method PlanAll (line 252) | func (wp *workflowPlanner) PlanAll() (*Plan, error) {
method GetEvents (line 274) | func (wp *workflowPlanner) GetEvents() []string {
function createStages (line 343) | func createStages(w *Workflow, jobIDs ...string) ([]*Stage, error) {
function listInStages (line 384) | func listInStages(srcList []string, stages ...*Stage) bool {
FILE: pkg/model/planner_test.go
type WorkflowPlanTest (line 11) | type WorkflowPlanTest struct
function TestPlanner (line 17) | func TestPlanner(t *testing.T) {
function TestWorkflow (line 43) | func TestWorkflow(t *testing.T) {
FILE: pkg/model/step_result.go
type stepStatus (line 5) | type stepStatus
method MarshalText (line 19) | func (s stepStatus) MarshalText() ([]byte, error) {
method UnmarshalText (line 23) | func (s *stepStatus) UnmarshalText(b []byte) error {
method String (line 34) | func (s stepStatus) String() string {
constant StepStatusSuccess (line 8) | StepStatusSuccess stepStatus = iota
constant StepStatusFailure (line 9) | StepStatusFailure
constant StepStatusSkipped (line 10) | StepStatusSkipped
type StepResult (line 41) | type StepResult struct
FILE: pkg/model/workflow.go
type Workflow (line 19) | type Workflow struct
method On (line 29) | func (w *Workflow) On() []string {
method OnEvent (line 60) | func (w *Workflow) OnEvent(event string) interface{} {
method UnmarshalYAML (line 71) | func (w *Workflow) UnmarshalYAML(node *yaml.Node) error {
method WorkflowDispatchConfig (line 117) | func (w *Workflow) WorkflowDispatchConfig() *WorkflowDispatch {
method WorkflowCallConfig (line 175) | func (w *Workflow) WorkflowCallConfig() *WorkflowCall {
method GetJob (line 726) | func (w *Workflow) GetJob(jobID string) *Job {
method GetJobIDs (line 742) | func (w *Workflow) GetJobIDs() []string {
type WorkflowStrict (line 87) | type WorkflowStrict
method UnmarshalYAML (line 89) | func (w *WorkflowStrict) UnmarshalYAML(node *yaml.Node) error {
type WorkflowDispatchInput (line 105) | type WorkflowDispatchInput struct
type WorkflowDispatch (line 113) | type WorkflowDispatch struct
type WorkflowCallInput (line 154) | type WorkflowCallInput struct
type WorkflowCallOutput (line 161) | type WorkflowCallOutput struct
type WorkflowCall (line 166) | type WorkflowCall struct
type WorkflowCallResult (line 171) | type WorkflowCallResult struct
type Job (line 196) | type Job struct
method InheritSecrets (line 266) | func (j *Job) InheritSecrets() bool {
method Secrets (line 279) | func (j *Job) Secrets() map[string]string {
method Container (line 293) | func (j *Job) Container() *ContainerSpec {
method Needs (line 311) | func (j *Job) Needs() []string {
method RunsOn (line 330) | func (j *Job) RunsOn() []string {
method Environment (line 383) | func (j *Job) Environment() map[string]string {
method Matrix (line 388) | func (j *Job) Matrix() map[string][]interface{} {
method GetMatrixes (line 401) | func (j *Job) GetMatrixes() ([]map[string]interface{}, error) {
method Type (line 530) | func (j *Job) Type() (JobType, error) {
type Strategy (line 216) | type Strategy struct
method GetMaxParallel (line 236) | func (s Strategy) GetMaxParallel() int {
method GetFailFast (line 253) | func (s Strategy) GetFailFast() bool {
type Defaults (line 225) | type Defaults struct
type RunDefaults (line 230) | type RunDefaults struct
function nodeAsStringSlice (line 354) | func nodeAsStringSlice(node yaml.Node) []string {
function environment (line 372) | func environment(yml yaml.Node) map[string]string {
function commonKeysMatch (line 481) | func commonKeysMatch(a map[string]interface{}, b map[string]interface{})...
function commonKeysMatch2 (line 490) | func commonKeysMatch2(a map[string]interface{}, b map[string]interface{}...
type JobType (line 501) | type JobType
method String (line 517) | func (j JobType) String() string {
constant JobTypeDefault (line 505) | JobTypeDefault JobType = iota
constant JobTypeReusableWorkflowLocal (line 508) | JobTypeReusableWorkflowLocal
constant JobTypeReusableWorkflowRemote (line 511) | JobTypeReusableWorkflowRemote
constant JobTypeInvalid (line 514) | JobTypeInvalid
type ContainerSpec (line 555) | type ContainerSpec struct
type Step (line 569) | type Step struct
method String (line 586) | func (s *Step) String() string {
method Environment (line 598) | func (s *Step) Environment() map[string]string {
method GetEnv (line 603) | func (s *Step) GetEnv() map[string]string {
method ShellCommand (line 615) | func (s *Step) ShellCommand() string {
method Type (line 691) | func (s *Step) Type() StepType {
type StepType (line 645) | type StepType
method String (line 670) | func (s StepType) String() string {
constant StepTypeRun (line 649) | StepTypeRun StepType = iota
constant StepTypeUsesDockerURL (line 652) | StepTypeUsesDockerURL
constant StepTypeUsesActionLocal (line 655) | StepTypeUsesActionLocal
constant StepTypeUsesActionRemote (line 658) | StepTypeUsesActionRemote
constant StepTypeReusableWorkflowLocal (line 661) | StepTypeReusableWorkflowLocal
constant StepTypeReusableWorkflowRemote (line 664) | StepTypeReusableWorkflowRemote
constant StepTypeInvalid (line 667) | StepTypeInvalid
function ReadWorkflow (line 714) | func ReadWorkflow(in io.Reader, strict bool) (*Workflow, error) {
function decodeNode (line 754) | func decodeNode(node yaml.Node, out interface{}) bool {
FILE: pkg/model/workflow_test.go
function TestReadWorkflow_StringEvent (line 12) | func TestReadWorkflow_StringEvent(t *testing.T) {
function TestReadWorkflow_ListEvent (line 31) | func TestReadWorkflow_ListEvent(t *testing.T) {
function TestReadWorkflow_MapEvent (line 51) | func TestReadWorkflow_MapEvent(t *testing.T) {
function TestReadWorkflow_RunsOnLabels (line 76) | func TestReadWorkflow_RunsOnLabels(t *testing.T) {
function TestReadWorkflow_RunsOnLabelsWithGroup (line 93) | func TestReadWorkflow_RunsOnLabelsWithGroup(t *testing.T) {
function TestReadWorkflow_StringContainer (line 111) | func TestReadWorkflow_StringContainer(t *testing.T) {
function TestReadWorkflow_ObjectContainer (line 139) | func TestReadWorkflow_ObjectContainer(t *testing.T) {
function TestReadWorkflow_JobTypes (line 178) | func TestReadWorkflow_JobTypes(t *testing.T) {
function TestReadWorkflow_JobTypes_InvalidPath (line 228) | func TestReadWorkflow_JobTypes_InvalidPath(t *testing.T) {
function TestReadWorkflow_StepsTypes (line 264) | func TestReadWorkflow_StepsTypes(t *testing.T) {
function TestReadWorkflow_JobOutputs (line 290) | func TestReadWorkflow_JobOutputs(t *testing.T) {
function TestReadWorkflow_Strategy (line 331) | func TestReadWorkflow_Strategy(t *testing.T) {
function TestMatrixOnlyIncludes (line 398) | func TestMatrixOnlyIncludes(t *testing.T) {
function TestStep_ShellCommand (line 424) | func TestStep_ShellCommand(t *testing.T) {
function TestReadWorkflow_WorkflowDispatchConfig (line 444) | func TestReadWorkflow_WorkflowDispatchConfig(t *testing.T) {
function TestReadWorkflow_InvalidStringEvent (line 548) | func TestReadWorkflow_InvalidStringEvent(t *testing.T) {
function TestReadWorkflow_AnchorStrict (line 564) | func TestReadWorkflow_AnchorStrict(t *testing.T) {
function TestReadWorkflow_Anchor (line 588) | func TestReadWorkflow_Anchor(t *testing.T) {
FILE: pkg/runner/action.go
type actionStep (line 24) | type actionStep interface
type readAction (line 32) | type readAction
type actionYamlReader (line 34) | type actionYamlReader
type fileWriter (line 36) | type fileWriter
type runAction (line 38) | type runAction
function readActionImpl (line 43) | func readActionImpl(ctx context.Context, step *model.Step, actionDir str...
function maybeCopyToActionDir (line 119) | func maybeCopyToActionDir(ctx context.Context, step actionStep, actionDi...
function runActionImpl (line 153) | func runActionImpl(step actionStep, actionDir string, remoteAction *remo...
function setupActionEnv (line 214) | func setupActionEnv(ctx context.Context, step actionStep, _ *remoteActio...
function removeGitIgnore (line 232) | func removeGitIgnore(ctx context.Context, directory string) error {
function execAsDocker (line 248) | func execAsDocker(ctx context.Context, step actionStep, actionName, base...
function evalDockerArgs (line 358) | func evalDockerArgs(ctx context.Context, step step, action *model.Action...
function newStepContainer (line 387) | func newStepContainer(ctx context.Context, step step, image string, cmd ...
function populateEnvsFromSavedState (line 441) | func populateEnvsFromSavedState(env *map[string]string, step actionStep,...
function populateEnvsFromInput (line 451) | func populateEnvsFromInput(ctx context.Context, env *map[string]string, ...
function getContainerActionPaths (line 462) | func getContainerActionPaths(step *model.Step, actionDir string, rc *Run...
function getOsSafeRelativePath (line 483) | func getOsSafeRelativePath(s, prefix string) string {
function shouldRunPreStep (line 493) | func shouldRunPreStep(step actionStep) common.Conditional {
function hasPreStep (line 506) | func hasPreStep(step actionStep) common.Conditional {
function runPreStep (line 517) | func runPreStep(step actionStep) common.Executor {
function shouldRunPostStep (line 588) | func shouldRunPostStep(step actionStep) common.Conditional {
function hasPostStep (line 613) | func hasPostStep(step actionStep) common.Conditional {
function runPostStep (line 624) | func runPostStep(step actionStep) common.Executor {
FILE: pkg/runner/action_cache.go
type ActionCache (line 25) | type ActionCache interface
type GoGitActionCache (line 30) | type GoGitActionCache struct
method Fetch (line 34) | func (c GoGitActionCache) Fetch(ctx context.Context, cacheDir, url, re...
method GetTarArchive (line 130) | func (c GoGitActionCache) GetTarArchive(ctx context.Context, cacheDir,...
type GitFileInfo (line 92) | type GitFileInfo struct
method IsDir (line 101) | func (g *GitFileInfo) IsDir() bool {
method ModTime (line 106) | func (g *GitFileInfo) ModTime() time.Time {
method Mode (line 111) | func (g *GitFileInfo) Mode() fs.FileMode {
method Name (line 116) | func (g *GitFileInfo) Name() string {
method Size (line 121) | func (g *GitFileInfo) Size() int64 {
method Sys (line 126) | func (g *GitFileInfo) Sys() any {
function actionCacheCopyFileOrDir (line 175) | func actionCacheCopyFileOrDir(ctx context.Context, cleanIncludePrefix st...
FILE: pkg/runner/action_cache_offline_mode.go
type GoGitActionCacheOfflineMode (line 13) | type GoGitActionCacheOfflineMode struct
method Fetch (line 17) | func (c GoGitActionCacheOfflineMode) Fetch(ctx context.Context, cacheD...
method GetTarArchive (line 45) | func (c GoGitActionCacheOfflineMode) GetTarArchive(ctx context.Context...
FILE: pkg/runner/action_cache_test.go
function TestActionCache (line 15) | func TestActionCache(t *testing.T) {
function TestActionCacheFailures (line 79) | func TestActionCacheFailures(t *testing.T) {
FILE: pkg/runner/action_composite.go
function evaluateCompositeInputAndEnv (line 13) | func evaluateCompositeInputAndEnv(ctx context.Context, parent *RunContex...
function newCompositeRunContext (line 47) | func newCompositeRunContext(ctx context.Context, parent *RunContext, ste...
function execAsComposite (line 84) | func execAsComposite(step actionStep) common.Executor {
type compositeSteps (line 126) | type compositeSteps struct
method compositeExecutor (line 133) | func (rc *RunContext) compositeExecutor(action *model.Action) *composite...
method newCompositeCommandExecutor (line 197) | func (rc *RunContext) newCompositeCommandExecutor(executor common.Execut...
function newCompositeStepLogExecutor (line 222) | func newCompositeStepLogExecutor(runStep common.Executor, stepID string)...
FILE: pkg/runner/action_test.go
type closerMock (line 15) | type closerMock struct
method Close (line 19) | func (m *closerMock) Close() error {
function TestActionReader (line 24) | func TestActionReader(t *testing.T) {
function TestActionRunner (line 143) | func TestActionRunner(t *testing.T) {
FILE: pkg/runner/command.go
function init (line 16) | func init() {
function tryParseRawActionCommand (line 21) | func tryParseRawActionCommand(line string) (command string, kvPairs map[...
method commandHandler (line 36) | func (rc *RunContext) commandHandler(ctx context.Context) common.LineHan...
method setEnv (line 87) | func (rc *RunContext) setEnv(ctx context.Context, kvPairs map[string]str...
method setOutput (line 106) | func (rc *RunContext) setOutput(ctx context.Context, kvPairs map[string]...
method addPath (line 124) | func (rc *RunContext) addPath(ctx context.Context, arg string) {
function parseKeyValuePairs (line 135) | func parseKeyValuePairs(kvPairs string, separator string) map[string]str...
function unescapeCommandData (line 146) | func unescapeCommandData(arg string) string {
function unescapeCommandProperty (line 157) | func unescapeCommandProperty(arg string) string {
function unescapeKvPairs (line 170) | func unescapeKvPairs(kvPairs map[string]string) map[string]string {
method saveState (line 177) | func (rc *RunContext) saveState(_ context.Context, kvPairs map[string]st...
FILE: pkg/runner/command_test.go
function TestSetEnv (line 17) | func TestSetEnv(t *testing.T) {
function TestSetOutput (line 27) | func TestSetOutput(t *testing.T) {
function TestAddpath (line 57) | func TestAddpath(t *testing.T) {
function TestStopCommands (line 70) | func TestStopCommands(t *testing.T) {
function TestAddpathADO (line 95) | func TestAddpathADO(t *testing.T) {
function TestAddmask (line 108) | func TestAddmask(t *testing.T) {
function captureOutput (line 124) | func captureOutput(t *testing.T, f func()) string {
function TestAddmaskUsemask (line 150) | func TestAddmaskUsemask(t *testing.T) {
function TestSaveState (line 177) | func TestSaveState(t *testing.T) {
FILE: pkg/runner/container_mock_test.go
type containerMock (line 12) | type containerMock struct
method Create (line 18) | func (cm *containerMock) Create(capAdd []string, capDrop []string) com...
method Pull (line 23) | func (cm *containerMock) Pull(forcePull bool) common.Executor {
method Start (line 28) | func (cm *containerMock) Start(attach bool) common.Executor {
method Remove (line 33) | func (cm *containerMock) Remove() common.Executor {
method Close (line 38) | func (cm *containerMock) Close() common.Executor {
method UpdateFromEnv (line 43) | func (cm *containerMock) UpdateFromEnv(srcPath string, env *map[string...
method UpdateFromImageEnv (line 48) | func (cm *containerMock) UpdateFromImageEnv(env *map[string]string) co...
method Copy (line 53) | func (cm *containerMock) Copy(destPath string, files ...*container.Fil...
method CopyDir (line 58) | func (cm *containerMock) CopyDir(destPath string, srcPath string, useG...
method Exec (line 63) | func (cm *containerMock) Exec(command []string, env map[string]string,...
method GetContainerArchive (line 68) | func (cm *containerMock) GetContainerArchive(ctx context.Context, srcP...
FILE: pkg/runner/expression.go
type ExpressionEvaluator (line 23) | type ExpressionEvaluator interface
method NewExpressionEvaluator (line 30) | func (rc *RunContext) NewExpressionEvaluator(ctx context.Context) Expres...
method NewExpressionEvaluatorWithEnv (line 34) | func (rc *RunContext) NewExpressionEvaluatorWithEnv(ctx context.Context,...
method NewStepExpressionEvaluator (line 110) | func (rc *RunContext) NewStepExpressionEvaluator(ctx context.Context, st...
method NewStepExpressionEvaluatorExt (line 115) | func (rc *RunContext) NewStepExpressionEvaluatorExt(ctx context.Context,...
method newStepExpressionEvaluator (line 123) | func (rc *RunContext) newStepExpressionEvaluator(ctx context.Context, st...
function getHashFilesFunction (line 170) | func getHashFilesFunction(ctx context.Context, rc *RunContext) func(v []...
type expressionEvaluator (line 231) | type expressionEvaluator struct
method evaluate (line 235) | func (ee expressionEvaluator) evaluate(ctx context.Context, in string,...
method evaluateScalarYamlNode (line 246) | func (ee expressionEvaluator) evaluateScalarYamlNode(ctx context.Conte...
method evaluateMappingYamlNode (line 266) | func (ee expressionEvaluator) evaluateMappingYamlNode(ctx context.Cont...
method evaluateSequenceYamlNode (line 324) | func (ee expressionEvaluator) evaluateSequenceYamlNode(ctx context.Con...
method evaluateYamlNodeInternal (line 356) | func (ee expressionEvaluator) evaluateYamlNodeInternal(ctx context.Con...
method EvaluateYamlNode (line 369) | func (ee expressionEvaluator) EvaluateYamlNode(ctx context.Context, no...
method Interpolate (line 380) | func (ee expressionEvaluator) Interpolate(ctx context.Context, in stri...
function EvalBool (line 401) | func EvalBool(ctx context.Context, evaluator ExpressionEvaluator, expr s...
function escapeFormatString (line 412) | func escapeFormatString(in string) string {
function rewriteSubExpression (line 416) | func rewriteSubExpression(ctx context.Context, in string, forceFormat bo...
function getEvaluatorInputs (line 482) | func getEvaluatorInputs(ctx context.Context, rc *RunContext, step step, ...
function setupWorkflowInputs (line 538) | func setupWorkflowInputs(ctx context.Context, inputs *map[string]interfa...
function getWorkflowSecrets (line 569) | func getWorkflowSecrets(ctx context.Context, rc *RunContext) map[string]...
function getWorkflowVars (line 592) | func getWorkflowVars(_ context.Context, rc *RunContext) map[string]string {
FILE: pkg/runner/expression_test.go
function createRunContext (line 17) | func createRunContext(t *testing.T) *RunContext {
function TestEvaluateRunContext (line 81) | func TestEvaluateRunContext(t *testing.T) {
function TestEvaluateStep (line 155) | func TestEvaluateStep(t *testing.T) {
function TestInterpolate (line 194) | func TestInterpolate(t *testing.T) {
function updateTestExpressionWorkflow (line 271) | func updateTestExpressionWorkflow(t *testing.T, tables []struct {
function TestRewriteSubExpression (line 321) | func TestRewriteSubExpression(t *testing.T) {
function TestRewriteSubExpressionForceFormat (line 351) | func TestRewriteSubExpressionForceFormat(t *testing.T) {
FILE: pkg/runner/hashfiles/index.js
function adopt (line 10) | function adopt(value) { return value instanceof P ? value : new P(functi...
function fulfilled (line 12) | function fulfilled(value) { try { step(generator.next(value)); } catch (...
function rejected (line 13) | function rejected(value) { try { step(generator["throw"](value)); } catc...
function step (line 14) | function step(result) { result.done ? resolve(result.value) : adopt(resu...
function verb (line 22) | function verb(n) { i[n] = o[n] && function (v) { return new Promise(func...
function settle (line 23) | function settle(resolve, reject, d, v) { Promise.resolve(v).then(functio...
function run (line 39) | function run() {
function issueCommand (line 148) | function issueCommand(command, properties, message) {
function issue (line 153) | function issue(name, message = '') {
class Command (line 158) | class Command {
method constructor (line 159) | constructor(command, properties, message) {
method toString (line 167) | toString() {
function escapeData (line 191) | function escapeData(s) {
function escapeProperty (line 197) | function escapeProperty(s) {
function adopt (line 234) | function adopt(value) { return value instanceof P ? value : new P(functi...
function fulfilled (line 236) | function fulfilled(value) { try { step(generator.next(value)); } catch (...
function rejected (line 237) | function rejected(value) { try { step(generator["throw"](value)); } catc...
function step (line 238) | function step(result) { result.done ? resolve(result.value) : adopt(resu...
function exportVariable (line 274) | function exportVariable(name, val) {
function setSecret (line 299) | function setSecret(secret) {
function addPath (line 307) | function addPath(inputPath) {
function getInput (line 327) | function getInput(name, options) {
function getMultilineInput (line 346) | function getMultilineInput(name, options) {
function getBooleanInput (line 363) | function getBooleanInput(name, options) {
function setOutput (line 382) | function setOutput(name, value) {
function setCommandEcho (line 392) | function setCommandEcho(enabled) {
function setFailed (line 404) | function setFailed(message) {
function isDebug (line 415) | function isDebug() {
function debug (line 423) | function debug(message) {
function error (line 432) | function error(message, properties = {}) {
function warning (line 441) | function warning(message, properties = {}) {
function notice (line 450) | function notice(message, properties = {}) {
function info (line 458) | function info(message) {
function startGroup (line 469) | function startGroup(name) {
function endGroup (line 476) | function endGroup() {
function group (line 488) | function group(name, fn) {
function saveState (line 512) | function saveState(name, value) {
function getState (line 522) | function getState(name) {
function getIDToken (line 526) | function getIDToken(aud) {
function issueCommand (line 585) | function issueCommand(command, message) {
function adopt (line 608) | function adopt(value) { return value instanceof P ? value : new P(functi...
function fulfilled (line 610) | function fulfilled(value) { try { step(generator.next(value)); } catch (...
function rejected (line 611) | function rejected(value) { try { step(generator["throw"](value)); } catc...
function step (line 612) | function step(result) { result.done ? resolve(result.value) : adopt(resu...
class OidcClient (line 621) | class OidcClient {
method createHttpClient (line 622) | static createHttpClient(allowRetry = true, maxRetry = 10) {
method getRequestToken (line 629) | static getRequestToken() {
method getIDTokenUrl (line 636) | static getIDTokenUrl() {
method getCall (line 643) | static getCall(id_token_url) {
method getIDToken (line 661) | static getIDToken(audience) {
function toPosixPath (line 720) | function toPosixPath(pth) {
function toWin32Path (line 731) | function toWin32Path(pth) {
function toPlatformPath (line 743) | function toPlatformPath(pth) {
function adopt (line 757) | function adopt(value) { return value instanceof P ? value : new P(functi...
function fulfilled (line 759) | function fulfilled(value) { try { step(generator.next(value)); } catch (...
function rejected (line 760) | function rejected(value) { try { step(generator["throw"](value)); } catc...
function step (line 761) | function step(result) { result.done ? resolve(result.value) : adopt(resu...
class Summary (line 772) | class Summary {
method constructor (line 773) | constructor() {
method filePath (line 782) | filePath() {
method wrap (line 810) | wrap(tag, content, attrs = {}) {
method write (line 826) | write(options) {
method clear (line 840) | clear() {
method stringify (line 850) | stringify() {
method isEmptyBuffer (line 858) | isEmptyBuffer() {
method emptyBuffer (line 866) | emptyBuffer() {
method addRaw (line 878) | addRaw(text, addEOL = false) {
method addEOL (line 887) | addEOL() {
method addCodeBlock (line 898) | addCodeBlock(code, lang) {
method addList (line 911) | addList(items, ordered = false) {
method addTable (line 924) | addTable(rows) {
method addDetails (line 952) | addDetails(label, content) {
method addImage (line 965) | addImage(src, alt, options) {
method addHeading (line 979) | addHeading(text, level) {
method addSeparator (line 992) | addSeparator() {
method addBreak (line 1001) | addBreak() {
method addQuote (line 1013) | addQuote(text, cite) {
method addLink (line 1026) | addLink(text, href) {
function toCommandValue (line 1054) | function toCommandValue(input) {
function toCommandProperties (line 1070) | function toCommandProperties(annotationProperties) {
function adopt (line 1094) | function adopt(value) { return value instanceof P ? value : new P(functi...
function fulfilled (line 1096) | function fulfilled(value) { try { step(generator.next(value)); } catch (...
function rejected (line 1097) | function rejected(value) { try { step(generator["throw"](value)); } catc...
function step (line 1098) | function step(result) { result.done ? resolve(result.value) : adopt(resu...
function create (line 1110) | function create(patterns, options) {
function getOptions (line 1130) | function getOptions(copy) {
function adopt (line 1163) | function adopt(value) { return value instanceof P ? value : new P(functi...
function fulfilled (line 1165) | function fulfilled(value) { try { step(generator.next(value)); } catch (...
function rejected (line 1166) | function rejected(value) { try { step(generator["throw"](value)); } catc...
function step (line 1167) | function step(result) { result.done ? resolve(result.value) : adopt(resu...
function verb (line 1175) | function verb(n) { i[n] = o[n] && function (v) { return new Promise(func...
function settle (line 1176) | function settle(resolve, reject, d, v) { Promise.resolve(v).then(functio...
function verb (line 1183) | function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(fu...
function resume (line 1184) | function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3...
function step (line 1185) | function step(r) { r.value instanceof __await ? Promise.resolve(r.value....
function fulfill (line 1186) | function fulfill(value) { resume("next", value); }
function reject (line 1187) | function reject(value) { resume("throw", value); }
function settle (line 1188) | function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q...
class DefaultGlobber (line 1200) | class DefaultGlobber {
method constructor (line 1201) | constructor(options) {
method getSearchPaths (line 1206) | getSearchPaths() {
method glob (line 1210) | glob() {
method globGenerator (line 1230) | globGenerator() {
method create (line 1306) | static create(patterns, options) {
method stat (line 1328) | static stat(item, options, traversalChain) {
function dirname (line 1429) | function dirname(p) {
function ensureAbsoluteRoot (line 1449) | function ensureAbsoluteRoot(root, itemPath) {
function hasAbsoluteRoot (line 1506) | function hasAbsoluteRoot(itemPath) {
function hasRoot (line 1523) | function hasRoot(itemPath) {
function normalizeSeparators (line 1540) | function normalizeSeparators(p) {
function safeTrimTrailingSeparator (line 1558) | function safeTrimTrailingSeparator(p) {
class Path (line 1598) | class Path {
method constructor (line 1603) | constructor(itemPath) {
method toString (line 1660) | toString() {
function getSearchPaths (line 1695) | function getSearchPaths(patterns) {
function match (line 1739) | function match(patterns, itemPath) {
function partialMatch (line 1755) | function partialMatch(patterns, itemPath) {
class Pattern (line 1777) | class Pattern {
method constructor (line 1778) | constructor(patternOrNegate, segments) {
method match (line 1837) | match(itemPath) {
method partialMatch (line 1864) | partialMatch(itemPath) {
method globEscape (line 1876) | static globEscape(s) {
method fixupPattern (line 1885) | static fixupPattern(pattern) {
method getLiteral (line 1934) | static getLiteral(segment) {
method regExpEscape (line 1992) | static regExpEscape(s) {
class SearchState (line 2007) | class SearchState {
method constructor (line 2008) | constructor(path, level) {
function adopt (line 2024) | function adopt(value) { return value instanceof P ? value : new P(functi...
function fulfilled (line 2026) | function fulfilled(value) { try { step(generator.next(value)); } catch (...
function rejected (line 2027) | function rejected(value) { try { step(generator["throw"](value)); } catc...
function step (line 2028) | function step(result) { result.done ? resolve(result.value) : adopt(resu...
class BasicCredentialHandler (line 2034) | class BasicCredentialHandler {
method constructor (line 2035) | constructor(username, password) {
method prepareRequest (line 2039) | prepareRequest(options) {
method canHandleAuthentication (line 2046) | canHandleAuthentication() {
method handleAuthentication (line 2049) | handleAuthentication() {
class BearerCredentialHandler (line 2056) | class BearerCredentialHandler {
method constructor (line 2057) | constructor(token) {
method prepareRequest (line 2062) | prepareRequest(options) {
method canHandleAuthentication (line 2069) | canHandleAuthentication() {
method handleAuthentication (line 2072) | handleAuthentication() {
class PersonalAccessTokenCredentialHandler (line 2079) | class PersonalAccessTokenCredentialHandler {
method constructor (line 2080) | constructor(token) {
method prepareRequest (line 2085) | prepareRequest(options) {
method canHandleAuthentication (line 2092) | canHandleAuthentication() {
method handleAuthentication (line 2095) | handleAuthentication() {
function adopt (line 2132) | function adopt(value) { return value instanceof P ? value : new P(functi...
function fulfilled (line 2134) | function fulfilled(value) { try { step(generator.next(value)); } catch (...
function rejected (line 2135) | function rejected(value) { try { step(generator["throw"](value)); } catc...
function step (line 2136) | function step(result) { result.done ? resolve(result.value) : adopt(resu...
function getProxyUrl (line 2189) | function getProxyUrl(serverUrl) {
class HttpClientError (line 2209) | class HttpClientError extends Error {
method constructor (line 2210) | constructor(message, statusCode) {
class HttpClientResponse (line 2218) | class HttpClientResponse {
method constructor (line 2219) | constructor(message) {
method readBody (line 2222) | readBody() {
function isHttps (line 2237) | function isHttps(requestUrl) {
class HttpClient (line 2242) | class HttpClient {
method constructor (line 2243) | constructor(userAgent, handlers, requestOptions) {
method options (line 2280) | options(requestUrl, additionalHeaders) {
method get (line 2285) | get(requestUrl, additionalHeaders) {
method del (line 2290) | del(requestUrl, additionalHeaders) {
method post (line 2295) | post(requestUrl, data, additionalHeaders) {
method patch (line 2300) | patch(requestUrl, data, additionalHeaders) {
method put (line 2305) | put(requestUrl, data, additionalHeaders) {
method head (line 2310) | head(requestUrl, additionalHeaders) {
method sendStream (line 2315) | sendStream(verb, requestUrl, stream, additionalHeaders) {
method getJson (line 2324) | getJson(requestUrl, additionalHeaders = {}) {
method postJson (line 2331) | postJson(requestUrl, obj, additionalHeaders = {}) {
method putJson (line 2340) | putJson(requestUrl, obj, additionalHeaders = {}) {
method patchJson (line 2349) | patchJson(requestUrl, obj, additionalHeaders = {}) {
method request (line 2363) | request(verb, requestUrl, data, headers) {
method dispose (line 2448) | dispose() {
method requestRaw (line 2459) | requestRaw(info, data) {
method requestRawWithCallback (line 2484) | requestRawWithCallback(info, data, onResult) {
method getAgent (line 2536) | getAgent(serverUrl) {
method _prepareRequest (line 2540) | _prepareRequest(method, requestUrl, headers) {
method _mergeHeaders (line 2567) | _mergeHeaders(headers) {
method _getExistingOrDefaultHeader (line 2573) | _getExistingOrDefaultHeader(additionalHeaders, header, _default) {
method _getAgent (line 2580) | _getAgent(parsedUrl) {
method _performExponentialBackoff (line 2639) | _performExponentialBackoff(retryNumber) {
method _processResponse (line 2646) | _processResponse(res, options) {
function getProxyUrl (line 2725) | function getProxyUrl(reqUrl) {
function checkBypass (line 2746) | function checkBypass(reqUrl) {
function balanced (line 2792) | function balanced(a, b, str) {
function maybeMatch (line 2807) | function maybeMatch(reg, str) {
function range (line 2813) | function range(a, b, str) {
function numeric (line 2867) | function numeric(str) {
function escapeBraces (line 2873) | function escapeBraces(str) {
function unescapeBraces (line 2881) | function unescapeBraces(str) {
function parseCommaParts (line 2893) | function parseCommaParts(str) {
function expandTop (line 2920) | function expandTop(str) {
function identity (line 2937) | function identity(e) {
function embrace (line 2941) | function embrace(str) {
function isPadded (line 2944) | function isPadded(el) {
function lte (line 2948) | function lte(i, y) {
function gte (line 2951) | function gte(i, y) {
function expand (line 2955) | function expand(str, isTop) {
function charSet (line 3123) | function charSet (s) {
function filter (line 3134) | function filter (pattern, options) {
function ext (line 3141) | function ext (a, b) {
function minimatch (line 3198) | function minimatch (p, pattern, options) {
function Minimatch (line 3211) | function Minimatch (pattern, options) {
function make (line 3243) | function make () {
function parseNegate (line 3296) | function parseNegate () {
function braceExpand (line 3331) | function braceExpand (pattern, options) {
function parse (line 3379) | function parse (pattern, isSub) {
function makeRe (line 3751) | function makeRe () {
function globUnescape (line 4024) | function globUnescape (s) {
function regExpEscape (line 4028) | function regExpEscape (s) {
function httpOverHttp (line 4064) | function httpOverHttp(options) {
function httpsOverHttp (line 4070) | function httpsOverHttp(options) {
function httpOverHttps (line 4078) | function httpOverHttps(options) {
function httpsOverHttps (line 4084) | function httpsOverHttps(options) {
function TunnelingAgent (line 4093) | function TunnelingAgent(options) {
function onFree (line 4136) | function onFree() {
function onCloseOrRemove (line 4140) | function onCloseOrRemove(err) {
function onResponse (line 4180) | function onResponse(res) {
function onUpgrade (line 4185) | function onUpgrade(res, socket, head) {
function onConnect (line 4192) | function onConnect(res, socket, head) {
function onError (line 4221) | function onError(cause) {
function createSecureSocket (line 4251) | function createSecureSocket(options, cb) {
function toOptions (line 4268) | function toOptions(host, port, localAddress) {
function mergeOptions (line 4279) | function mergeOptions(target) {
function _interopRequireDefault (line 4397) | function _interopRequireDefault(obj) { return obj && obj.__esModule ? ob...
function _interopRequireDefault (line 4414) | function _interopRequireDefault(obj) { return obj && obj.__esModule ? ob...
function md5 (line 4416) | function md5(bytes) {
function _interopRequireDefault (line 4459) | function _interopRequireDefault(obj) { return obj && obj.__esModule ? ob...
function parse (line 4461) | function parse(uuid) {
function _interopRequireDefault (line 4526) | function _interopRequireDefault(obj) { return obj && obj.__esModule ? ob...
function rng (line 4532) | function rng() {
function _interopRequireDefault (line 4557) | function _interopRequireDefault(obj) { return obj && obj.__esModule ? ob...
function sha1 (line 4559) | function sha1(bytes) {
function _interopRequireDefault (line 4587) | function _interopRequireDefault(obj) { return obj && obj.__esModule ? ob...
function stringify (line 4599) | function stringify(arr, offset = 0) {
function _interopRequireDefault (line 4635) | function _interopRequireDefault(obj) { return obj && obj.__esModule ? ob...
function v1 (line 4649) | function v1(options, buf, offset) {
function _interopRequireDefault (line 4749) | function _interopRequireDefault(obj) { return obj && obj.__esModule ? ob...
function _interopRequireDefault (line 4773) | function _interopRequireDefault(obj) { return obj && obj.__esModule ? ob...
function stringToBytes (line 4775) | function stringToBytes(str) {
function _default (line 4792) | function _default(name, version, hashfunc) {
function _interopRequireDefault (line 4857) | function _interopRequireDefault(obj) { return obj && obj.__esModule ? ob...
function v4 (line 4859) | function v4(options, buf, offset) {
function _interopRequireDefault (line 4901) | function _interopRequireDefault(obj) { return obj && obj.__esModule ? ob...
function _interopRequireDefault (line 4922) | function _interopRequireDefault(obj) { return obj && obj.__esModule ? ob...
function validate (line 4924) | function validate(uuid) {
function _interopRequireDefault (line 4946) | function _interopRequireDefault(obj) { return obj && obj.__esModule ? ob...
function version (line 4948) | function version(uuid) {
function __nccwpck_require__ (line 5063) | function __nccwpck_require__(moduleId) {
FILE: pkg/runner/job_executor.go
type jobInfo (line 12) | type jobInfo interface
function newJobExecutor (line 23) | func newJobExecutor(info jobInfo, sf stepFactory, rc *RunContext) common...
function setJobResult (line 157) | func setJobResult(ctx context.Context, info jobInfo, rc *RunContext, suc...
function setJobOutputs (line 185) | func setJobOutputs(ctx context.Context, rc *RunContext) {
function useStepLogger (line 200) | func useStepLogger(rc *RunContext, stepModel *model.Step, stage stepStag...
FILE: pkg/runner/job_executor_test.go
function TestJobExecutor (line 16) | func TestJobExecutor(t *testing.T) {
type jobInfoMock (line 37) | type jobInfoMock struct
method matrix (line 41) | func (jim *jobInfoMock) matrix() map[string]interface{} {
method steps (line 46) | func (jim *jobInfoMock) steps() []*model.Step {
method startContainer (line 52) | func (jim *jobInfoMock) startContainer() common.Executor {
method stopContainer (line 58) | func (jim *jobInfoMock) stopContainer() common.Executor {
method closeContainer (line 64) | func (jim *jobInfoMock) closeContainer() common.Executor {
method interpolateOutputs (line 70) | func (jim *jobInfoMock) interpolateOutputs() common.Executor {
method result (line 76) | func (jim *jobInfoMock) result(result string) {
type jobContainerMock (line 80) | type jobContainerMock struct
method ReplaceLogWriter (line 85) | func (jcm *jobContainerMock) ReplaceLogWriter(_, _ io.Writer) (io.Writ...
type stepFactoryMock (line 89) | type stepFactoryMock struct
method newStep (line 93) | func (sfm *stepFactoryMock) newStep(model *model.Step, rc *RunContext)...
function TestNewJobExecutor (line 98) | func TestNewJobExecutor(t *testing.T) {
FILE: pkg/runner/local_repository_cache.go
type LocalRepositoryCache (line 19) | type LocalRepositoryCache struct
method Fetch (line 25) | func (l *LocalRepositoryCache) Fetch(ctx context.Context, cacheDir, ur...
method GetTarArchive (line 44) | func (l *LocalRepositoryCache) GetTarArchive(ctx context.Context, cach...
FILE: pkg/runner/logger.go
constant red (line 20) | red = 31
constant green (line 21) | green = 32
constant yellow (line 22) | yellow = 33
constant blue (line 23) | blue = 34
constant magenta (line 24) | magenta = 35
constant cyan (line 25) | cyan = 36
constant gray (line 26) | gray = 37
function init (line 33) | func init() {
type masksContextKey (line 40) | type masksContextKey
constant masksContextKeyVal (line 42) | masksContextKeyVal = masksContextKey("logrus.FieldLogger")
function Masks (line 45) | func Masks(ctx context.Context) *[]string {
function WithMasks (line 56) | func WithMasks(ctx context.Context, masks *[]string) context.Context {
type JobLoggerFactory (line 60) | type JobLoggerFactory interface
type jobLoggerFactoryContextKey (line 64) | type jobLoggerFactoryContextKey
function WithJobLoggerFactory (line 68) | func WithJobLoggerFactory(ctx context.Context, factory JobLoggerFactory)...
function WithJobLogger (line 73) | func WithJobLogger(ctx context.Context, jobID string, jobName string, co...
function WithCompositeLogger (line 113) | func WithCompositeLogger(ctx context.Context, masks *[]string) context.C...
function WithCompositeStepLogger (line 118) | func WithCompositeStepLogger(ctx context.Context, stepID string) context...
function withStepLogger (line 135) | func withStepLogger(ctx context.Context, stepID string, stepName string,...
type entryProcessor (line 144) | type entryProcessor
function valueMasker (line 146) | func valueMasker(insecureSecrets bool, secrets map[string]string) entryP...
type maskedFormatter (line 174) | type maskedFormatter struct
method Format (line 179) | func (f *maskedFormatter) Format(entry *logrus.Entry) ([]byte, error) {
type jobLogFormatter (line 183) | type jobLogFormatter struct
method Format (line 188) | func (f *jobLogFormatter) Format(entry *logrus.Entry) ([]byte, error) {
method printColored (line 201) | func (f *jobLogFormatter) printColored(b *bytes.Buffer, entry *logrus....
method print (line 225) | func (f *jobLogFormatter) print(b *bytes.Buffer, entry *logrus.Entry) {
method isColored (line 249) | func (f *jobLogFormatter) isColored(entry *logrus.Entry) bool {
function checkIfTerminal (line 263) | func checkIfTerminal(w io.Writer) bool {
FILE: pkg/runner/reusable_workflow.go
function newLocalReusableWorkflowExecutor (line 19) | func newLocalReusableWorkflowExecutor(rc *RunContext) common.Executor {
function newRemoteReusableWorkflowExecutor (line 23) | func newRemoteReusableWorkflowExecutor(rc *RunContext) common.Executor {
function newActionCacheReusableWorkflowExecutor (line 47) | func newActionCacheReusableWorkflowExecutor(rc *RunContext, filename str...
function newMutexExecutor (line 86) | func newMutexExecutor(executor common.Executor) common.Executor {
function cloneIfRequired (line 95) | func cloneIfRequired(rc *RunContext, remoteReusableWorkflow remoteReusab...
function newReusableWorkflowExecutor (line 116) | func newReusableWorkflowExecutor(rc *RunContext, directory string, workf...
function NewReusableWorkflowRunner (line 137) | func NewReusableWorkflowRunner(rc *RunContext) (Runner, error) {
type remoteReusableWorkflow (line 149) | type remoteReusableWorkflow struct
method CloneURL (line 157) | func (r *remoteReusableWorkflow) CloneURL() string {
function newRemoteReusableWorkflow (line 161) | func newRemoteReusableWorkflow(uses string) *remoteReusableWorkflow {
FILE: pkg/runner/run_context.go
type RunContext (line 32) | type RunContext struct
method AddMask (line 58) | func (rc *RunContext) AddMask(mask string) {
method String (line 67) | func (rc *RunContext) String() string {
method GetEnv (line 78) | func (rc *RunContext) GetEnv() map[string]string {
method jobContainerName (line 92) | func (rc *RunContext) jobContainerName() string {
method networkName (line 98) | func (rc *RunContext) networkName() (string, bool) {
method GetBindsAndMounts (line 127) | func (rc *RunContext) GetBindsAndMounts() ([]string, map[string]string) {
method startHostEnvironment (line 186) | func (rc *RunContext) startHostEnvironment() common.Executor {
method startJobContainer (line 255) | func (rc *RunContext) startJobContainer() common.Executor {
method execJobContainer (line 439) | func (rc *RunContext) execJobContainer(cmd []string, env map[string]st...
method InitializeNodeTool (line 445) | func (rc *RunContext) InitializeNodeTool() common.Executor {
method GetNodeToolFullPath (line 454) | func (rc *RunContext) GetNodeToolFullPath(ctx context.Context) string {
method ApplyExtraPath (line 489) | func (rc *RunContext) ApplyExtraPath(ctx context.Context, env *map[str...
method UpdateExtraPath (line 518) | func (rc *RunContext) UpdateExtraPath(ctx context.Context, githubEnvPa...
method stopJobContainer (line 553) | func (rc *RunContext) stopJobContainer() common.Executor {
method pullServicesImages (line 562) | func (rc *RunContext) pullServicesImages(forcePull bool) common.Execut...
method startServiceContainers (line 572) | func (rc *RunContext) startServiceContainers(_ string) common.Executor {
method waitForServiceContainer (line 586) | func (rc *RunContext) waitForServiceContainer(c container.ExecutionsEn...
method waitForServiceContainers (line 610) | func (rc *RunContext) waitForServiceContainers() common.Executor {
method stopServiceContainers (line 620) | func (rc *RunContext) stopServiceContainers() common.Executor {
method ActionCacheDir (line 633) | func (rc *RunContext) ActionCacheDir() string {
method interpolateOutputs (line 651) | func (rc *RunContext) interpolateOutputs() common.Executor {
method startContainer (line 664) | func (rc *RunContext) startContainer() common.Executor {
method IsHostEnv (line 675) | func (rc *RunContext) IsHostEnv(ctx context.Context) bool {
method stopContainer (line 681) | func (rc *RunContext) stopContainer() common.Executor {
method closeContainer (line 685) | func (rc *RunContext) closeContainer() common.Executor {
method matrix (line 694) | func (rc *RunContext) matrix() map[string]interface{} {
method result (line 698) | func (rc *RunContext) result(result string) {
method steps (line 702) | func (rc *RunContext) steps() []*model.Step {
method Executor (line 707) | func (rc *RunContext) Executor() (common.Executor, error) {
method containerImage (line 734) | func (rc *RunContext) containerImage(ctx context.Context) string {
method runsOnImage (line 745) | func (rc *RunContext) runsOnImage(ctx context.Context) string {
method runsOnPlatformNames (line 760) | func (rc *RunContext) runsOnPlatformNames(ctx context.Context) []string {
method platformImage (line 775) | func (rc *RunContext) platformImage(ctx context.Context) string {
method options (line 783) | func (rc *RunContext) options(ctx context.Context) string {
method isEnabled (line 793) | func (rc *RunContext) isEnabled(ctx context.Context) (bool, error) {
method getJobContext (line 860) | func (rc *RunContext) getJobContext() *model.JobContext {
method getStepsContext (line 877) | func (rc *RunContext) getStepsContext() map[string]*model.StepResult {
method getGithubContext (line 881) | func (rc *RunContext) getGithubContext(ctx context.Context) *model.Git...
method withGithubEnv (line 1027) | func (rc *RunContext) withGithubEnv(ctx context.Context, github *model...
method handleCredentials (line 1096) | func (rc *RunContext) handleCredentials(ctx context.Context) (string, ...
method handleServiceCredentials (line 1129) | func (rc *RunContext) handleServiceCredentials(ctx context.Context, cr...
method GetServiceBindsAndMounts (line 1153) | func (rc *RunContext) GetServiceBindsAndMounts(svcVolumes []string) ([...
type MappableOutput (line 62) | type MappableOutput struct
function getDockerDaemonSocketMountPath (line 108) | func getDockerDaemonSocketMountPath(daemonPath string) string {
function mergeMaps (line 827) | func mergeMaps(maps ...map[string]string) map[string]string {
function createContainerName (line 837) | func createContainerName(parts ...string) string {
function trimToLen (line 850) | func trimToLen(s string, l int) string {
function isLocalCheckout (line 984) | func isLocalCheckout(ghc *model.GithubContext, step *model.Step) bool {
function nestedMapLookup (line 1010) | func nestedMapLookup(m map[string]interface{}, ks ...string) (rval inter...
function setActionRuntimeVars (line 1077) | func setActionRuntimeVars(rc *RunContext, env map[string]string) {
FILE: pkg/runner/run_context_test.go
function TestRunContext_EvalBool (line 22) | func TestRunContext_EvalBool(t *testing.T) {
function updateTestIfWorkflow (line 170) | func updateTestIfWorkflow(t *testing.T, tables []struct {
function TestRunContext_GetBindsAndMounts (line 231) | func TestRunContext_GetBindsAndMounts(t *testing.T) {
function TestGetGitHubContext (line 340) | func TestGetGitHubContext(t *testing.T) {
function TestGetGithubContextRef (line 396) | func TestGetGithubContextRef(t *testing.T) {
function createIfTestRunContext (line 437) | func createIfTestRunContext(jobs map[string]*model.Job) *RunContext {
function createJob (line 459) | func createJob(t *testing.T, input string, result string) *model.Job {
function TestRunContextRunsOnPlatformNames (line 468) | func TestRunContextRunsOnPlatformNames(t *testing.T) {
function TestRunContextIsEnabled (line 515) | func TestRunContextIsEnabled(t *testing.T) {
function TestRunContextGetEnv (line 630) | func TestRunContextGetEnv(t *testing.T) {
function TestSetRuntimeVariables (line 681) | func TestSetRuntimeVariables(t *testing.T) {
function TestSetRuntimeVariablesWithRunID (line 702) | func TestSetRuntimeVariablesWithRunID(t *testing.T) {
FILE: pkg/runner/runner.go
type Runner (line 17) | type Runner interface
type Config (line 22) | type Config struct
method GetConcurrentJobs (line 67) | func (config *Config) GetConcurrentJobs() int {
type caller (line 80) | type caller struct
type runnerImpl (line 84) | type runnerImpl struct
method configure (line 99) | func (runner *runnerImpl) configure() (Runner, error) {
method NewPlanExecutor (line 122) | func (runner *runnerImpl) NewPlanExecutor(plan *model.Plan) common.Exe...
method newRunContext (line 253) | func (runner *runnerImpl) newRunContext(ctx context.Context, run *mode...
function New (line 91) | func New(runnerConfig *Config) (Runner, error) {
function handleFailure (line 221) | func handleFailure(plan *model.Plan) common.Executor {
function selectMatrixes (line 234) | func selectMatrixes(originalMatrixes []map[string]interface{}, targetMat...
FILE: pkg/runner/runner_test.go
function init (line 35) | func init() {
function TestNoWorkflowsFoundByPlanner (line 58) | func TestNoWorkflowsFoundByPlanner(t *testing.T) {
function TestGraphMissingEvent (line 78) | func TestGraphMissingEvent(t *testing.T) {
function TestGraphMissingFirst (line 96) | func TestGraphMissingFirst(t *testing.T) {
function TestGraphWithMissing (line 106) | func TestGraphWithMissing(t *testing.T) {
function TestGraphWithSomeMissing (line 123) | func TestGraphWithSomeMissing(t *testing.T) {
function TestGraphEvent (line 143) | func TestGraphEvent(t *testing.T) {
type TestJobFileInfo (line 165) | type TestJobFileInfo struct
method runTest (line 174) | func (j *TestJobFileInfo) runTest(ctx context.Context, t *testing.T, c...
type TestConfig (line 221) | type TestConfig struct
function TestRunEvent (line 225) | func TestRunEvent(t *testing.T) {
type captureJobLoggerFactory (line 371) | type captureJobLoggerFactory struct
method WithJobLogger (line 375) | func (factory *captureJobLoggerFactory) WithJobLogger() *logrus.Logger {
function TestPullAndPostStepFailureIsJobFailure (line 383) | func TestPullAndPostStepFailureIsJobFailure(t *testing.T) {
type mockCache (line 445) | type mockCache struct
method Fetch (line 448) | func (c mockCache) Fetch(ctx context.Context, cacheDir string, url str...
method GetTarArchive (line 456) | func (c mockCache) GetTarArchive(ctx context.Context, cacheDir string,...
function TestFetchFailureIsJobFailure (line 464) | func TestFetchFailureIsJobFailure(t *testing.T) {
function TestRunEventHostEnvironment (line 510) | func TestRunEventHostEnvironment(t *testing.T) {
function TestDryrunEvent (line 610) | func TestDryrunEvent(t *testing.T) {
function TestDockerActionForcePullForceRebuild (line 639) | func TestDockerActionForcePullForceRebuild(t *testing.T) {
function TestRunDifferentArchitecture (line 663) | func TestRunDifferentArchitecture(t *testing.T) {
type maskJobLoggerFactory (line 679) | type maskJobLoggerFactory struct
method WithJobLogger (line 683) | func (f *maskJobLoggerFactory) WithJobLogger() *log.Logger {
function TestMaskValues (line 690) | func TestMaskValues(t *testing.T) {
function TestRunEventSecrets (line 721) | func TestRunEventSecrets(t *testing.T) {
function TestRunActionInputs (line 743) | func TestRunActionInputs(t *testing.T) {
function TestRunEventPullRequest (line 764) | func TestRunEventPullRequest(t *testing.T) {
function TestRunMatrixWithUserDefinedInclusions (line 782) | func TestRunMatrixWithUserDefinedInclusions(t *testing.T) {
FILE: pkg/runner/step.go
type step (line 21) | type step interface
type stepStage (line 33) | type stepStage
method String (line 44) | func (s stepStage) String() string {
constant stepStagePre (line 36) | stepStagePre stepStage = iota
constant stepStageMain (line 37) | stepStageMain
constant stepStagePost (line 38) | stepStagePost
constant maxSymlinkDepth (line 42) | maxSymlinkDepth = 10
function processRunnerSummaryCommand (line 56) | func processRunnerSummaryCommand(ctx context.Context, fileName string, r...
function processRunnerEnvFileCommand (line 82) | func processRunnerEnvFileCommand(ctx context.Context, fileName string, r...
function runStepExecutor (line 94) | func runStepExecutor(step step, stage stepStage, executor common.Executo...
function monitorJobCancellation (line 217) | func monitorJobCancellation(ctx context.Context, stepCtx context.Context...
function evaluateStepTimeout (line 235) | func evaluateStepTimeout(ctx context.Context, exprEval ExpressionEvaluat...
function setupEnv (line 245) | func setupEnv(ctx context.Context, step step) error {
function mergeEnv (line 272) | func mergeEnv(ctx context.Context, step step) {
function isStepEnabled (line 297) | func isStepEnabled(ctx context.Context, expr string, step step, stage st...
function isContinueOnError (line 315) | func isContinueOnError(ctx context.Context, expr string, step step, _ st...
function mergeIntoMap (line 331) | func mergeIntoMap(step step, target *map[string]string, maps ...map[stri...
function mergeIntoMapCaseSensitive (line 339) | func mergeIntoMapCaseSensitive(target map[string]string, maps ...map[str...
function mergeIntoMapCaseInsensitive (line 347) | func mergeIntoMapCaseInsensitive(target map[string]string, maps ...map[s...
function symlinkJoin (line 367) | func symlinkJoin(filename, sym, parent string) (string, error) {
FILE: pkg/runner/step_action_local.go
type stepActionLocal (line 18) | type stepActionLocal struct
method pre (line 29) | func (sal *stepActionLocal) pre() common.Executor {
method main (line 37) | func (sal *stepActionLocal) main() common.Executor {
method post (line 87) | func (sal *stepActionLocal) post() common.Executor {
method getRunContext (line 91) | func (sal *stepActionLocal) getRunContext() *RunContext {
method getGithubContext (line 95) | func (sal *stepActionLocal) getGithubContext(ctx context.Context) *mod...
method getStepModel (line 99) | func (sal *stepActionLocal) getStepModel() *model.Step {
method getEnv (line 103) | func (sal *stepActionLocal) getEnv() *map[string]string {
method getIfExpression (line 107) | func (sal *stepActionLocal) getIfExpression(_ context.Context, stage s...
method getActionModel (line 117) | func (sal *stepActionLocal) getActionModel() *model.Action {
method getCompositeRunContext (line 121) | func (sal *stepActionLocal) getCompositeRunContext(ctx context.Context...
method getCompositeSteps (line 132) | func (sal *stepActionLocal) getCompositeSteps() *compositeSteps {
FILE: pkg/runner/step_action_local_test.go
type stepActionLocalMocks (line 18) | type stepActionLocalMocks struct
method runAction (line 22) | func (salm *stepActionLocalMocks) runAction(step actionStep, actionDir...
method readAction (line 27) | func (salm *stepActionLocalMocks) readAction(_ context.Context, step *...
function TestStepActionLocalTest (line 32) | func TestStepActionLocalTest(t *testing.T) {
function TestStepActionLocalPost (line 105) | func TestStepActionLocalPost(t *testing.T) {
FILE: pkg/runner/step_action_remote.go
type stepActionRemote (line 22) | type stepActionRemote struct
method prepareActionExecutor (line 40) | func (sar *stepActionRemote) prepareActionExecutor() common.Executor {
method pre (line 147) | func (sar *stepActionRemote) pre() common.Executor {
method main (line 155) | func (sar *stepActionRemote) main() common.Executor {
method post (line 177) | func (sar *stepActionRemote) post() common.Executor {
method getRunContext (line 181) | func (sar *stepActionRemote) getRunContext() *RunContext {
method getGithubContext (line 185) | func (sar *stepActionRemote) getGithubContext(ctx context.Context) *mo...
method getStepModel (line 198) | func (sar *stepActionRemote) getStepModel() *model.Step {
method getEnv (line 202) | func (sar *stepActionRemote) getEnv() *map[string]string {
method getIfExpression (line 206) | func (sar *stepActionRemote) getIfExpression(ctx context.Context, stag...
method getActionModel (line 223) | func (sar *stepActionRemote) getActionModel() *model.Action {
method getCompositeRunContext (line 227) | func (sar *stepActionRemote) getCompositeRunContext(ctx context.Contex...
method getCompositeSteps (line 249) | func (sar *stepActionRemote) getCompositeSteps() *compositeSteps {
type remoteAction (line 253) | type remoteAction struct
method CloneURL (line 261) | func (ra *remoteAction) CloneURL() string {
method IsCheckout (line 265) | func (ra *remoteAction) IsCheckout() bool {
function newRemoteAction (line 272) | func newRemoteAction(action string) *remoteAction {
function safeFilename (line 292) | func safeFilename(s string) string {
FILE: pkg/runner/step_action_remote_test.go
type stepActionRemoteMocks (line 20) | type stepActionRemoteMocks struct
method readAction (line 24) | func (sarm *stepActionRemoteMocks) readAction(_ context.Context, step ...
method runAction (line 29) | func (sarm *stepActionRemoteMocks) runAction(step actionStep, actionDi...
function TestStepActionRemote (line 34) | func TestStepActionRemote(t *testing.T) {
function TestStepActionRemotePre (line 209) | func TestStepActionRemotePre(t *testing.T) {
function TestStepActionRemotePreThroughAction (line 276) | func TestStepActionRemotePreThroughAction(t *testing.T) {
function TestStepActionRemotePreThroughActionToken (line 346) | func TestStepActionRemotePreThroughActionToken(t *testing.T) {
function TestStepActionRemotePost (line 417) | func TestStepActionRemotePost(t *testing.T) {
function Test_safeFilename (line 622) | func Test_safeFilename(t *testing.T) {
FILE: pkg/runner/step_docker.go
type stepDocker (line 14) | type stepDocker struct
method pre (line 20) | func (sd *stepDocker) pre() common.Executor {
method main (line 26) | func (sd *stepDocker) main() common.Executor {
method post (line 32) | func (sd *stepDocker) post() common.Executor {
method getRunContext (line 38) | func (sd *stepDocker) getRunContext() *RunContext {
method getGithubContext (line 42) | func (sd *stepDocker) getGithubContext(ctx context.Context) *model.Git...
method getStepModel (line 46) | func (sd *stepDocker) getStepModel() *model.Step {
method getEnv (line 50) | func (sd *stepDocker) getEnv() *map[string]string {
method getIfExpression (line 54) | func (sd *stepDocker) getIfExpression(_ context.Context, _ stepStage) ...
method runUsesContainer (line 58) | func (sd *stepDocker) runUsesContainer() common.Executor {
method newStepContainer (line 92) | func (sd *stepDocker) newStepContainer(ctx context.Context, image stri...
FILE: pkg/runner/step_docker_test.go
function TestStepDockerMain (line 15) | func TestStepDockerMain(t *testing.T) {
function TestStepDockerPrePost (line 107) | func TestStepDockerPrePost(t *testing.T) {
FILE: pkg/runner/step_factory.go
type stepFactory (line 9) | type stepFactory interface
type stepFactoryImpl (line 13) | type stepFactoryImpl struct
method newStep (line 15) | func (sf *stepFactoryImpl) newStep(stepModel *model.Step, rc *RunConte...
FILE: pkg/runner/step_factory_test.go
function TestStepFactoryNewStep (line 10) | func TestStepFactoryNewStep(t *testing.T) {
function TestStepFactoryInvalidStep (line 70) | func TestStepFactoryInvalidStep(t *testing.T) {
FILE: pkg/runner/step_run.go
type stepRun (line 17) | type stepRun struct
method pre (line 26) | func (sr *stepRun) pre() common.Executor {
method main (line 32) | func (sr *stepRun) main() common.Executor {
method post (line 46) | func (sr *stepRun) post() common.Executor {
method getRunContext (line 52) | func (sr *stepRun) getRunContext() *RunContext {
method getGithubContext (line 56) | func (sr *stepRun) getGithubContext(ctx context.Context) *model.Github...
method getStepModel (line 60) | func (sr *stepRun) getStepModel() *model.Step {
method getEnv (line 64) | func (sr *stepRun) getEnv() *map[string]string {
method getIfExpression (line 68) | func (sr *stepRun) getIfExpression(_ context.Context, _ stepStage) str...
method setupShellCommandExecutor (line 72) | func (sr *stepRun) setupShellCommandExecutor() common.Executor {
method setupShellCommand (line 101) | func (sr *stepRun) setupShellCommand(ctx context.Context) (name, scrip...
method setupShell (line 164) | func (sr *stepRun) setupShell(ctx context.Context) {
method setupWorkingDirectory (line 206) | func (sr *stepRun) setupWorkingDirectory(ctx context.Context) {
function getScriptName (line 88) | func getScriptName(rc *RunContext, step *model.Step) string {
type localEnv (line 148) | type localEnv struct
method Getenv (line 152) | func (l *localEnv) Getenv(name string) string {
FILE: pkg/runner/step_run_test.go
function TestStepRun (line 16) | func TestStepRun(t *testing.T) {
function TestStepRunPrePost (line 86) | func TestStepRunPrePost(t *testing.T) {
FILE: pkg/runner/step_test.go
function TestMergeIntoMap (line 15) | func TestMergeIntoMap(t *testing.T) {
type stepMock (line 74) | type stepMock struct
method pre (line 79) | func (sm *stepMock) pre() common.Executor {
method main (line 84) | func (sm *stepMock) main() common.Executor {
method post (line 89) | func (sm *stepMock) post() common.Executor {
method getRunContext (line 94) | func (sm *stepMock) getRunContext() *RunContext {
method getGithubContext (line 99) | func (sm *stepMock) getGithubContext(ctx context.Context) *model.Githu...
method getStepModel (line 104) | func (sm *stepMock) getStepModel() *model.Step {
method getEnv (line 109) | func (sm *stepMock) getEnv() *map[string]string {
function TestSetupEnv (line 114) | func TestSetupEnv(t *testing.T) {
function TestIsStepEnabled (line 197) | func TestIsStepEnabled(t *testing.T) {
function TestIsContinueOnError (line 279) | func TestIsContinueOnError(t *testing.T) {
FILE: pkg/runner/testdata/actions-environment-and-context-tests/js/index.js
function checkEnvVar (line 1) | function checkEnvVar({ name, allowEmpty }) {
FILE: pkg/runner/testdata/actions/node12/dist/index.js
function issueCommand (line 51) | function issueCommand(command, properties, message) {
function issue (line 56) | function issue(name, message = '') {
class Command (line 61) | class Command {
method constructor (line 62) | constructor(command, properties, message) {
method toString (line 70) | toString() {
function escapeData (line 94) | function escapeData(s) {
function escapeProperty (line 100) | function escapeProperty(s) {
function adopt (line 118) | function adopt(value) { return value instanceof P ? value : new P(functi...
function fulfilled (line 120) | function fulfilled(value) { try { step(generator.next(value)); } catch (...
function rejected (line 121) | function rejected(value) { try { step(generator["throw"](value)); } catc...
function step (line 122) | function step(result) { result.done ? resolve(result.value) : adopt(resu...
function exportVariable (line 162) | function exportVariable(name, val) {
function setSecret (line 180) | function setSecret(secret) {
function addPath (line 188) | function addPath(inputPath) {
function getInput (line 206) | function getInput(name, options) {
function setOutput (line 221) | function setOutput(name, value) {
function setCommandEcho (line 230) | function setCommandEcho(enabled) {
function setFailed (line 242) | function setFailed(message) {
function isDebug (line 253) | function isDebug() {
function debug (line 261) | function debug(message) {
function error (line 269) | function error(message) {
function warning (line 277) | function warning(message) {
function info (line 285) | function info(message) {
function startGroup (line 296) | function startGroup(name) {
function endGroup (line 303) | function endGroup() {
function group (line 315) | function group(name, fn) {
function saveState (line 339) | function saveState(name, value) {
function getState (line 349) | function getState(name) {
function issueCommand (line 376) | function issueCommand(command, message) {
function toCommandValue (line 405) | function toCommandValue(input) {
class Context (line 428) | class Context {
method constructor (line 432) | constructor() {
method issue (line 453) | get issue() {
method repo (line 457) | get repo() {
function getOctokit (line 511) | function getOctokit(token, options) {
function getAuthString (line 546) | function getAuthString(token, options) {
function getProxyAgent (line 556) | function getProxyAgent(destinationUrl) {
function getApiBaseUrl (line 561) | function getApiBaseUrl() {
function getOctokitOptions (line 616) | function getOctokitOptions(token, options) {
function getProxyUrl (line 684) | function getProxyUrl(serverUrl) {
class HttpClientResponse (line 704) | class HttpClientResponse {
method constructor (line 705) | constructor(message) {
method readBody (line 708) | readBody() {
function isHttps (line 721) | function isHttps(requestUrl) {
class HttpClient (line 726) | class HttpClient {
method constructor (line 727) | constructor(userAgent, handlers, requestOptions) {
method options (line 764) | options(requestUrl, additionalHeaders) {
method get (line 767) | get(requestUrl, additionalHeaders) {
method del (line 770) | del(requestUrl, additionalHeaders) {
method post (line 773) | post(requestUrl, data, additionalHeaders) {
method patch (line 776) | patch(requestUrl, data, additionalHeaders) {
method put (line 779) | put(requestUrl, data, additionalHeaders) {
method head (line 782) | head(requestUrl, additionalHeaders) {
method sendStream (line 785) | sendStream(verb, requestUrl, stream, additionalHeaders) {
method getJson (line 792) | async getJson(requestUrl, additionalHeaders = {}) {
method postJson (line 797) | async postJson(requestUrl, obj, additionalHeaders = {}) {
method putJson (line 804) | async putJson(requestUrl, obj, additionalHeaders = {}) {
method patchJson (line 811) | async patchJson(requestUrl, obj, additionalHeaders = {}) {
method request (line 823) | async request(verb, requestUrl, data, headers) {
method dispose (line 904) | dispose() {
method requestRaw (line 915) | requestRaw(info, data) {
method requestRawWithCallback (line 932) | requestRawWithCallback(info, data, onResult) {
method getAgent (line 981) | getAgent(serverUrl) {
method _prepareRequest (line 985) | _prepareRequest(method, requestUrl, headers) {
method _mergeHeaders (line 1012) | _mergeHeaders(headers) {
method _getExistingOrDefaultHeader (line 1019) | _getExistingOrDefaultHeader(additionalHeaders, header, _default) {
method _getAgent (line 1027) | _getAgent(parsedUrl) {
method _performExponentialBackoff (line 1091) | _performExponentialBackoff(retryNumber) {
method dateTimeDeserializer (line 1096) | static dateTimeDeserializer(key, value) {
method _processResponse (line 1105) | async _processResponse(res, options) {
function getProxyUrl (line 1176) | function getProxyUrl(reqUrl) {
function checkBypass (line 1195) | function checkBypass(reqUrl) {
function auth (line 1243) | async function auth(token) {
function withAuthorizationPrefix (line 1257) | function withAuthorizationPrefix(token) {
function hook (line 1265) | async function hook(token, request, route, parameters) {
function _defineProperty (line 1306) | function _defineProperty(obj, key, value) {
function ownKeys (line 1321) | function ownKeys(object, enumerableOnly) {
function _objectSpread2 (line 1335) | function _objectSpread2(target) {
class Octokit (line 1357) | class Octokit {
method constructor (line 1358) | constructor(options = {}) {
method defaults (line 1432) | static defaults(defaults) {
method plugin (line 1458) | static plugin(...newPlugins) {
function lowercaseKeys (line 1487) | function lowercaseKeys(object) {
function mergeDeep (line 1498) | function mergeDeep(defaults, options) {
function merge (line 1514) | function merge(defaults, route, options) {
function addQueryParameters (line 1539) | function addQueryParameters(url, parameters) {
function removeNonChars (line 1558) | function removeNonChars(variableName) {
function extractUrlVariableNames (line 1562) | function extractUrlVariableNames(url) {
function omit (line 1572) | function omit(object, keysToOmit) {
function encodeReserved (line 1606) | function encodeReserved(str) {
function encodeUnreserved (line 1616) | function encodeUnreserved(str) {
function encodeValue (line 1622) | function encodeValue(operator, value, key) {
function isDefined (line 1632) | function isDefined(value) {
function isKeyOperator (line 1636) | function isKeyOperator(operator) {
function getValues (line 1640) | function getValues(context, operator, key, modifier) {
function parseUrl (line 1704) | function parseUrl(template) {
function expand (line 1710) | function expand(template, context) {
function parse (line 1746) | function parse(options) {
function endpointWithDefaults (line 1820) | function endpointWithDefaults(defaults, route, options) {
function withDefaults (line 1824) | function withDefaults(oldDefaults, newDefaults) {
class GraphqlError (line 1874) | class GraphqlError extends Error {
method constructor (line 1875) | constructor(request, response) {
function graphql (line 1896) | function graphql(request, query, options) {
function withDefaults (line 1943) | function withDefaults(request$1, newDefaults) {
function withCustomRequest (line 1963) | function withCustomRequest(customRequest) {
function normalizePaginatedListResponse (line 2003) | function normalizePaginatedListResponse(response) {
function iterator (line 2030) | function iterator(octokit, route, parameters) {
function paginate (line 2064) | function paginate(octokit, route, parameters, mapFn) {
function gather (line 2073) | function gather(octokit, results, iterator, mapFn) {
function paginateRest (line 2100) | function paginateRest(octokit) {
function endpointsToMethods (line 3174) | function endpointsToMethods(octokit, endpointsMap) {
function decorate (line 3204) | function decorate(octokit, scope, methodName, defaults, decorations) {
function restEndpointMethods (line 3266) | function restEndpointMethods(octokit) {
function _interopDefault (line 3285) | function _interopDefault (ex) { return (ex && (typeof ex === 'object') &...
class RequestError (line 3295) | class RequestError extends Error {
method constructor (line 3296) | constructor(message, statusCode, options) {
function _interopDefault (line 3348) | function _interopDefault (ex) { return (ex && (typeof ex === 'object') &...
function getBufferResponse (line 3358) | function getBufferResponse(response) {
function fetchWrapper (line 3362) | function fetchWrapper(requestOptions) {
function withDefaults (line 3457) | function withDefaults(oldEndpoint, newDefaults) {
function bindApi (line 3507) | function bindApi (hook, state, name) {
function HookSingular (line 3518) | function HookSingular () {
function HookCollection (line 3528) | function HookCollection () {
function Hook (line 3540) | function Hook () {
function addHook (line 3565) | function addHook (state, kind, name, hook) {
function register (line 3618) | function register (state, name, method, options) {
function removeHook (line 3653) | function removeHook (state, name, method) {
class Deprecation (line 3680) | class Deprecation extends Error {
method constructor (line 3681) | constructor(message) {
function isObject (line 3715) | function isObject(o) {
function isPlainObject (line 3719) | function isPlainObject(o) {
function _interopDefault (line 3754) | function _interopDefault (ex) { return (ex && (typeof ex === 'object') &...
class Blob (line 3770) | class Blob {
method constructor (line 3771) | constructor() {
method size (line 3809) | get size() {
method type (line 3812) | get type() {
method text (line 3815) | text() {
method arrayBuffer (line 3818) | arrayBuffer() {
method stream (line 3823) | stream() {
method toString (line 3830) | toString() {
method slice (line 3833) | slice() {
function FetchError (line 3890) | function FetchError(message, type, systemError) {
function Body (line 3928) | function Body(body) {
method body (line 3972) | get body() {
method bodyUsed (line 3976) | get bodyUsed() {
method arrayBuffer (line 3985) | arrayBuffer() {
method blob (line 3996) | blob() {
method json (line 4014) | json() {
method text (line 4031) | text() {
method buffer (line 4042) | buffer() {
method textConverted (line 4052) | textConverted() {
function consumeBody (line 4088) | function consumeBody() {
function convertBody (line 4192) | function convertBody(buffer, headers) {
function isURLSearchParams (line 4256) | function isURLSearchParams(obj) {
function isBlob (line 4271) | function isBlob(obj) {
function clone (line 4281) | function clone(instance) {
function extractContentType (line 4315) | function extractContentType(body) {
function getTotalBytes (line 4359) | function getTotalBytes(instance) {
function writeToStream (line 4391) | function writeToStream(dest, instance) {
function validateName (line 4422) | function validateName(name) {
function validateValue (line 4429) | function validateValue(value) {
function find (line 4444) | function find(map, name) {
class Headers (line 4455) | class Headers {
method constructor (line 4462) | constructor() {
method get (line 4523) | get(name) {
method forEach (line 4541) | forEach(callback) {
method set (line 4564) | set(name, value) {
method append (line 4580) | append(name, value) {
method has (line 4599) | has(name) {
method delete (line 4611) | delete(name) {
method raw (line 4625) | raw() {
method keys (line 4634) | keys() {
method values (line 4643) | values() {
method [Symbol.iterator] (line 4654) | [Symbol.iterator]() {
function getHeaders (line 4679) | function getHeaders(headers) {
function createHeadersIterator (line 4694) | function createHeadersIterator(target, kind) {
method next (line 4705) | next() {
function exportNodeCompatibleHeaders (line 4747) | function exportNodeCompatibleHeaders(headers) {
function createHeadersLenient (line 4767) | function createHeadersLenient(obj) {
class Response (line 4803) | class Response {
method constructor (line 4804) | constructor() {
method url (line 4829) | get url() {
method status (line 4833) | get status() {
method ok (line 4840) | get ok() {
method redirected (line 4844) | get redirected() {
method statusText (line 4848) | get statusText() {
method headers (line 4852) | get headers() {
method clone (line 4861) | clone() {
function isRequest (line 4906) | function isRequest(input) {
function isAbortSignal (line 4910) | function isAbortSignal(signal) {
class Request (line 4922) | class Request {
method constructor (line 4923) | constructor(input) {
method method (line 4989) | get method() {
method url (line 4993) | get url() {
method headers (line 4997) | get headers() {
method redirect (line 5001) | get redirect() {
method signal (line 5005) | get signal() {
method clone (line 5014) | clone() {
function getNodeRequestOptions (line 5043) | function getNodeRequestOptions(request) {
function AbortError (line 5121) | function AbortError(message) {
function fetch (line 5146) | function fetch(url, opts) {
function once (line 5426) | function once (fn) {
function onceStrict (line 5436) | function onceStrict (fn) {
function httpOverHttp (line 5481) | function httpOverHttp(options) {
function httpsOverHttp (line 5487) | function httpsOverHttp(options) {
function httpOverHttps (line 5495) | function httpOverHttps(options) {
function httpsOverHttps (line 5501) | function httpsOverHttps(options) {
function TunnelingAgent (line 5510) | function TunnelingAgent(options) {
function onFree (line 5553) | function onFree() {
function onCloseOrRemove (line 5557) | function onCloseOrRemove(err) {
function onResponse (line 5597) | function onResponse(res) {
function onUpgrade (line 5602) | function onUpgrade(res, socket, head) {
function onConnect (line 5609) | function onConnect(res, socket, head) {
function onError (line 5638) | function onError(cause) {
function createSecureSocket (line 5668) | function createSecureSocket(options, cb) {
function toOptions (line 5685) | function toOptions(host, port, localAddress) {
function mergeOptions (line 5696) | function mergeOptions(target) {
function getUserAgent (line 5740) | function getUserAgent() {
function wrappy (line 5767) | function wrappy (fn, cb) {
function __webpack_require__ (line 5916) | function __webpack_require__(moduleId) {
FILE: pkg/runner/testdata/actions/node16/dist/index.js
function issueCommand (line 64) | function issueCommand(command, properties, message) {
function issue (line 69) | function issue(name, message = '') {
class Command (line 74) | class Command {
method constructor (line 75) | constructor(command, properties, message) {
method toString (line 83) | toString() {
function escapeData (line 107) | function escapeData(s) {
function escapeProperty (line 113) | function escapeProperty(s) {
function adopt (line 150) | function adopt(value) { return value instanceof P ? value : new P(functi...
function fulfilled (line 152) | function fulfilled(value) { try { step(generator.next(value)); } catch (...
function rejected (line 153) | function rejected(value) { try { step(generator["throw"](value)); } catc...
function step (line 154) | function step(result) { result.done ? resolve(result.value) : adopt(resu...
function exportVariable (line 189) | function exportVariable(name, val) {
function setSecret (line 207) | function setSecret(secret) {
function addPath (line 215) | function addPath(inputPath) {
function getInput (line 235) | function getInput(name, options) {
function getMultilineInput (line 254) | function getMultilineInput(name, options) {
function getBooleanInput (line 271) | function getBooleanInput(name, options) {
function setOutput (line 290) | function setOutput(name, value) {
function setCommandEcho (line 300) | function setCommandEcho(enabled) {
function setFailed (line 312) | function setFailed(message) {
function isDebug (line 323) | function isDebug() {
function debug (line 331) | function debug(message) {
function error (line 340) | function error(message, properties = {}) {
function warning (line 349) | function warning(message, properties = {}) {
function notice (line 358) | function notice(message, properties = {}) {
function info (line 366) | function info(message) {
function startGroup (line 377) | function startGroup(name) {
function endGroup (line 384) | function endGroup() {
function group (line 396) | function group(name, fn) {
function saveState (line 420) | function saveState(name, value) {
function getState (line 430) | function getState(name) {
function getIDToken (line 434) | function getIDToken(aud) {
function issueCommand (line 476) | function issueCommand(command, message) {
function adopt (line 499) | function adopt(value) { return value instanceof P ? value : new P(functi...
function fulfilled (line 501) | function fulfilled(value) { try { step(generator.next(value)); } catch (...
function rejected (line 502) | function rejected(value) { try { step(generator["throw"](value)); } catc...
function step (line 503) | function step(result) { result.done ? resolve(result.value) : adopt(resu...
class OidcClient (line 512) | class OidcClient {
method createHttpClient (line 513) | static createHttpClient(allowRetry = true, maxRetry = 10) {
method getRequestToken (line 520) | static getRequestToken() {
method getIDTokenUrl (line 527) | static getIDTokenUrl() {
method getCall (line 534) | static getCall(id_token_url) {
method getIDToken (line 552) | static getIDToken(audience) {
function toCommandValue (line 590) | function toCommandValue(input) {
function toCommandProperties (line 606) | function toCommandProperties(annotationProperties) {
class Context (line 633) | class Context {
method constructor (line 637) | constructor() {
method issue (line 658) | get issue() {
method repo (line 662) | get repo() {
function getOctokit (line 716) | function getOctokit(token, options) {
function getAuthString (line 751) | function getAuthString(token, options) {
function getProxyAgent (line 761) | function getProxyAgent(destinationUrl) {
function getApiBaseUrl (line 766) | function getApiBaseUrl() {
function getOctokitOptions (line 821) | function getOctokitOptions(token, options) {
class BasicCredentialHandler (line 841) | class BasicCredentialHandler {
method constructor (line 842) | constructor(username, password) {
method prepareRequest (line 846) | prepareRequest(options) {
method canHandleAuthentication (line 852) | canHandleAuthentication(response) {
method handleAuthentication (line 855) | handleAuthentication(httpClient, requestInfo, objs) {
class BearerCredentialHandler (line 860) | class BearerCredentialHandler {
method constructor (line 861) | constructor(token) {
method prepareRequest (line 866) | prepareRequest(options) {
method canHandleAuthentication (line 870) | canHandleAuthentication(response) {
method handleAuthentication (line 873) | handleAuthentication(httpClient, requestInfo, objs) {
class PersonalAccessTokenCredentialHandler (line 878) | class PersonalAccessTokenCredentialHandler {
method constructor (line 879) | constructor(token) {
method prepareRequest (line 884) | prepareRequest(options) {
method canHandleAuthentication (line 889) | canHandleAuthentication(response) {
method handleAuthentication (line 892) | handleAuthentication(httpClient, requestInfo, objs) {
function getProxyUrl (line 954) | function getProxyUrl(serverUrl) {
class HttpClientError (line 974) | class HttpClientError extends Error {
method constructor (line 975) | constructor(message, statusCode) {
class HttpClientResponse (line 983) | class HttpClientResponse {
method constructor (line 984) | constructor(message) {
method readBody (line 987) | readBody() {
function isHttps (line 1000) | function isHttps(requestUrl) {
class HttpClient (line 1005) | class HttpClient {
method constructor (line 1006) | constructor(userAgent, handlers, requestOptions) {
method options (line 1043) | options(requestUrl, additionalHeaders) {
method get (line 1046) | get(requestUrl, additionalHeaders) {
method del (line 1049) | del(requestUrl, additionalHeaders) {
method post (line 1052) | post(requestUrl, data, additionalHeaders) {
method patch (line 1055) | patch(requestUrl, data, additionalHeaders) {
method put (line 1058) | put(requestUrl, data, additionalHeaders) {
method head (line 1061) | head(requestUrl, additionalHeaders) {
method sendStream (line 1064) | sendStream(verb, requestUrl, stream, additionalHeaders) {
method getJson (line 1071) | async getJson(requestUrl, additionalHeaders = {}) {
method postJson (line 1076) | async postJson(requestUrl, obj, additionalHeaders = {}) {
method putJson (line 1083) | async putJson(requestUrl, obj, additionalHeaders = {}) {
method patchJson (line 1090) | async patchJson(requestUrl, obj, additionalHeaders = {}) {
method request (line 1102) | async request(verb, requestUrl, data, headers) {
method dispose (line 1183) | dispose() {
method requestRaw (line 1194) | requestRaw(info, data) {
method requestRawWithCallback (line 1211) | requestRawWithCallback(info, data, onResult) {
method getAgent (line 1260) | getAgent(serverUrl) {
method _prepareRequest (line 1264) | _prepareRequest(method, requestUrl, headers) {
method _mergeHeaders (line 1291) | _mergeHeaders(headers) {
method _getExistingOrDefaultHeader (line 1298) | _getExistingOrDefaultHeader(additionalHeaders, header, _default) {
method _getAgent (line 1306) | _getAgent(parsedUrl) {
method _performExponentialBackoff (line 1372) | _performExponentialBackoff(retryNumber) {
method dateTimeDeserializer (line 1377) | static dateTimeDeserializer(key, value) {
method _processResponse (line 1386) | async _processResponse(res, options) {
function getProxyUrl (line 1452) | function getProxyUrl(reqUrl) {
function checkBypass (line 1471) | function checkBypass(reqUrl) {
function auth (line 1522) | async function auth(token) {
function withAuthorizationPrefix (line 1539) | function withAuthorizationPrefix(token) {
function hook (line 1547) | async function hook(token, request, route, parameters) {
function _objectWithoutPropertiesLoose (line 1588) | function _objectWithoutPropertiesLoose(source, excluded) {
function _objectWithoutProperties (line 1603) | function _objectWithoutProperties(source, excluded) {
class Octokit (line 1627) | class Octokit {
method constructor (line 1628) | constructor(options = {}) {
method defaults (line 1714) | static defaults(defaults) {
method plugin (line 1740) | static plugin(...newPlugins) {
function lowercaseKeys (line 1769) | function lowercaseKeys(object) {
function mergeDeep (line 1780) | function mergeDeep(defaults, options) {
function removeUndefinedProperties (line 1796) | function removeUndefinedProperties(obj) {
function merge (line 1806) | function merge(defaults, route, options) {
function addQueryParameters (line 1834) | function addQueryParameters(url, parameters) {
function removeNonChars (line 1853) | function removeNonChars(variableName) {
function extractUrlVariableNames (line 1857) | function extractUrlVariableNames(url) {
function omit (line 1867) | function omit(object, keysToOmit) {
function encodeReserved (line 1901) | function encodeReserved(str) {
function encodeUnreserved (line 1911) | function encodeUnreserved(str) {
function encodeValue (line 1917) | function encodeValue(operator, value, key) {
function isDefined (line 1927) | function isDefined(value) {
function isKeyOperator (line 1931) | function isKeyOperator(operator) {
function getValues (line 1935) | function getValues(context, operator, key, modifier) {
function parseUrl (line 1999) | function parseUrl(template) {
function expand (line 2005) | function expand(template, context) {
function parse (line 2041) | function parse(options) {
function endpointWithDefaults (line 2115) | function endpointWithDefaults(defaults, route, options) {
function withDefaults (line 2119) | function withDefaults(oldDefaults, newDefaults) {
function _buildMessageForResponseErrors (line 2169) | function _buildMessageForResponseErrors(data) {
class GraphqlResponseError (line 2173) | class GraphqlResponseError extends Error {
method constructor (line 2174) | constructor(request, headers, response) {
function graphql (line 2196) | function graphql(request, query, options) {
function withDefaults (line 2247) | function withDefaults(request$1, newDefaults) {
function withCustomRequest (line 2267) | function withCustomRequest(customRequest) {
function ownKeys (line 2292) | function ownKeys(object, enumerableOnly) {
function _objectSpread2 (line 2310) | function _objectSpread2(target) {
function _defineProperty (line 2330) | function _defineProperty(obj, key, value) {
function normalizePaginatedListResponse (line 2361) | function normalizePaginatedListResponse(response) {
function iterator (line 2395) | function iterator(octokit, route, parameters) {
function paginate (line 2439) | function paginate(octokit, route, parameters, mapFn) {
function gather (line 2448) | function gather(octokit, results, iterator, mapFn) {
function isPaginatingEndpoint (line 2476) | function isPaginatingEndpoint(arg) {
function paginateRest (line 2489) | function paginateRest(octokit) {
function _defineProperty (line 2515) | function _defineProperty(obj, key, value) {
function ownKeys (line 2530) | function ownKeys(object, enumerableOnly) {
function _objectSpread2 (line 2544) | function _objectSpread2(target) {
function endpointsToMethods (line 3649) | function endpointsToMethods(octokit, endpointsMap) {
function decorate (line 3679) | function decorate(octokit, scope, methodName, defaults, decorations) {
function restEndpointMethods (line 3730) | function restEndpointMethods(octokit) {
function _interopDefault (line 3752) | function _interopDefault (ex) { return (ex && (typeof ex === 'object') &...
class RequestError (line 3763) | class RequestError extends Error {
method constructor (line 3764) | constructor(message, statusCode, options) {
function _interopDefault (line 3834) | function _interopDefault (ex) { return (ex && (typeof ex === 'object') &...
function getBufferResponse (line 3844) | function getBufferResponse(response) {
function fetchWrapper (line 3848) | function fetchWrapper(requestOptions) {
function getResponseData (line 3943) | async function getResponseData(response) {
function toErrorMessage (line 3957) | function toErrorMessage(data) {
function withDefaults (line 3972) | function withDefaults(oldEndpoint, newDefaults) {
function bindApi (line 4022) | function bindApi (hook, state, name) {
function HookSingular (line 4033) | function HookSingular () {
function HookCollection (line 4043) | function HookCollection () {
function Hook (line 4055) | function Hook () {
function addHook (line 4080) | function addHook(state, kind, name, hook) {
function register (line 4133) | function register(state, name, method, options) {
function removeHook (line 4167) | function removeHook(state, name, method) {
class Deprecation (line 4196) | class Deprecation extends Error {
method constructor (line 4197) | constructor(message) {
function isObject (line 4231) | function isObject(o) {
function isPlainObject (line 4235) | function isPlainObject(o) {
function _interopDefault (line 4270) | function _interopDefault (ex) { return (ex && (typeof ex === 'object') &...
class Blob (line 4287) | class Blob {
method constructor (line 4288) | constructor() {
method size (line 4326) | get size() {
method type (line 4329) | get type() {
method text (line 4332) | text() {
method arrayBuffer (line 4335) | arrayBuffer() {
method stream (line 4340) | stream() {
method toString (line 4347) | toString() {
method slice (line 4350) | slice() {
function FetchError (line 4407) | function FetchError(message, type, systemError) {
function Body (line 4445) | function Body(body) {
method body (line 4489) | get body() {
method bodyUsed (line 4493) | get bodyUsed() {
method arrayBuffer (line 4502) | arrayBuffer() {
method blob (line 4513) | blob() {
method json (line 4531) | json() {
method text (line 4548) | text() {
method buffer (line 4559) | buffer() {
method textConverted (line 4569) | textConverted() {
function consumeBody (line 4605) | function consumeBody() {
function convertBody (line 4709) | function convertBody(buffer, headers) {
function isURLSearchParams (line 4773) | function isURLSearchParams(obj) {
function isBlob (line 4788) | function isBlob(obj) {
function clone (line 4798) | function clone(instance) {
function extractContentType (line 4832) | function extractContentType(body) {
function getTotalBytes (line 4876) | function getTotalBytes(instance) {
function writeToStream (line 4908) | function writeToStream(dest, instance) {
function validateName (line 4939) | function validateName(name) {
function validateValue (line 4946) | function validateValue(value) {
function find (line 4961) | function find(map, name) {
class Headers (line 4972) | class Headers {
method constructor (line 4979) | constructor() {
method get (line 5040) | get(name) {
method forEach (line 5058) | forEach(callback) {
method set (line 5081) | set(name, value) {
method append (line 5097) | append(name, value) {
method has (line 5116) | has(name) {
method delete (line 5128) | delete(name) {
method raw (line 5142) | raw() {
method keys (line 5151) | keys() {
method values (line 5160) | values() {
method [Symbol.iterator] (line 5171) | [Symbol.iterator]() {
function getHeaders (line 5196) | function getHeaders(headers) {
function createHeadersIterator (line 5211) | function createHeadersIterator(target, kind) {
method next (line 5222) | next() {
function exportNodeCompatibleHeaders (line 5264) | function exportNodeCompatibleHeaders(headers) {
function createHeadersLenient (line 5284) | function createHeadersLenient(obj) {
class Response (line 5320) | class Response {
method constructor (line 5321) | constructor() {
method url (line 5346) | get url() {
method status (line 5350) | get status() {
method ok (line 5357) | get ok() {
method redirected (line 5361) | get redirected() {
method statusText (line 5365) | get statusText() {
method headers (line 5369) | get headers() {
method clone (line 5378) | clone() {
function parseURL (line 5422) | function parseURL(urlStr) {
function isRequest (line 5444) | function isRequest(input) {
function isAbortSignal (line 5448) | function isAbortSignal(signal) {
class Request (line 5460) | class Request {
method constructor (line 5461) | constructor(input) {
method method (line 5527) | get method() {
method url (line 5531) | get url() {
method headers (line 5535) | get headers() {
method redirect (line 5539) | get redirect() {
method signal (line 5543) | get signal() {
method clone (line 5552) | clone() {
function getNodeRequestOptions (line 5581) | function getNodeRequestOptions(request) {
function AbortError (line 5659) | function AbortError(message) {
function fetch (line 5684) | function fetch(url, opts) {
function once (line 5964) | function once (fn) {
function onceStrict (line 5974) | function onceStrict (fn) {
function normalize (line 6004) | function normalize(str) { // fix bug in v8
function findStatus (line 6008) | function findStatus(val) {
function countSymbols (line 6030) | function countSymbols(string) {
function mapChars (line 6038) | function mapChars(domain_name, useSTD3, processing_option) {
function validateLabel (line 6093) | function validateLabel(label, processing_option) {
function processing (line 6126) | function processing(domain_name, useSTD3, processing_option) {
function httpOverHttp (line 6220) | function httpOverHttp(options) {
function httpsOverHttp (line 6226) | function httpsOverHttp(options) {
function httpOverHttps (line 6234) | function httpOverHttps(options) {
function httpsOverHttps (line 6240) | function httpsOverHttps(options) {
function TunnelingAgent (line 6249) | function TunnelingAgent(options) {
function onFree (line 6292) | function onFree() {
function onCloseOrRemove (line 6296) | function onCloseOrRemove(err) {
function onResponse (line 6336) | function onResponse(res) {
function onUpgrade (line 6341) | function onUpgrade(res, socket, head) {
function onConnect (line 6348) | function onConnect(res, socket, head) {
function onError (line 6377) | function onError(cause) {
function createSecureSocket (line 6407) | function createSecureSocket(options, cb) {
function toOptions (line 6424) | function toOptions(host, port, localAddress) {
function mergeOptions (line 6435) | function mergeOptions(target) {
function getUserAgent (line 6479) | function getUserAgent() {
function sign (line 6506) | function sign(x) {
function evenRound (line 6510) | function evenRound(x) {
function createNumberConversion (line 6519) | function createNumberConversion(bitLength, typeOpts) {
method constructor (line 6702) | constructor(constructorArgs) {
method href (line 6724) | get href() {
method href (line 6728) | set href(v) {
method origin (line 6737) | get origin() {
method protocol (line 6741) | get protocol() {
method protocol (line 6745) | set protocol(v) {
method username (line 6749) | get username() {
method username (line 6753) | set username(v) {
method password (line 6761) | get password() {
method password (line 6765) | set password(v) {
method host (line 6773) | get host() {
method host (line 6787) | set host(v) {
method hostname (line 6795) | get hostname() {
method hostname (line 6803) | set hostname(v) {
method port (line 6811) | get port() {
method port (line 6819) | set port(v) {
method pathname (line 6831) | get pathname() {
method pathname (line 6843) | set pathname(v) {
method search (line 6852) | get search() {
method search (line 6860) | set search(v) {
method hash (line 6875) | get hash() {
method hash (line 6883) | set hash(v) {
method toJSON (line 6894) | toJSON() {
function URL (line 6914) | function URL(url) {
method get (line 6944) | get() {
method set (line 6947) | set(V) {
method get (line 6963) | get() {
method get (line 6971) | get() {
method set (line 6974) | set(V) {
method get (line 6983) | get() {
method set (line 6986) | set(V) {
method get (line 6995) | get() {
method set (line 6998) | set(V) {
method get (line 7007) | get() {
method set (line 7010) | set(V) {
method get (line 7019) | get() {
method set (line 7022) | set(V) {
method get (line 7031) | get() {
method set (line 7034) | set(V) {
method get (line 7043) | get() {
method set (line 7046) | set(V) {
method get (line 7055) | get() {
method set (line 7058) | set(V) {
method get (line 7067) | get() {
method set (line 7070) | set(V) {
method is (line 7080) | is(obj) {
method create (line 7083) | create(constructorArgs, privateData) {
method setup (line 7088) | setup(obj, constructorArgs, privateData) {
function countSymbols (line 7145) | function countSymbols(str) {
function at (line 7149) | function at(input, idx) {
function isASCIIDigit (line 7154) | function isASCIIDigit(c) {
function isASCIIAlpha (line 7158) | function isASCIIAlpha(c) {
function isASCIIAlphanumeric (line 7162) | function isASCIIAlphanumeric(c) {
function isASCIIHex (line 7166) | function isASCIIHex(c) {
function isSingleDot (line 7170) | function isSingleDot(buffer) {
function isDoubleDot (line 7174) | function isDoubleDot(buffer) {
function isWindowsDriveLetterCodePoints (line 7179) | function isWindowsDriveLetterCodePoints(cp1, cp2) {
function isWindowsDriveLetterString (line 7183) | function isWindowsDriveLetterString(string) {
function isNormalizedWindowsDriveLetterString (line 7187) | function isNormalizedWindowsDriveLetterString(string) {
function containsForbiddenHostCodePoint (line 7191) | function containsForbiddenHostCodePoint(string) {
function containsForbiddenHostCodePointExcludingPercent (line 7195) | function containsForbiddenHostCodePointExcludingPercent(string) {
function isSpecialScheme (line 7199) | function isSpecialScheme(scheme) {
function isSpecial (line 7203) | function isSpecial(url) {
function defaultPort (line 7207) | function defaultPort(scheme) {
function percentEncode (line 7211) | function percentEncode(c) {
function utf8PercentEncode (line 7220) | function utf8PercentEncode(c) {
function utf8PercentDecode (line 7232) | function utf8PercentDecode(str) {
function isC0ControlPercentEncode (line 7248) | function isC0ControlPercentEncode(c) {
function isPathPercentEncode (line 7253) | function isPathPercentEncode(c) {
function isUserinfoPercentEncode (line 7259) | function isUserinfoPercentEncode(c) {
function percentEncodeChar (line 7263) | function percentEncodeChar(c, encodeSetPredicate) {
function parseIPv4Number (line 7273) | function parseIPv4Number(input) {
function parseIPv4 (line 7296) | function parseIPv4(input) {
function serializeIPv4 (line 7341) | function serializeIPv4(address) {
function parseIPv6 (line 7356) | function parseIPv6(input) {
function serializeIPv6 (line 7485) | function serializeIPv6(address) {
function parseHost (line 7515) | function parseHost(input, isSpecialArg) {
function parseOpaqueHost (line 7546) | function parseOpaqueHost(input) {
function findLongestZeroSequence (line 7559) | function findLongestZeroSequence(arr) {
function serializeHost (line 7594) | function serializeHost(host) {
function trimControlChars (line 7607) | function trimControlChars(url) {
function trimTabAndNewline (line 7611) | function trimTabAndNewline(url) {
function shortenPath (line 7615) | function shortenPath(url) {
function includesCredentials (line 7627) | function includesCredentials(url) {
function cannotHaveAUsernamePasswordPort (line 7631) | function cannotHaveAUsernamePasswordPort(url) {
function isNormalizedWindowsDriveLetter (line 7635) | function isNormalizedWindowsDriveLetter(string) {
function URLStateMachine (line 7639) | function URLStateMachine(input, base, encodingOverride, url, stateOverri...
function serializeURL (line 8297) | function serializeURL(url, excludeFragment) {
function serializeOrigin (line 8338) | function serializeOrigin(tuple) {
function wrappy (line 8467) | function wrappy (fn, cb) {
function __webpack_require__ (line 8632) | function __webpack_require__(moduleId) {
FILE: pkg/runner/testdata/actions/node20/dist/index.js
function issueCommand (line 64) | function issueCommand(command, properties, message) {
function issue (line 69) | function issue(name, message = '') {
class Command (line 74) | class Command {
method constructor (line 75) | constructor(command, properties, message) {
method toString (line 83) | toString() {
function escapeData (line 107) | function escapeData(s) {
function escapeProperty (line 113) | function escapeProperty(s) {
function adopt (line 150) | function adopt(value) { return value instanceof P ? value : new P(functi...
function fulfilled (line 152) | function fulfilled(value) { try { step(generator.next(value)); } catch (...
function rejected (line 153) | function rejected(value) { try { step(generator["throw"](value)); } catc...
function step (line 154) | function step(result) { result.done ? resolve(result.value) : adopt(resu...
function exportVariable (line 189) | function exportVariable(name, val) {
function setSecret (line 207) | function setSecret(secret) {
function addPath (line 215) | function addPath(inputPath) {
function getInput (line 235) | function getInput(name, options) {
function getMultilineInput (line 254) | function getMultilineInput(name, options) {
function getBooleanInput (line 271) | function getBooleanInput(name, options) {
function setOutput (line 290) | function setOutput(name, value) {
function setCommandEcho (line 300) | function setCommandEcho(enabled) {
function setFailed (line 312) | function setFailed(message) {
function isDebug (line 323) | function isDebug() {
function debug (line 331) | function debug(message) {
function error (line 340) | function error(message, properties = {}) {
function warning (line 349) | function warning(message, properties = {}) {
function notice (line 358) | function notice(message, properties = {}) {
function info (line 366) | function info(message) {
function startGroup (line 377) | function startGroup(name) {
function endGroup (line 384) | function endGroup() {
function group (line 396) | function group(name, fn) {
function saveState (line 420) | function saveState(name, value) {
function getState (line 430) | function getState(name) {
function getIDToken (line 434) | function getIDToken(aud) {
function issueCommand (line 476) | function issueCommand(command, message) {
function adopt (line 499) | function adopt(value) { return value instanceof P ? value : new P(functi...
function fulfilled (line 501) | function fulfilled(value) { try { step(generator.next(value)); } catch (...
function rejected (line 502) | function rejected(value) { try { step(generator["throw"](value)); } catc...
function step (line 503) | function step(result) { result.done ? resolve(result.value) : adopt(resu...
class OidcClient (line 512) | class OidcClient {
method createHttpClient (line 513) | static createHttpClient(allowRetry = true, maxRetry = 10) {
method getRequestToken (line 520) | static getRequestToken() {
method getIDTokenUrl (line 527) | static getIDTokenUrl() {
method getCall (line 534) | static getCall(id_token_url) {
method getIDToken (line 552) | static getIDToken(audience) {
function toCommandValue (line 590) | function toCommandValue(input) {
function toCommandProperties (line 606) | function toCommandProperties(annotationProperties) {
class Context (line 633) | class Context {
method constructor (line 637) | constructor() {
method issue (line 658) | get issue() {
method repo (line 662) | get repo() {
function getOctokit (line 716) | function getOctokit(token, options) {
function getAuthString (line 751) | function getAuthString(token, options) {
function getProxyAgent (line 761) | function getProxyAgent(destinationUrl) {
function getApiBaseUrl (line 766) | function getApiBaseUrl() {
function getOctokitOptions (line 821) | function getOctokitOptions(token, options) {
class BasicCredentialHandler (line 841) | class BasicCredentialHandler {
method constructor (line 842) | constructor(username, password) {
method prepareRequest (line 846) | prepareRequest(options) {
method canHandleAuthentication (line 852) | canHandleAuthentication(response) {
method handleAuthentication (line 855) | handleAuthentication(httpClient, requestInfo, objs) {
class BearerCredentialHandler (line 860) | class BearerCredentialHandler {
method constructor (line 861) | constructor(token) {
method prepareRequest (line 866) | prepareRequest(options) {
method canHandleAuthentication (line 870) | canHandleAuthentication(response) {
method handleAuthentication (line 873) | handleAuthentication(httpClient, requestInfo, objs) {
class PersonalAccessTokenCredentialHandler (line 878) | class PersonalAccessTokenCredentialHandler {
method constructor (line 879) | constructor(token) {
method prepareRequest (line 884) | prepareRequest(options) {
method canHandleAuthentication (line 889) | canHandleAuthentication(response) {
method handleAuthentication (line 892) | handleAuthentication(httpClient, requestInfo, objs) {
function getProxyUrl (line 954) | function getProxyUrl(serverUrl) {
class HttpClientError (line 974) | class HttpClientError extends Error {
method constructor (line 975) | constructor(message, statusCode) {
class HttpClientResponse (line 983) | class HttpClientResponse {
method constructor (line 984) | constructor(message) {
method readBody (line 987) | readBody() {
function isHttps (line 1000) | function isHttps(requestUrl) {
class HttpClient (line 1005) | class HttpClient {
method constructor (line 1006) | constructor(userAgent, handlers, requestOptions) {
method options (line 1043) | options(requestUrl, additionalHeaders) {
method get (line 1046) | get(requestUrl, additionalHeaders) {
method del (line 1049) | del(requestUrl, additionalHeaders) {
method post (line 1052) | post(requestUrl, data, additionalHeaders) {
method patch (line 1055) | patch(requestUrl, data, additionalHeaders) {
method put (line 1058) | put(requestUrl, data, additionalHeaders) {
method head (line 1061) | head(requestUrl, additionalHeaders) {
method sendStream (line 1064) | sendStream(verb, requestUrl, stream, additionalHeaders) {
method getJson (line 1071) | async getJson(requestUrl, additionalHeaders = {}) {
method postJson (line 1076) | async postJson(requestUrl, obj, additionalHeaders = {}) {
method putJson (line 1083) | async putJson(requestUrl, obj, additionalHeaders = {}) {
method patchJson (line 1090) | async patchJson(requestUrl, obj, additionalHeaders = {}) {
method request (line 1102) | async request(verb, requestUrl, data, headers) {
method dispose (line 1183) | dispose() {
method requestRaw (line 1194) | requestRaw(info, data) {
method requestRawWithCallback (line 1211) | requestRawWithCallback(info, data, onResult) {
method getAgent (line 1260) | getAgent(serverUrl) {
method _prepareRequest (line 1264) | _prepareRequest(method, requestUrl, headers) {
method _mergeHeaders (line 1291) | _mergeHeaders(headers) {
method _getExistingOrDefaultHeader (line 1298) | _getExistingOrDefaultHeader(additionalHeaders, header, _default) {
method _getAgent (line 1306) | _getAgent(parsedUrl) {
method _performExponentialBackoff (line 1372) | _performExponentialBackoff(retryNumber) {
method dateTimeDeserializer (line 1377) | static dateTimeDeserializer(key, value) {
method _processResponse (line 1386) | async _processResponse(res, options) {
function getProxyUrl (line 1452) | function getProxyUrl(reqUrl) {
function checkBypass (line 1471) | function checkBypass(reqUrl) {
function auth (line 1522) | async function auth(token) {
function withAuthorizationPrefix (line 1539) | function withAuthorizationPrefix(token) {
function hook (line 1547) | async function hook(token, request, route, parameters) {
function _objectWithoutPropertiesLoose (line 1588) | function _objectWithoutPropertiesLoose(source, excluded) {
function _objectWithoutProperties (line 1603) | function _objectWithoutProperties(source, excluded) {
class Octokit (line 1627) | class Octokit {
method constructor (line 1628) | constructor(options = {}) {
method defaults (line 1714) | static defaults(defaults) {
method plugin (line 1740) | static plugin(...newPlugins) {
function lowercaseKeys (line 1769) | function lowercaseKeys(object) {
function mergeDeep (line 1780) | function mergeDeep(defaults, options) {
function removeUndefinedProperties (line 1796) | function removeUndefinedProperties(obj) {
function merge (line 1806) | function merge(defaults, route, options) {
function addQueryParameters (line 1834) | function addQueryParameters(url, parameters) {
function removeNonChars (line 1853) | function removeNonChars(variableName) {
function extractUrlVariableNames (line 1857) | function extractUrlVariableNames(url) {
function omit (line 1867) | function omit(object, keysToOmit) {
function encodeReserved (line 1901) | function encodeReserved(str) {
function encodeUnreserved (line 1911) | function encodeUnreserved(str) {
function encodeValue (line 1917) | function encodeValue(operator, value, key) {
function isDefined (line 1927) | function isDefined(value) {
function isKeyOperator (line 1931) | function isKeyOperator(operator) {
function getValues (line 1935) | function getValues(context, operator, key, modifier) {
function parseUrl (line 1999) | function parseUrl(template) {
function expand (line 2005) | function expand(template, context) {
function parse (line 2041) | function parse(options) {
function endpointWithDefaults (line 2115) | function endpointWithDefaults(defaults, route, options) {
function withDefaults (line 2119) | function withDefaults(oldDefaults, newDefaults) {
function _buildMessageForResponseErrors (line 2169) | function _buildMessageForResponseErrors(data) {
class GraphqlResponseError (line 2173) | class GraphqlResponseError extends Error {
method constructor (line 2174) | constructor(request, headers, response) {
function graphql (line 2196) | function graphql(request, query, options) {
function withDefaults (line 2247) | function withDefaults(request$1, newDefaults) {
function withCustomRequest (line 2267) | function withCustomRequest(customRequest) {
function ownKeys (line 2292) | function ownKeys(object, enumerableOnly) {
function _objectSpread2 (line 2310) | function _objectSpread2(target) {
function _defineProperty (line 2330) | function _defineProperty(obj, key, value) {
function normalizePaginatedListResponse (line 2361) | function normalizePaginatedListResponse(response) {
function iterator (line 2395) | function iterator(octokit, route, parameters) {
function paginate (line 2439) | function paginate(octokit, route, parameters, mapFn) {
function gather (line 2448) | function gather(octokit, results, iterator, mapFn) {
function isPaginatingEndpoint (line 2476) | function isPaginatingEndpoint(arg) {
function paginateRest (line 2489) | function paginateRest(octokit) {
function _defineProperty (line 2515) | function _defineProperty(obj, key, value) {
function ownKeys (line 2530) | function ownKeys(object, enumerableOnly) {
function _objectSpread2 (line 2544) | function _objectSpread2(target) {
function endpointsToMethods (line 3649) | function endpointsToMethods(octokit, endpointsMap) {
function decorate (line 3679) | function decorate(octokit, scope, methodName, defaults, decorations) {
function restEndpointMethods (line 3730) | function restEndpointMethods(octokit) {
function _interopDefault (line 3752) | function _interopDefault (ex) { return (ex && (typeof ex === 'object') &...
class RequestError (line 3763) | class RequestError extends Error {
method constructor (line 3764) | constructor(message, statusCode, options) {
function _interopDefault (line 3834) | function _interopDefault (ex) { return (ex && (typeof ex === 'object') &...
function getBufferResponse (line 3844) | function getBufferResponse(response) {
function fetchWrapper (line 3848) | function fetchWrapper(requestOptions) {
function getResponseData (line 3943) | async function getResponseData(response) {
function toErrorMessage (line 3957) | function toErrorMessage(data) {
function withDefaults (line 3972) | function withDefaults(oldEndpoint, newDefaults) {
function bindApi (line 4022) | function bindApi (hook, state, name) {
function HookSingular (line 4033) | function HookSingular () {
function HookCollection (line 4043) | function HookCollection () {
function Hook (line 4055) | function Hook () {
function addHook (line 4080) | function addHook(state, kind, name, hook) {
function register (line 4133) | function register(state, name, method, options) {
function removeHook (line 4167) | function removeHook(state, name, method) {
class Deprecation (line 4196) | class Deprecation extends Error {
method constructor (line 4197) | constructor(message) {
function isObject (line 4231) | function isObject(o) {
function isPlainObject (line 4235) | function isPlainObject(o) {
function _interopDefault (line 4270) | function _interopDefault (ex) { return (ex && (typeof ex === 'object') &...
class Blob (line 4287) | class Blob {
method constructor (line 4288) | constructor() {
method size (line 4326) | get size() {
method type (line 4329) | get type() {
method text (line 4332) | text() {
method arrayBuffer (line 4335) | arrayBuffer() {
method stream (line 4340) | stream() {
method toString (line 4347) | toString() {
method slice (line 4350) | slice() {
function FetchError (line 4407) | function FetchError(message, type, systemError) {
function Body (line 4445) | function Body(body) {
method body (line 4489) | get body() {
method bodyUsed (line 4493) | get bodyUsed() {
method arrayBuffer (line 4502) | arrayBuffer() {
method blob (line 4513) | blob() {
method json (line 4531) | json() {
method text (line 4548) | text() {
method buffer (line 4559) | buffer() {
method textConverted (line 4569) | textConverted() {
function consumeBody (line 4605) | function consumeBody() {
function convertBody (line 4709) | function convertBody(buffer, headers) {
function isURLSearchParams (line 4773) | function isURLSearchParams(obj) {
function isBlob (line 4788) | function isBlob(obj) {
function clone (line 4798) | function clone(instance) {
function extractContentType (line 4832) | function extractContentType(body) {
function getTotalBytes (line 4876) | function getTotalBytes(instance) {
function writeToStream (line 4908) | function writeToStream(dest, instance) {
function validateName (line 4939) | function validateName(name) {
function validateValue (line 4946) | function validateValue(value) {
function find (line 4961) | function find(map, name) {
class Headers (line 4972) | class Headers {
method constructor (line 4979) | constructor() {
method get (line 5040) | get(name) {
method forEach (line 5058) | forEach(callback) {
method set (line 5081) | set(name, value) {
method append (line 5097) | append(name, value) {
method has (line 5116) | has(name) {
method delete (line 5128) | delete(name) {
method raw (line 5142) | raw() {
method keys (line 5151) | keys() {
method values (line 5160) | values() {
method [Symbol.iterator] (line 5171) | [Symbol.iterator]() {
function getHeaders (line 5196) | function getHeaders(headers) {
function createHeadersIterator (line 5211) | function createHeadersIterator(target, kind) {
method next (line 5222) | next() {
function exportNodeCompatibleHeaders (line 5264) | function exportNodeCompatibleHeaders(headers) {
function createHeadersLenient (line 5284) | function createHeadersLenient(obj) {
class Response (line 5320) | class Response {
method constructor (line 5321) | constructor() {
method url (line 5346) | get url() {
method status (line 5350) | get status() {
method ok (line 5357) | get ok() {
method redirected (line 5361) | get redirected() {
method statusText (line 5365) | get statusText() {
method headers (line 5369) | get headers() {
method clone (line 5378) | clone() {
function parseURL (line 5422) | function parseURL(urlStr) {
function isRequest (line 5444) | function isRequest(input) {
function isAbortSignal (line 5448) | function isAbortSignal(signal) {
class Request (line 5460) | class Request {
method constructor (line 5461) | constructor(input) {
method method (line 5527) | get method() {
method url (line 5531) | get url() {
method headers (line 5535) | get headers() {
method redirect (line 5539) | get redirect() {
method signal (line 5543) | get signal() {
method clone (line 5552) | clone() {
function getNodeRequestOptions (line 5581) | function getNodeRequestOptions(request) {
function AbortError (line 5659) | function AbortError(message) {
function fetch (line 5684) | function fetch(url, opts) {
function once (line 5964) | function once (fn) {
function onceStrict (line 5974) | function onceStrict (fn) {
function normalize (line 6004) | function normalize(str) { // fix bug in v8
function findStatus (line 6008) | function findStatus(val) {
function countSymbols (line 6030) | function countSymbols(string) {
function mapChars (line 6038) | function mapChars(domain_name, useSTD3, processing_option) {
function validateLabel (line 6093) | function validateLabel(label, processing_option) {
function processing (line 6126) | function processing(domain_name, useSTD3, processing_option) {
function httpOverHttp (line 6220) | function httpOverHttp(options) {
function httpsOverHttp (line 6226) | function httpsOverHttp(options) {
function httpOverHttps (line 6234) | function httpOverHttps(options) {
function httpsOverHttps (line 6240) | function httpsOverHttps(options) {
function TunnelingAgent (line 6249) | function TunnelingAgent(options) {
function onFree (line 6292) | function onFree() {
function onCloseOrRemove (line 6296) | function onCloseOrRemove(err) {
function onResponse (line 6336) | function onResponse(res) {
function onUpgrade (line 6341) | function onUpgrade(res, socket, head) {
function onConnect (line 6348) | function onConnect(res, socket, head) {
function onError (line 6377) | function onError(cause) {
function createSecureSocket (line 6407) | function createSecureSocket(options, cb) {
function toOptions (line 6424) | function toOptions(host, port, localAddress) {
function mergeOptions (line 6435) | function mergeOptions(target) {
function getUserAgent (line 6479) | function getUserAgent() {
function sign (line 6506) | function sign(x) {
function evenRound (line 6510) | function evenRound(x) {
function createNumberConversion (line 6519) | function createNumberConversion(bitLength, typeOpts) {
method constructor (line 6702) | constructor(constructorArgs) {
method href (line 6724) | get href() {
method href (line 6728) | set href(v) {
method origin (line 6737) | get origin() {
method protocol (line 6741) | get protocol() {
method protocol (line 6745) | set protocol(v) {
method username (line 6749) | get username() {
method username (line 6753) | set username(v) {
method password (line 6761) | get password() {
method password (line 6765) | set password(v) {
method host (line 6773) | get host() {
method host (line 6787) | set host(v) {
method hostname (line 6795) | get hostname() {
method hostname (line 6803) | set hostname(v) {
method port (line 6811) | get port() {
method port (line 6819) | set port(v) {
method pathname (line 6831) | get pathname() {
method pathname (line 6843) | set pathname(v) {
method search (line 6852) | get search() {
method search (line 6860) | set search(v) {
method hash (line 6875) | get hash() {
method hash (line 6883) | set hash(v) {
method toJSON (line 6894) | toJSON() {
function URL (line 6914) | function URL(url) {
method get (line 6944) | get() {
method set (line 6947) | set(V) {
method get (line 6963) | get() {
method get (line 6971) | get() {
method set (line 6974) | set(V) {
method get (line 6983) | get() {
method set (line 6986) | set(V) {
method get (line 6995) | get() {
method set (line 6998) | set(V) {
method get (line 7007) | get() {
method set (line 7010) | set(V) {
method get (line 7019) | get() {
method set (line 7022) | set(V) {
method get (line 7031) | get() {
method set (line 7034) | set(V) {
method get (line 7043) | get() {
method set (line 7046) | set(V) {
method get (line 7055) | get() {
method set (line 7058) | set(V) {
method get (line 7067) | get() {
method set (line 7070) | set(V) {
method is (line 7080) | is(obj) {
method create (line 7083) | create(constructorArgs, privateData) {
method setup (line 7088) | setup(obj, constructorArgs, privateData) {
function countSymbols (line 7145) | function countSymbols(str) {
function at (line 7149) | function at(input, idx) {
function isASCIIDigit (line 7154) | function isASCIIDigit(c) {
function isASCIIAlpha (line 7158) | function isASCIIAlpha(c) {
function isASCIIAlphanumeric (line 7162) | function isASCIIAlphanumeric(c) {
function isASCIIHex (line 7166) | function isASCIIHex(c) {
function isSingleDot (line 7170) | function isSingleDot(buffer) {
function isDoubleDot (line 7174) | function isDoubleDot(buffer) {
function isWindowsDriveLetterCodePoints (line 7179) | function isWindowsDriveLetterCodePoints(cp1, cp2) {
function isWindowsDriveLetterString (line 7183) | function isWindowsDriveLetterString(string) {
function isNormalizedWindowsDriveLetterString (line 7187) | function isNormalizedWindowsDriveLetterString(string) {
function containsForbiddenHostCodePoint (line 7191) | function containsForbiddenHostCodePoint(string) {
function containsForbiddenHostCodePointExcludingPercent (line 7195) | function containsForbiddenHostCodePointExcludingPercent(string) {
function isSpecialScheme (line 7199) | function isSpecialScheme(scheme) {
function isSpecial (line 7203) | function isSpecial(url) {
function defaultPort (line 7207) | function defaultPort(scheme) {
function percentEncode (line 7211) | function percentEncode(c) {
function utf8PercentEncode (line 7220) | function utf8PercentEncode(c) {
function utf8PercentDecode (line 7232) | function utf8PercentDecode(str) {
function isC0ControlPercentEncode (line 7248) | function isC0ControlPercentEncode(c) {
function isPathPercentEncode (line 7253) | function isPathPercentEncode(c) {
function isUserinfoPercentEncode (line 7259) | function isUserinfoPercentEncode(c) {
function percentEncodeChar (line 7263) | function percentEncodeChar(c, encodeSetPredicate) {
function parseIPv4Number (line 7273) | function parseIPv4Number(input) {
function parseIPv4 (line 7296) | function parseIPv4(input) {
function serializeIPv4 (line 7341) | function serializeIPv4(address) {
function parseIPv6 (line 7356) | function parseIPv6(input) {
function serializeIPv6 (line 7485) | function serializeIPv6(address) {
function parseHost (line 7515) | function parseHost(input, isSpecialArg) {
function parseOpaqueHost (line 7546) | function parseOpaqueHost(input) {
function findLongestZeroSequence (line 7559) | function findLongestZeroSequence(arr) {
function serializeHost (line 7594) | function serializeHost(host) {
function trimControlChars (line 7607) | function trimControlChars(url) {
function trimTabAndNewline (line 7611) | function trimTabAndNewline(url) {
function shortenPath (line 7615) | function shortenPath(url) {
function includesCredentials (line 7627) | function includesCredentials(url) {
function cannotHaveAUsernamePasswordPort (line 7631) | function cannotHaveAUsernamePasswordPort(url) {
function isNormalizedWindowsDriveLetter (line 7635) | function isNormalizedWindowsDriveLetter(string) {
function URLStateMachine (line 7639) | function URLStateMachine(input, base, encodingOverride, url, stateOverri...
function serializeURL (line 8297) | function serializeURL(url, excludeFragment) {
function serializeOrigin (line 8338) | function serializeOrigin(tuple) {
function wrappy (line 8467) | function wrappy (fn, cb) {
function __webpack_require__ (line 8632) | function __webpack_require__(moduleId) {
FILE: pkg/schema/schema.go
type Schema (line 25) | type Schema struct
method GetDefinition (line 29) | func (s *Schema) GetDefinition(name string) Definition {
type Definition (line 52) | type Definition struct
type MappingDefinition (line 64) | type MappingDefinition struct
type MappingProperty (line 70) | type MappingProperty struct
method UnmarshalJSON (line 75) | func (s *MappingProperty) UnmarshalJSON(data []byte) error {
type SequenceDefinition (line 83) | type SequenceDefinition struct
type StringDefinition (line 87) | type StringDefinition struct
type NumberDefinition (line 92) | type NumberDefinition struct
type BooleanDefinition (line 95) | type BooleanDefinition struct
type NullDefinition (line 98) | type NullDefinition struct
function GetWorkflowSchema (line 101) | func GetWorkflowSchema() *Schema {
function GetActionSchema (line 107) | func GetActionSchema() *Schema {
type Node (line 113) | type Node struct
method checkSingleExpression (line 125) | func (s *Node) checkSingleExpression(exprNode actionlint.ExprNode) err...
method GetFunctions (line 167) | func (s *Node) GetFunctions() *[]FunctionInfo {
method checkExpression (line 202) | func (s *Node) checkExpression(node *yaml.Node) (bool, error) {
method UnmarshalYAML (line 237) | func (s *Node) UnmarshalYAML(node *yaml.Node) error {
method checkString (line 288) | func (s *Node) checkString(node *yaml.Node, def Definition) error {
method checkOneOf (line 308) | func (s *Node) checkOneOf(def Definition, node *yaml.Node) error {
method checkSequence (line 343) | func (s *Node) checkSequence(node *yaml.Node, def Definition) error {
method checkMapping (line 362) | func (s *Node) checkMapping(node *yaml.Node, def Definition) error {
type FunctionInfo (line 119) | type FunctionInfo struct
function AddFunction (line 229) | func AddFunction(funcs *[]FunctionInfo, s string, i1, i2 int) {
function getStringKind (line 326) | func getStringKind(k yaml.Kind) string {
function formatLocation (line 358) | func formatLocation(node *yaml.Node) string {
FILE: pkg/schema/schema_test.go
function TestAdditionalFunctions (line 10) | func TestAdditionalFunctions(t *testing.T) {
function TestAdditionalFunctionsFailure (line 31) | func TestAdditionalFunctionsFailure(t *testing.T) {
function TestAdditionalFunctionsSteps (line 52) | func TestAdditionalFunctionsSteps(t *testing.T) {
function TestAdditionalFunctionsStepsExprSyntax (line 73) | func TestAdditionalFunctionsStepsExprSyntax(t *testing.T) {
FILE: pkg/workflowpattern/trace_writer.go
type TraceWriter (line 5) | type TraceWriter interface
type EmptyTraceWriter (line 9) | type EmptyTraceWriter struct
method Info (line 11) | func (*EmptyTraceWriter) Info(string, ...interface{}) {
type StdOutTraceWriter (line 14) | type St
Condensed preview — 411 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (2,871K chars).
[
{
"path": ".actrc",
"chars": 0,
"preview": ""
},
{
"path": ".codespellrc",
"chars": 257,
"preview": "[codespell]\n# Ref: https://github.com/codespell-project/codespell#using-a-config-file\nskip = .git*,go.sum,package-lock.j"
},
{
"path": ".editorconfig",
"chars": 331,
"preview": "root = true\n\n[*]\nend_of_line = lf\ncharset = utf-8\ninsert_final_newline = true\ntrim_trailing_whitespace = true\nindent_sty"
},
{
"path": ".github/FUNDING.yml",
"chars": 14,
"preview": "github: cplee\n"
},
{
"path": ".github/ISSUE_TEMPLATE/bug_report.yml",
"chars": 2407,
"preview": "name: Bug report\ndescription: Use this template for reporting bugs/issues.\nlabels:\n - 'kind/bug'\nbody:\n - type: markdo"
},
{
"path": ".github/ISSUE_TEMPLATE/config.yml",
"chars": 320,
"preview": "blank_issues_enabled: true\ncontact_links:\n - name: Start a discussion\n url: https://github.com/nektos/act/discussion"
},
{
"path": ".github/ISSUE_TEMPLATE/feature_template.yml",
"chars": 839,
"preview": "name: Feature request\ndescription: Use this template for requesting a feature/enhancement.\nlabels:\n - 'kind/feature-req"
},
{
"path": ".github/ISSUE_TEMPLATE/wiki_issue.yml",
"chars": 401,
"preview": "name: Wiki issue\ndescription: Report issue/improvement ragarding documentation (wiki)\nlabels:\n - 'kind/discussion'\n - "
},
{
"path": ".github/actions/choco/Dockerfile",
"chars": 722,
"preview": "FROM alpine:3.21\n\nARG CHOCOVERSION=1.1.0\n\nRUN apk add --no-cache bash ca-certificates git \\\n && apk --no-cache --reposi"
},
{
"path": ".github/actions/choco/action.yml",
"chars": 388,
"preview": "name: 'Chocolatey Packager'\ndescription: 'Create the choco package and push it'\ninputs:\n version:\n description: 'Ver"
},
{
"path": ".github/actions/choco/entrypoint.sh",
"chars": 854,
"preview": "#!/bin/bash\n\nset -e\n\nfunction choco {\n mono /opt/chocolatey/choco.exe \"$@\" --allow-unofficial --nocolor\n}\n\nfunction get"
},
{
"path": ".github/dependabot.yml",
"chars": 660,
"preview": "# To get started with Dependabot version updates, you'll need to specify which\n# package ecosystems to update and where "
},
{
"path": ".github/workflows/.gitignore",
"chars": 11,
"preview": "test-*.yml\n"
},
{
"path": ".github/workflows/checks.yml",
"chars": 5764,
"preview": "name: checks\non: [pull_request, workflow_dispatch]\n\nconcurrency:\n cancel-in-progress: true\n group: ${{ github.workflow"
},
{
"path": ".github/workflows/codespell.yml",
"chars": 404,
"preview": "# Codespell configuration is within .codespellrc\n---\nname: Codespell\n\non:\n push:\n branches: [master]\n pull_request:"
},
{
"path": ".github/workflows/promote.yml",
"chars": 759,
"preview": "name: promote\non:\n schedule:\n - cron: '0 2 1 * *'\n workflow_dispatch: {}\n\njobs:\n release:\n name: promote\n ru"
},
{
"path": ".github/workflows/release.yml",
"chars": 1509,
"preview": "name: release\non:\n push:\n tags:\n - v*\n\npermissions:\n contents: write\n actions: write\n\njobs:\n release:\n na"
},
{
"path": ".github/workflows/stale.yml",
"chars": 749,
"preview": "name: 'Close stale issues'\non:\n workflow_dispatch:\n\njobs:\n stale:\n name: Stale\n runs-on: ubuntu-latest\n steps"
},
{
"path": ".gitignore",
"chars": 395,
"preview": "# Binaries for programs and plugins\n*.exe\n*.exe~\n*.dll\n*.so\n*.dylib\n\n# Test binary, build with `go test -c`\n*.test\n\n# Ou"
},
{
"path": ".gitleaksignore",
"chars": 208,
"preview": "b910a42edfab7a02b08a52ecef203fd419725642:pkg/container/testdata/docker-pull-options/config.json:generic-api-key:4\n710a3a"
},
{
"path": ".golangci.yml",
"chars": 1234,
"preview": "# Minimum golangci-lint version required: v1.46.0\nrun:\n timeout: 3m\n\nissues:\n exclude-dirs:\n - report # megalinter "
},
{
"path": ".goreleaser.yml",
"chars": 1007,
"preview": "version: 2\nbefore:\n hooks:\n - go mod tidy\nbuilds:\n - env:\n - CGO_ENABLED=0\n goos:\n - darwin\n - li"
},
{
"path": ".markdownlint.yml",
"chars": 265,
"preview": "# Default state for all rules\ndefault: true\n\n# MD013/line-length - Line length\nMD013:\n line_length: 1024\n\n# MD033/no-in"
},
{
"path": ".mega-linter.yml",
"chars": 464,
"preview": "---\nAPPLY_FIXES: none\nDISABLE:\n - ACTION\n - BASH\n - COPYPASTE\n - DOCKERFILE\n - GO\n - JAVASCRIPT\n - SPELL\nDISABLE_"
},
{
"path": ".mergify.yml",
"chars": 1919,
"preview": "merge_queue:\n max_parallel_checks: 1\n\npull_request_rules:\n - name: warn on conflicts\n conditions:\n - -draft\n "
},
{
"path": ".prettierignore",
"chars": 27,
"preview": "**/testdata\npkg/runner/res\n"
},
{
"path": ".prettierrc.yml",
"chars": 125,
"preview": "overrides:\n - files: '*.yml'\n options:\n singleQuote: true\n - files: '*.json'\n options:\n singleQuote: f"
},
{
"path": "CONTRIBUTING.md",
"chars": 5581,
"preview": "# Contributing to Act\n\nHelp wanted! We'd love your contributions to Act. Please review the following guidelines before c"
},
{
"path": "IMAGES.md",
"chars": 5927,
"preview": "# List of Docker images for `act`\n\n**Warning:** Below badges with size for each image are displaying size of **compresse"
},
{
"path": "LICENSE",
"chars": 1056,
"preview": "MIT License\n\nCopyright (c) 2019\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this so"
},
{
"path": "Makefile",
"chars": 2909,
"preview": "PREFIX ?= /usr/local\nVERSION ?= $(shell git describe --tags --dirty --always | sed -e 's/^v//')\nIS_SNAPSHOT = $(if $(fin"
},
{
"path": "README.md",
"chars": 3315,
"preview": "\n\n# Overview [\n\nvar (\n\tUserHomeDir string\n\tCacheHome"
},
{
"path": "cmd/execute_test.go",
"chars": 879,
"preview": "package cmd\n\nimport (\n\t\"context\"\n\t\"os\"\n\t\"testing\"\n)\n\n// Helper function to test main with different os.Args\nfunc testMai"
},
{
"path": "cmd/graph.go",
"chars": 742,
"preview": "package cmd\n\nimport (\n\t\"os\"\n\n\t\"github.com/nektos/act/pkg/common\"\n\t\"github.com/nektos/act/pkg/model\"\n)\n\nfunc drawGraph(pl"
},
{
"path": "cmd/input.go",
"chars": 3554,
"preview": "package cmd\n\nimport (\n\t\"path/filepath\"\n\n\tlog \"github.com/sirupsen/logrus\"\n)\n\n// Input contains the input for the root co"
},
{
"path": "cmd/list.go",
"chars": 2480,
"preview": "package cmd\n\nimport (\n\t\"fmt\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/nektos/act/pkg/model\"\n)\n\nfunc printList(plan *model.Pla"
},
{
"path": "cmd/notices.go",
"chars": 2911,
"preview": "package cmd\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"runtime\"\n\t\"strings\"\n\t\"time"
},
{
"path": "cmd/platforms.go",
"chars": 465,
"preview": "package cmd\n\nimport (\n\t\"strings\"\n)\n\nfunc (i *Input) newPlatforms() map[string]string {\n\tplatforms := map[string]string{\n"
},
{
"path": "cmd/root.go",
"chars": 32840,
"preview": "package cmd\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"regexp\"\n\t\"runtime\"\n\t"
},
{
"path": "cmd/root_test.go",
"chars": 3376,
"preview": "package cmd\n\nimport (\n\t\"context\"\n\t\"path\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestReadSecrets(t *te"
},
{
"path": "cmd/secrets.go",
"chars": 1070,
"preview": "package cmd\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"strings\"\n\n\tlog \"github.com/sirupsen/logrus\"\n\t\"golang.org/x/term\"\n)\n\ntype secrets ma"
},
{
"path": "cmd/testdata/env.actrc",
"chars": 74,
"preview": "--artifact-server-path $FAKEPWD/.artifacts\n--env FOO=prefix/${FOO}/suffix\n"
},
{
"path": "cmd/testdata/secrets.yml",
"chars": 36,
"preview": "mysecret: |\n line1\n line2\n line3\n"
},
{
"path": "cmd/testdata/simple.actrc",
"chars": 59,
"preview": "--container-architecture=linux/amd64\n--action-offline-mode\n"
},
{
"path": "cmd/testdata/split.actrc",
"chars": 77,
"preview": "--container-options --volume /foo:/bar --volume /baz:/qux --volume /tmp:/tmp\n"
},
{
"path": "codecov.yml",
"chars": 302,
"preview": "coverage:\n status:\n project:\n default:\n target: auto # auto compares coverage to the previous base commi"
},
{
"path": "go.mod",
"chars": 4968,
"preview": "module github.com/nektos/act\n\ngo 1.24.0\n\nrequire (\n\tgithub.com/AlecAivazis/survey/v2 v2.3.7\n\tgithub.com/Masterminds/semv"
},
{
"path": "go.sum",
"chars": 28927,
"preview": "dario.cat/mergo v1.0.2 h1:85+piFYR1tMbRrLcDwR18y4UKJ3aH1Tbzi24VRW1TK8=\ndario.cat/mergo v1.0.2/go.mod h1:E/hbnu0NxMFBjpMI"
},
{
"path": "install.sh",
"chars": 10964,
"preview": "#!/bin/sh\nset -e\n# Code originally generated by godownloader on 2021-12-22T16:10:52Z. DO NOT EDIT.\n# (godownloader is de"
},
{
"path": "main.go",
"chars": 284,
"preview": "package main\n\nimport (\n\t_ \"embed\"\n\n\t\"github.com/nektos/act/cmd\"\n\t\"github.com/nektos/act/pkg/common\"\n)\n\n//go:embed VERSIO"
},
{
"path": "main_test.go",
"chars": 120,
"preview": "package main\n\nimport (\n\t\"os\"\n\t\"testing\"\n)\n\nfunc TestMain(_ *testing.T) {\n\tos.Args = []string{\"act\", \"--help\"}\n\tmain()\n}\n"
},
{
"path": "pkg/artifactcache/doc.go",
"chars": 538,
"preview": "// Package artifactcache provides a cache handler for the runner.\n//\n// Inspired by https://github.com/sp-ricard-valverd"
},
{
"path": "pkg/artifactcache/handler.go",
"chars": 13813,
"preview": "package artifactcache\n\nimport (\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"net\"\n\t\"net/http\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"rege"
},
{
"path": "pkg/artifactcache/handler_test.go",
"chars": 21725,
"preview": "package artifactcache\n\nimport (\n\t\"bytes\"\n\t\"crypto/rand\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"path/filepath\"\n\t\"str"
},
{
"path": "pkg/artifactcache/model.go",
"chars": 886,
"preview": "package artifactcache\n\ntype Request struct {\n\tKey string `json:\"key\" `\n\tVersion string `json:\"version\"`\n\tSize int"
},
{
"path": "pkg/artifactcache/storage.go",
"chars": 2712,
"preview": "package artifactcache\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"path/filepath\"\n)\n\ntype Storage struct {\n\trootDir string"
},
{
"path": "pkg/artifactcache/testdata/example/example.yaml",
"chars": 710,
"preview": "# Copied from https://github.com/actions/cache#example-cache-workflow\nname: Caching Primes\n\non: push\n\njobs:\n build:\n "
},
{
"path": "pkg/artifacts/artifact.pb.go",
"chars": 39732,
"preview": "// Copyright 2024 The Gitea Authors. All rights reserved.\n// SPDX-License-Identifier: MIT\n\n// Code generated by protoc-g"
},
{
"path": "pkg/artifacts/artifacts_v4.go",
"chars": 13981,
"preview": "// Copyright 2024 The Gitea Authors. All rights reserved.\n// SPDX-License-Identifier: MIT\n\npackage artifacts\n\n// GitHub "
},
{
"path": "pkg/artifacts/server.go",
"chars": 7468,
"preview": "package artifacts\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"io/fs\"\n\t\"net/http\"\n\t\"os\"\n\t\"path/filepat"
},
{
"path": "pkg/artifacts/server_test.go",
"chars": 9859,
"preview": "package artifacts\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"os\"\n\t\"path\"\n\t\"path/fil"
},
{
"path": "pkg/artifacts/testdata/GHSL-2023-004/artifacts.yml",
"chars": 1339,
"preview": "\nname: \"GHSL-2023-0004\"\non: push\n\njobs:\n test-artifacts:\n runs-on: ubuntu-latest\n steps:\n - run: echo \"hello"
},
{
"path": "pkg/artifacts/testdata/upload-and-download/artifacts.yml",
"chars": 8154,
"preview": "\nname: \"Test that artifact uploads and downloads succeed\"\non: push\n\njobs:\n test-artifacts:\n runs-on: ubuntu-latest\n "
},
{
"path": "pkg/artifacts/testdata/v4/artifacts.yml",
"chars": 1910,
"preview": "on:\n push:\njobs:\n _5:\n runs-on: ubuntu-latest\n steps: \n - run: env\n - run: |\n github:\n ${{ t"
},
{
"path": "pkg/common/auth.go",
"chars": 2059,
"preview": "// Copyright 2024 The Gitea Authors. All rights reserved.\n// SPDX-License-Identifier: MIT\n\npackage common\n\nimport (\n\t\"en"
},
{
"path": "pkg/common/auth_test.go",
"chars": 1910,
"preview": "// Copyright 2024 The Gitea Authors. All rights reserved.\n// SPDX-License-Identifier: MIT\n\npackage common\n\nimport (\n\t\"en"
},
{
"path": "pkg/common/cartesian.go",
"chars": 1065,
"preview": "package common\n\n// CartesianProduct takes map of lists and returns list of unique tuples\nfunc CartesianProduct(mapOfList"
},
{
"path": "pkg/common/cartesian_test.go",
"chars": 705,
"preview": "package common\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestCartesianProduct(t *testing.T) {\n"
},
{
"path": "pkg/common/context.go",
"chars": 899,
"preview": "package common\n\nimport (\n\t\"context\"\n\t\"os\"\n\t\"os/signal\"\n\t\"syscall\"\n)\n\nfunc createGracefulJobCancellationContext() (contex"
},
{
"path": "pkg/common/context_test.go",
"chars": 2590,
"preview": "package common\n\nimport (\n\t\"context\"\n\t\"os\"\n\t\"syscall\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc T"
},
{
"path": "pkg/common/draw.go",
"chars": 3096,
"preview": "package common\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"strings\"\n)\n\n// Style is a specific style\ntype Style int\n\n// Styles\nconst ("
},
{
"path": "pkg/common/dryrun.go",
"chars": 537,
"preview": "package common\n\nimport (\n\t\"context\"\n)\n\ntype dryrunContextKey string\n\nconst dryrunContextKeyVal = dryrunContextKey(\"dryru"
},
{
"path": "pkg/common/executor.go",
"chars": 5473,
"preview": "package common\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\n\tlog \"github.com/sirupsen/logrus\"\n)\n\n// Warning that implements `e"
},
{
"path": "pkg/common/executor_test.go",
"chars": 3265,
"preview": "package common\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestNewWork"
},
{
"path": "pkg/common/file.go",
"chars": 1278,
"preview": "package common\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n)\n\n// CopyFile copy file\nfunc CopyFile(source string, dest string) (err erro"
},
{
"path": "pkg/common/git/git.go",
"chars": 11626,
"preview": "package git\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"path\"\n\t\"regexp\"\n\t\"strings\"\n\t\"sync\"\n\n\t\"github.com/go-git/"
},
{
"path": "pkg/common/git/git_test.go",
"chars": 7783,
"preview": "package git\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\t\"os/exec\"\n\t\"path/filepath\"\n\t\"syscall\"\n\t\"testing\"\n\n\tlog \"github.com/sirups"
},
{
"path": "pkg/common/job_error.go",
"chars": 1695,
"preview": "package common\n\nimport (\n\t\"context\"\n)\n\ntype jobErrorContextKey string\n\nconst jobErrorContextKeyVal = jobErrorContextKey("
},
{
"path": "pkg/common/line_writer.go",
"chars": 891,
"preview": "package common\n\nimport (\n\t\"bytes\"\n\t\"io\"\n)\n\n// LineHandler is a callback function for handling a line\ntype LineHandler fu"
},
{
"path": "pkg/common/line_writer_test.go",
"chars": 740,
"preview": "package common\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestLineWriter(t *testing.T) {\n\tlines"
},
{
"path": "pkg/common/logger.go",
"chars": 649,
"preview": "package common\n\nimport (\n\t\"context\"\n\n\t\"github.com/sirupsen/logrus\"\n)\n\ntype loggerContextKey string\n\nconst loggerContextK"
},
{
"path": "pkg/common/outbound_ip.go",
"chars": 1711,
"preview": "package common\n\nimport (\n\t\"net\"\n\t\"sort\"\n\t\"strings\"\n)\n\n// GetOutboundIP returns an outbound IP address of this machine.\n/"
},
{
"path": "pkg/container/DOCKER_LICENSE",
"chars": 10765,
"preview": "\n Apache License\n Version 2.0, January 2004\n "
},
{
"path": "pkg/container/container_types.go",
"chars": 2231,
"preview": "package container\n\nimport (\n\t\"context\"\n\t\"io\"\n\n\t\"github.com/docker/go-connections/nat\"\n\t\"github.com/nektos/act/pkg/common"
},
{
"path": "pkg/container/docker_auth.go",
"chars": 1673,
"preview": "//go:build !(WITHOUT_DOCKER || !(linux || darwin || windows || netbsd))\n\npackage container\n\nimport (\n\t\"context\"\n\t\"string"
},
{
"path": "pkg/container/docker_build.go",
"chars": 3421,
"preview": "//go:build !(WITHOUT_DOCKER || !(linux || darwin || windows || netbsd))\n\npackage container\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\""
},
{
"path": "pkg/container/docker_cli.go",
"chars": 41479,
"preview": "//go:build !(WITHOUT_DOCKER || !(linux || darwin || windows || netbsd))\n\n// This file is exact copy of https://github.co"
},
{
"path": "pkg/container/docker_cli_test.go",
"chars": 35877,
"preview": "// This file is exact copy of https://github.com/docker/cli/blob/9ac8584acfd501c3f4da0e845e3a40ed15c85041/cli/command/co"
},
{
"path": "pkg/container/docker_images.go",
"chars": 1744,
"preview": "//go:build !(WITHOUT_DOCKER || !(linux || darwin || windows || netbsd))\n\npackage container\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n"
},
{
"path": "pkg/container/docker_images_test.go",
"chars": 2043,
"preview": "package container\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"testing\"\n\n\t\"github.com/docker/docker/api/types/image\"\n\t\"github.com/docker"
},
{
"path": "pkg/container/docker_logger.go",
"chars": 1854,
"preview": "//go:build !(WITHOUT_DOCKER || !(linux || darwin || windows || netbsd))\n\npackage container\n\nimport (\n\t\"bufio\"\n\t\"encoding"
},
{
"path": "pkg/container/docker_network.go",
"chars": 1868,
"preview": "//go:build !(WITHOUT_DOCKER || !(linux || darwin || windows || netbsd))\n\npackage container\n\nimport (\n\t\"context\"\n\n\t\"githu"
},
{
"path": "pkg/container/docker_pull.go",
"chars": 3285,
"preview": "//go:build !(WITHOUT_DOCKER || !(linux || darwin || windows || netbsd))\n\npackage container\n\nimport (\n\t\"context\"\n\t\"encodi"
},
{
"path": "pkg/container/docker_pull_test.go",
"chars": 2028,
"preview": "package container\n\nimport (\n\t\"context\"\n\t\"testing\"\n\n\t\"github.com/docker/cli/cli/config\"\n\n\tlog \"github.com/sirupsen/logrus"
},
{
"path": "pkg/container/docker_run.go",
"chars": 24932,
"preview": "//go:build !(WITHOUT_DOCKER || !(linux || darwin || windows || netbsd))\n\npackage container\n\nimport (\n\t\"archive/tar\"\n\t\"by"
},
{
"path": "pkg/container/docker_run_test.go",
"chars": 7445,
"preview": "package container\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\t\"net\"\n\t\"strings\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com"
},
{
"path": "pkg/container/docker_socket.go",
"chars": 4725,
"preview": "package container\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\n\tlog \"github.com/sirupsen/logrus\"\n)\n\nvar CommonSoc"
},
{
"path": "pkg/container/docker_socket_test.go",
"chars": 4607,
"preview": "package container\n\nimport (\n\t\"os\"\n\t\"testing\"\n\n\tlog \"github.com/sirupsen/logrus\"\n\tassert \"github.com/stretchr/testify/ass"
},
{
"path": "pkg/container/docker_stub.go",
"chars": 2008,
"preview": "//go:build WITHOUT_DOCKER || !(linux || darwin || windows || netbsd)\n\npackage container\n\nimport (\n\t\"context\"\n\t\"runtime\"\n"
},
{
"path": "pkg/container/docker_volume.go",
"chars": 1150,
"preview": "//go:build !(WITHOUT_DOCKER || !(linux || darwin || windows || netbsd))\n\npackage container\n\nimport (\n\t\"context\"\n\n\t\"githu"
},
{
"path": "pkg/container/executions_environment.go",
"chars": 383,
"preview": "package container\n\nimport \"context\"\n\ntype ExecutionsEnvironment interface {\n\tContainer\n\tToContainerPath(string) string\n\t"
},
{
"path": "pkg/container/host_environment.go",
"chars": 10947,
"preview": "package container\n\nimport (\n\t\"archive/tar\"\n\t\"bytes\"\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"io/fs\"\n\t\"os\"\n\t\"os/exec\"\n\t\"path/f"
},
{
"path": "pkg/container/host_environment_test.go",
"chars": 1999,
"preview": "package container\n\nimport (\n\t\"archive/tar\"\n\t\"context\"\n\t\"io\"\n\t\"os\"\n\t\"path\"\n\t\"path/filepath\"\n\t\"testing\"\n\n\t\"github.com/stre"
},
{
"path": "pkg/container/linux_container_environment_extensions.go",
"chars": 2419,
"preview": "package container\n\nimport (\n\t\"context\"\n\t\"path/filepath\"\n\t\"regexp\"\n\t\"runtime\"\n\t\"strings\"\n\n\tlog \"github.com/sirupsen/logru"
},
{
"path": "pkg/container/linux_container_environment_extensions_test.go",
"chars": 1831,
"preview": "package container\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"runtime\"\n\t\"strings\"\n\t\"testing\"\n\n\tlog \"github.com/sirupsen/logrus\"\n\t\"github.co"
},
{
"path": "pkg/container/parse_env_file.go",
"chars": 1860,
"preview": "package container\n\nimport (\n\t\"archive/tar\"\n\t\"bufio\"\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\t\"strings\"\n\n\t\"github.com/nektos/act/pkg/comm"
},
{
"path": "pkg/container/testdata/Dockerfile",
"chars": 168,
"preview": "FROM scratch\nENV PATH=\"/this/path/does/not/exists/anywhere:/this/either\"\nENV SOME_RANDOM_VAR=\"\"\nENV ANOTHER_ONE=\"BUT_I_H"
},
{
"path": "pkg/container/testdata/docker-pull-options/config.json",
"chars": 129,
"preview": "{\n \"auths\": {\n \"https://index.docker.io/v1/\": {\n \"auth\": \"dXNlcm5hbWU6cGFzc3dvcmQK\"\n "
},
{
"path": "pkg/container/testdata/scratch/test.txt",
"chars": 8,
"preview": "testfile"
},
{
"path": "pkg/container/testdata/utf8.env",
"chars": 25,
"preview": "FOO=BAR\nHELLO=您好\nBAR=FOO"
},
{
"path": "pkg/container/testdata/valid.env",
"chars": 12,
"preview": "ENV1=value1\n"
},
{
"path": "pkg/container/testdata/valid.label",
"chars": 14,
"preview": "LABEL1=value1\n"
},
{
"path": "pkg/container/util.go",
"chars": 420,
"preview": "//go:build (!windows && !plan9 && !openbsd) || (!windows && !plan9 && !mips64)\n\npackage container\n\nimport (\n\t\"os\"\n\t\"sysc"
},
{
"path": "pkg/container/util_openbsd_mips64.go",
"chars": 271,
"preview": "package container\n\nimport (\n\t\"errors\"\n\t\"os\"\n\t\"syscall\"\n)\n\nfunc getSysProcAttr(cmdLine string, tty bool) *syscall.SysProc"
},
{
"path": "pkg/container/util_plan9.go",
"chars": 280,
"preview": "package container\n\nimport (\n\t\"errors\"\n\t\"os\"\n\t\"syscall\"\n)\n\nfunc getSysProcAttr(cmdLine string, tty bool) *syscall.SysProc"
},
{
"path": "pkg/container/util_windows.go",
"chars": 317,
"preview": "package container\n\nimport (\n\t\"errors\"\n\t\"os\"\n\t\"syscall\"\n)\n\nfunc getSysProcAttr(cmdLine string, tty bool) *syscall.SysProc"
},
{
"path": "pkg/exprparser/functions.go",
"chars": 7256,
"preview": "package exprparser\n\nimport (\n\t\"crypto/sha256\"\n\t\"encoding/hex\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"io/fs\"\n\t\"os\"\n\t\"path/filepa"
},
{
"path": "pkg/exprparser/functions_test.go",
"chars": 11134,
"preview": "package exprparser\n\nimport (\n\t\"path/filepath\"\n\t\"testing\"\n\n\t\"github.com/nektos/act/pkg/model\"\n\t\"github.com/stretchr/testi"
},
{
"path": "pkg/exprparser/interpreter.go",
"chars": 17041,
"preview": "package exprparser\n\nimport (\n\t\"encoding\"\n\t\"fmt\"\n\t\"math\"\n\t\"reflect\"\n\t\"strings\"\n\n\t\"github.com/nektos/act/pkg/model\"\n\t\"gith"
},
{
"path": "pkg/exprparser/interpreter_test.go",
"chars": 22660,
"preview": "package exprparser\n\nimport (\n\t\"math\"\n\t\"testing\"\n\n\t\"github.com/nektos/act/pkg/model\"\n\t\"github.com/stretchr/testify/assert"
},
{
"path": "pkg/exprparser/testdata/for-hashing-1.txt",
"chars": 6,
"preview": "Hello\n"
},
{
"path": "pkg/exprparser/testdata/for-hashing-2.txt",
"chars": 7,
"preview": "World!\n"
},
{
"path": "pkg/exprparser/testdata/for-hashing-3/data.txt",
"chars": 13,
"preview": "Knock knock!\n"
},
{
"path": "pkg/exprparser/testdata/for-hashing-3/nested/nested-data.txt",
"chars": 14,
"preview": "Anybody home?\n"
},
{
"path": "pkg/filecollector/file_collector.go",
"chars": 4936,
"preview": "package filecollector\n\nimport (\n\t\"archive/tar\"\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\t\"io/fs\"\n\t\"os\"\n\t\"path\"\n\t\"path/filepath\"\n\t\"strings"
},
{
"path": "pkg/filecollector/file_collector_test.go",
"chars": 4746,
"preview": "package filecollector\n\nimport (\n\t\"archive/tar\"\n\t\"context\"\n\t\"io\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/go-"
},
{
"path": "pkg/gh/gh.go",
"chars": 651,
"preview": "package gh\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"context\"\n\t\"os/exec\"\n)\n\nfunc GetToken(ctx context.Context, workingDirectory stri"
},
{
"path": "pkg/gh/gh_test.go",
"chars": 138,
"preview": "package gh\n\nimport (\n\t\"context\"\n\t\"testing\"\n)\n\nfunc TestGetToken(t *testing.T) {\n\ttoken, _ := GetToken(context.TODO(), \"\""
},
{
"path": "pkg/lookpath/LICENSE",
"chars": 1473,
"preview": "Copyright (c) 2009 The Go Authors. All rights reserved.\n\nRedistribution and use in source and binary forms, with or with"
},
{
"path": "pkg/lookpath/env.go",
"chars": 272,
"preview": "package lookpath\n\nimport \"os\"\n\ntype Env interface {\n\tGetenv(name string) string\n}\n\ntype defaultEnv struct {\n}\n\nfunc (*de"
},
{
"path": "pkg/lookpath/error.go",
"chars": 123,
"preview": "package lookpath\n\ntype Error struct {\n\tName string\n\tErr error\n}\n\nfunc (e *Error) Error() string {\n\treturn e.Err.Error()"
},
{
"path": "pkg/lookpath/lp_js.go",
"chars": 835,
"preview": "// Copyright 2018 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
},
{
"path": "pkg/lookpath/lp_plan9.go",
"chars": 1434,
"preview": "// Copyright 2011 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
},
{
"path": "pkg/lookpath/lp_unix.go",
"chars": 1641,
"preview": "// Copyright 2010 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
},
{
"path": "pkg/lookpath/lp_windows.go",
"chars": 2195,
"preview": "// Copyright 2010 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
},
{
"path": "pkg/model/action.go",
"chars": 4882,
"preview": "package model\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"strings\"\n\n\t\"github.com/nektos/act/pkg/schema\"\n\t\"gopkg.in/yaml.v3\"\n)\n\n// ActionRun"
},
{
"path": "pkg/model/anchors.go",
"chars": 828,
"preview": "package model\n\nimport (\n\t\"errors\"\n\n\t\"gopkg.in/yaml.v3\"\n)\n\nfunc resolveAliasesExt(node *yaml.Node, path map[*yaml.Node]bo"
},
{
"path": "pkg/model/anchors_test.go",
"chars": 1599,
"preview": "package model\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n\t\"gopkg.in/yaml.v3\"\n)\n\nfunc TestVerifyNilAlias"
},
{
"path": "pkg/model/github_context.go",
"chars": 7237,
"preview": "package model\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/nektos/act/pkg/common\"\n\t\"github.com/nektos/act/pkg/co"
},
{
"path": "pkg/model/github_context_test.go",
"chars": 4544,
"preview": "package model\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"testing\"\n\n\tlog \"github.com/sirupsen/logrus\"\n\t\"github.com/stretchr/testify/as"
},
{
"path": "pkg/model/job_context.go",
"chars": 256,
"preview": "package model\n\ntype JobContext struct {\n\tStatus string `json:\"status\"`\n\tContainer struct {\n\t\tID string `json:\"id"
},
{
"path": "pkg/model/planner.go",
"chars": 9399,
"preview": "package model\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"io/fs\"\n\t\"math\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"regexp\"\n\t\"sort\"\n\n\tlog \"github.com/sirupse"
},
{
"path": "pkg/model/planner_test.go",
"chars": 1856,
"preview": "package model\n\nimport (\n\t\"path/filepath\"\n\t\"testing\"\n\n\tlog \"github.com/sirupsen/logrus\"\n\t\"github.com/stretchr/testify/ass"
},
{
"path": "pkg/model/step_result.go",
"chars": 822,
"preview": "package model\n\nimport \"fmt\"\n\ntype stepStatus int\n\nconst (\n\tStepStatusSuccess stepStatus = iota\n\tStepStatusFailure\n\tStepS"
},
{
"path": "pkg/model/testdata/container-volumes/push.yml",
"chars": 491,
"preview": "name: Job Container\non: push\n\njobs:\n with-volumes:\n runs-on: ubuntu-latest\n container:\n image: node:16-buste"
},
{
"path": "pkg/model/testdata/empty-workflow/push.yml",
"chars": 0,
"preview": ""
},
{
"path": "pkg/model/testdata/invalid-job-name/invalid-1.yml",
"chars": 231,
"preview": "name: invalid-job-name-1\non: push\n\njobs:\n invalid-JOB-Name-v1.2.3-docker_hub:\n runs-on: ubuntu-latest\n steps:\n "
},
{
"path": "pkg/model/testdata/invalid-job-name/invalid-2.yml",
"chars": 140,
"preview": "name: invalid-job-name-2\non: push\n\njobs:\n 1234invalid-JOB-Name-v123-docker_hub:\n runs-on: ubuntu-latest\n steps:\n "
},
{
"path": "pkg/model/testdata/invalid-job-name/valid-1.yml",
"chars": 132,
"preview": "name: valid-job-name-1\non: push\n\njobs:\n valid-JOB-Name-v123-docker_hub:\n runs-on: ubuntu-latest\n steps:\n - r"
},
{
"path": "pkg/model/testdata/invalid-job-name/valid-2.yml",
"chars": 135,
"preview": "name: valid-job-name-2\non: push\n\njobs:\n ___valid-JOB-Name-v123-docker_hub:\n runs-on: ubuntu-latest\n steps:\n "
},
{
"path": "pkg/model/testdata/nested/success.yml",
"chars": 155,
"preview": "name: Hello World Workflow\non: push\n\njobs:\n hello-world:\n name: Hello World Job\n runs-on: ubuntu-latest\n steps"
},
{
"path": "pkg/model/testdata/nested/workflows/fail.yml",
"chars": 0,
"preview": ""
},
{
"path": "pkg/model/testdata/strategy/push.yml",
"chars": 1121,
"preview": "---\njobs:\n strategy-all:\n name: ${{ matrix.node-version }} | ${{ matrix.site }} | ${{ matrix.datacenter }}\n runs-"
},
{
"path": "pkg/model/workflow.go",
"chars": 20811,
"preview": "package model\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"reflect\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/nektos/act/pkg/c"
},
{
"path": "pkg/model/workflow_test.go",
"chars": 17203,
"preview": "package model\n\nimport (\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/requi"
},
{
"path": "pkg/runner/action.go",
"chars": 21828,
"preview": "package runner\n\nimport (\n\t\"context\"\n\t\"embed\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"io/fs\"\n\t\"os\"\n\t\"path\"\n\t\"path/filepath\"\n\t\"regexp\"\n\t\""
},
{
"path": "pkg/runner/action_cache.go",
"chars": 6399,
"preview": "package runner\n\nimport (\n\t\"archive/tar\"\n\t\"context\"\n\t\"crypto/rand\"\n\t\"encoding/hex\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"io/fs\"\n\t\"path"
},
{
"path": "pkg/runner/action_cache_offline_mode.go",
"chars": 1332,
"preview": "package runner\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"path\"\n\n\tgit \"github.com/go-git/go-git/v5\"\n\t\"github.com/go-git/go-git/v5/plum"
},
{
"path": "pkg/runner/action_cache_test.go",
"chars": 3068,
"preview": "package runner\n\nimport (\n\t\"archive/tar\"\n\t\"bytes\"\n\t\"context\"\n\t\"io\"\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert"
},
{
"path": "pkg/runner/action_composite.go",
"chars": 6905,
"preview": "package runner\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"regexp\"\n\t\"strings\"\n\n\t\"github.com/nektos/act/pkg/common\"\n\t\"github.com/nektos"
},
{
"path": "pkg/runner/action_test.go",
"chars": 5313,
"preview": "package runner\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"io/fs\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/nektos/act/pkg/model\"\n\t\"github.co"
},
{
"path": "pkg/runner/command.go",
"chars": 5370,
"preview": "package runner\n\nimport (\n\t\"context\"\n\t\"regexp\"\n\t\"strings\"\n\n\t\"github.com/nektos/act/pkg/common\"\n\n\t\"github.com/sirupsen/log"
},
{
"path": "pkg/runner/command_test.go",
"chars": 4611,
"preview": "package runner\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"io\"\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/sirupsen/logrus/hooks/test\"\n\t\"github.c"
},
{
"path": "pkg/runner/container_mock_test.go",
"chars": 2180,
"preview": "package runner\n\nimport (\n\t\"context\"\n\t\"io\"\n\n\t\"github.com/nektos/act/pkg/common\"\n\t\"github.com/nektos/act/pkg/container\"\n\t\""
},
{
"path": "pkg/runner/expression.go",
"chars": 16425,
"preview": "package runner\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"fmt\"\n\t\"path\"\n\t\"reflect\"\n\t\"regexp\"\n\t\"strings\"\n\t\"time\"\n\n\t_ \"embed\"\n\n\t\"githu"
},
{
"path": "pkg/runner/expression_test.go",
"chars": 11721,
"preview": "package runner\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\t\"regexp\"\n\t\"sort\"\n\t\"testing\"\n\n\t\"github.com/nektos/act/pkg/exprparser\"\n\t"
},
{
"path": "pkg/runner/hashfiles/index.js",
"chars": 168437,
"preview": "/******/ (() => { // webpackBootstrap\n/******/ \tvar __webpack_modules__ = ({\n\n/***/ 2627:\n/***/ (function(__unused_webpa"
},
{
"path": "pkg/runner/job_executor.go",
"chars": 6934,
"preview": "package runner\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"time\"\n\n\t\"github.com/nektos/act/pkg/common\"\n\t\"github.com/nektos/act/pkg/mode"
},
{
"path": "pkg/runner/job_executor_test.go",
"chars": 8006,
"preview": "package runner\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\t\"testing\"\n\n\t\"github.com/nektos/act/pkg/common\"\n\t\"github.com/nektos/act"
},
{
"path": "pkg/runner/local_repository_cache.go",
"chars": 3025,
"preview": "package runner\n\nimport (\n\t\"archive/tar\"\n\t\"bytes\"\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\t\"io/fs\"\n\tgoURL \"net/url\"\n\t\"os\"\n\t\"path/filepath"
},
{
"path": "pkg/runner/logger.go",
"chars": 6406,
"preview": "package runner\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"strings\"\n\t\"sync\"\n\n\t\"github.com/nektos/act/pkg/common\"\n"
},
{
"path": "pkg/runner/res/trampoline.js",
"chars": 304,
"preview": "const { spawnSync } = require('child_process')\nconst spawnArguments = {\n cwd: process.env.INPUT_CWD,\n stdio: [\n pro"
},
{
"path": "pkg/runner/reusable_workflow.go",
"chars": 5184,
"preview": "package runner\n\nimport (\n\t\"archive/tar\"\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io/fs\"\n\t\"os\"\n\t\"path\"\n\t\"regexp\"\n\t\"sync\"\n\n\t\"github.c"
},
{
"path": "pkg/runner/run_context.go",
"chars": 35525,
"preview": "package runner\n\nimport (\n\t\"archive/tar\"\n\t\"bufio\"\n\t\"bytes\"\n\t\"context\"\n\t\"crypto/rand\"\n\t\"crypto/sha256\"\n\t\"encoding/hex\"\n\t\"e"
},
{
"path": "pkg/runner/run_context_test.go",
"chars": 22075,
"preview": "package runner\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\t\"regexp\"\n\t\"runtime\"\n\t\"sort\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/golang"
},
{
"path": "pkg/runner/runner.go",
"chars": 11119,
"preview": "package runner\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"os\"\n\t\"runtime\"\n\n\tdocker_container \"github.com/docker/docke"
},
{
"path": "pkg/runner/runner_test.go",
"chars": 27810,
"preview": "package runner\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"path\"\n\t\"path/filepath\"\n\t\"run"
},
{
"path": "pkg/runner/step.go",
"chars": 11538,
"preview": "package runner\n\nimport (\n\t\"archive/tar\"\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"path\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\n\t\"githu"
},
{
"path": "pkg/runner/step_action_local.go",
"chars": 3662,
"preview": "package runner\n\nimport (\n\t\"archive/tar\"\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"io/fs\"\n\t\"os\"\n\t\"path\"\n\t\"path/filepath\"\n\n\t\"git"
},
{
"path": "pkg/runner/step_action_local_test.go",
"chars": 7523,
"preview": "package runner\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"io\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/nektos/act/pkg/c"
},
{
"path": "pkg/runner/step_action_remote.go",
"chars": 10071,
"preview": "package runner\n\nimport (\n\t\"archive/tar\"\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"path\"\n\t\"path/filepath\"\n\t\"regexp\"\n\t\"str"
},
{
"path": "pkg/runner/step_action_remote_test.go",
"chars": 15746,
"preview": "package runner\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"errors\"\n\t\"io\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert"
},
{
"path": "pkg/runner/step_docker.go",
"chars": 3750,
"preview": "package runner\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/kballard/go-shellquote\"\n\t\"github.com/nektos/act/pkg/"
},
{
"path": "pkg/runner/step_docker_test.go",
"chars": 2811,
"preview": "package runner\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"io\"\n\t\"testing\"\n\n\t\"github.com/nektos/act/pkg/container\"\n\t\"github.com/nekto"
},
{
"path": "pkg/runner/step_factory.go",
"chars": 1096,
"preview": "package runner\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/nektos/act/pkg/model\"\n)\n\ntype stepFactory interface {\n\tnewStep(step *model"
},
{
"path": "pkg/runner/step_factory_test.go",
"chars": 1357,
"preview": "package runner\n\nimport (\n\t\"testing\"\n\n\t\"github.com/nektos/act/pkg/model\"\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc Te"
},
{
"path": "pkg/runner/step_run.go",
"chars": 6471,
"preview": "package runner\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"runtime\"\n\t\"strings\"\n\n\t\"github.com/kballard/go-shellquote\"\n\n\t\"github.com/nek"
},
{
"path": "pkg/runner/step_run_test.go",
"chars": 2400,
"preview": "package runner\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"io\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretc"
},
{
"path": "pkg/runner/step_test.go",
"chars": 9652,
"preview": "package runner\n\nimport (\n\t\"context\"\n\t\"testing\"\n\n\t\"github.com/nektos/act/pkg/common\"\n\t\"github.com/nektos/act/pkg/model\"\n\t"
},
{
"path": "pkg/runner/testdata/.github/workflows/local-reusable-and-dispatch.yml",
"chars": 920,
"preview": "name: reuse\n\non:\n workflow_dispatch:\n inputs:\n my-val:\n type: string\n required: true\n defa"
},
{
"path": "pkg/runner/testdata/.github/workflows/local-reusable-workflow-no-inputs-array.yml",
"chars": 126,
"preview": "name: reusable\n\non:\n- workflow_call\n\njobs:\n reusable_workflow_job:\n runs-on: ubuntu-latest\n steps:\n - run: ech"
},
{
"path": "pkg/runner/testdata/.github/workflows/local-reusable-workflow-no-inputs-string.yml",
"chars": 124,
"preview": "name: reusable\n\non: workflow_call\n\njobs:\n reusable_workflow_job:\n runs-on: ubuntu-latest\n steps:\n - run: echo "
},
{
"path": "pkg/runner/testdata/.github/workflows/local-reusable-workflow.yml",
"chars": 2456,
"preview": "name: reusable\n\non:\n workflow_call:\n inputs:\n string_required:\n required: true\n type: string\n "
},
{
"path": "pkg/runner/testdata/GITHUB_ENV-use-in-env-ctx/push.yml",
"chars": 1016,
"preview": "on: push\njobs:\n _:\n runs-on: ubuntu-latest\n env:\n MYGLOBALENV3: myglobalval3\n steps:\n - run: |\n "
},
{
"path": "pkg/runner/testdata/GITHUB_STATE/push.yml",
"chars": 1461,
"preview": "on: push\njobs:\n _:\n runs-on: ubuntu-latest\n steps:\n - uses: nektos/act-test-actions/script@main\n with:\n "
},
{
"path": "pkg/runner/testdata/act-composite-env-test/action1/action.yml",
"chars": 448,
"preview": "name: action1\ndescription: action1\nruns:\n using: composite\n steps:\n - name: env.COMPOSITE_OVERRIDE != '1'\n run: ex"
}
]
// ... and 211 more files (download for full content)
About this extraction
This page contains the full source code of the nektos/act GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 411 files (2.5 MB), approximately 675.5k tokens, and a symbol index with 2450 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.