Compare commits
2 Commits
main
...
ethomson/u
Author | SHA1 | Date | |
---|---|---|---|
|
63aa003870 | ||
|
8dd2e77965 |
@ -1,6 +0,0 @@
|
|||||||
# Ignore list
|
|
||||||
/*
|
|
||||||
|
|
||||||
# Do not ignore these folders:
|
|
||||||
!__tests__/
|
|
||||||
!src/
|
|
51
.eslintrc.js
51
.eslintrc.js
@ -1,51 +0,0 @@
|
|||||||
// This is a reusable configuration file copied from https://github.com/actions/reusable-workflows/tree/main/reusable-configurations. Please don't make changes to this file as it's the subject of an automatic update.
|
|
||||||
module.exports = {
|
|
||||||
extends: [
|
|
||||||
'eslint:recommended',
|
|
||||||
'plugin:@typescript-eslint/recommended',
|
|
||||||
'plugin:eslint-plugin-jest/recommended',
|
|
||||||
'eslint-config-prettier'
|
|
||||||
],
|
|
||||||
parser: '@typescript-eslint/parser',
|
|
||||||
plugins: ['@typescript-eslint', 'eslint-plugin-node', 'eslint-plugin-jest'],
|
|
||||||
rules: {
|
|
||||||
'@typescript-eslint/no-require-imports': 'error',
|
|
||||||
'@typescript-eslint/no-non-null-assertion': 'off',
|
|
||||||
'@typescript-eslint/no-explicit-any': 'off',
|
|
||||||
'@typescript-eslint/no-empty-function': 'off',
|
|
||||||
'@typescript-eslint/ban-ts-comment': [
|
|
||||||
'error',
|
|
||||||
{
|
|
||||||
'ts-ignore': 'allow-with-description'
|
|
||||||
}
|
|
||||||
],
|
|
||||||
'no-console': 'error',
|
|
||||||
'yoda': 'error',
|
|
||||||
'prefer-const': [
|
|
||||||
'error',
|
|
||||||
{
|
|
||||||
destructuring: 'all'
|
|
||||||
}
|
|
||||||
],
|
|
||||||
'no-control-regex': 'off',
|
|
||||||
'no-constant-condition': ['error', {checkLoops: false}],
|
|
||||||
'node/no-extraneous-import': 'error'
|
|
||||||
},
|
|
||||||
overrides: [
|
|
||||||
{
|
|
||||||
files: ['**/*{test,spec}.ts'],
|
|
||||||
rules: {
|
|
||||||
'@typescript-eslint/no-unused-vars': 'off',
|
|
||||||
'jest/no-standalone-expect': 'off',
|
|
||||||
'jest/no-conditional-expect': 'off',
|
|
||||||
'no-console': 'off',
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
env: {
|
|
||||||
node: true,
|
|
||||||
es6: true,
|
|
||||||
'jest/globals': true
|
|
||||||
}
|
|
||||||
};
|
|
2
.gitattributes
vendored
2
.gitattributes
vendored
@ -1,2 +0,0 @@
|
|||||||
* text=auto eol=lf
|
|
||||||
.licenses/** -diff linguist-generated=true
|
|
38
.github/ISSUE_TEMPLATE/bug_report.md
vendored
38
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@ -1,38 +0,0 @@
|
|||||||
---
|
|
||||||
name: Bug report
|
|
||||||
about: Create a bug report
|
|
||||||
title: ''
|
|
||||||
labels: bug, needs triage
|
|
||||||
assignees: ''
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
<!--- Please direct any generic questions related to actions to our support community forum at https://github.community/c/code-to-cloud/github-actions/41 --->
|
|
||||||
<!--- Before opening up a new bug report, please make sure to check for similar existing issues -->
|
|
||||||
|
|
||||||
**Description:**
|
|
||||||
A clear and concise description of what the bug is.
|
|
||||||
|
|
||||||
**Action version:**
|
|
||||||
Specify the action version
|
|
||||||
|
|
||||||
**Platform:**
|
|
||||||
- [ ] Ubuntu
|
|
||||||
- [ ] macOS
|
|
||||||
- [ ] Windows
|
|
||||||
|
|
||||||
**Runner type:**
|
|
||||||
- [ ] Hosted
|
|
||||||
- [ ] Self-hosted
|
|
||||||
|
|
||||||
**Tools version:**
|
|
||||||
<!--- Please specify go version -->
|
|
||||||
|
|
||||||
**Repro steps:**
|
|
||||||
A description with steps to reproduce the issue. If your have a public example or repo to share, please provide the link.
|
|
||||||
|
|
||||||
**Expected behavior:**
|
|
||||||
A description of what you expected to happen.
|
|
||||||
|
|
||||||
**Actual behavior:**
|
|
||||||
A description of what is actually happening.
|
|
1
.github/ISSUE_TEMPLATE/config.yml
vendored
1
.github/ISSUE_TEMPLATE/config.yml
vendored
@ -1 +0,0 @@
|
|||||||
blank_issues_enabled: false
|
|
18
.github/ISSUE_TEMPLATE/feature_request.md
vendored
18
.github/ISSUE_TEMPLATE/feature_request.md
vendored
@ -1,18 +0,0 @@
|
|||||||
---
|
|
||||||
name: Feature request
|
|
||||||
about: Suggest an idea for this project
|
|
||||||
title: ''
|
|
||||||
labels: feature request, needs triage
|
|
||||||
assignees: ''
|
|
||||||
---
|
|
||||||
<!--- Please direct any generic questions related to actions to our support community forum at https://github.community/c/code-to-cloud/github-actions/41 --->
|
|
||||||
<!--- Before opening up a new feature request, please make sure to check for similar existing issues and pull requests -->
|
|
||||||
|
|
||||||
**Description:**
|
|
||||||
Describe your proposal.
|
|
||||||
|
|
||||||
**Justification:**
|
|
||||||
Justification or a use case for your proposal.
|
|
||||||
|
|
||||||
**Are you willing to submit a PR?**
|
|
||||||
<!--- We accept contributions! -->
|
|
16
.github/go.json
vendored
Normal file
16
.github/go.json
vendored
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"problemMatcher": [
|
||||||
|
{
|
||||||
|
"owner": "go",
|
||||||
|
"pattern": [
|
||||||
|
{
|
||||||
|
"regexp": "^([^:]*: )?((.:)?[^:]*):(\\d+)(:(\\d+))?: (.*)$",
|
||||||
|
"file": 2,
|
||||||
|
"line": 4,
|
||||||
|
"column": 6,
|
||||||
|
"message": 7
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
9
.github/pull_request_template.md
vendored
9
.github/pull_request_template.md
vendored
@ -1,9 +0,0 @@
|
|||||||
**Description:**
|
|
||||||
Describe your changes.
|
|
||||||
|
|
||||||
**Related issue:**
|
|
||||||
Add link to the related issue.
|
|
||||||
|
|
||||||
**Check list:**
|
|
||||||
- [ ] Mark if documentation changes are required.
|
|
||||||
- [ ] Mark if tests were added or updated to cover the changes.
|
|
18
.github/workflows/basic-validation.yml
vendored
18
.github/workflows/basic-validation.yml
vendored
@ -1,18 +0,0 @@
|
|||||||
name: Basic validation
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
paths-ignore:
|
|
||||||
- '**.md'
|
|
||||||
pull_request:
|
|
||||||
paths-ignore:
|
|
||||||
- '**.md'
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
call-basic-validation:
|
|
||||||
name: Basic validation
|
|
||||||
uses: actions/reusable-workflows/.github/workflows/basic-validation.yml@main
|
|
||||||
with:
|
|
||||||
node-version: '20'
|
|
19
.github/workflows/check-dist.yml
vendored
19
.github/workflows/check-dist.yml
vendored
@ -1,19 +0,0 @@
|
|||||||
name: Check dist/
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
paths-ignore:
|
|
||||||
- '**.md'
|
|
||||||
pull_request:
|
|
||||||
paths-ignore:
|
|
||||||
- '**.md'
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
call-check-dist:
|
|
||||||
name: Check dist/
|
|
||||||
uses: actions/reusable-workflows/.github/workflows/check-dist.yml@main
|
|
||||||
with:
|
|
||||||
node-version: '20'
|
|
14
.github/workflows/codeql-analysis.yml
vendored
14
.github/workflows/codeql-analysis.yml
vendored
@ -1,14 +0,0 @@
|
|||||||
name: CodeQL analysis
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [main]
|
|
||||||
pull_request:
|
|
||||||
branches: [main]
|
|
||||||
schedule:
|
|
||||||
- cron: '0 3 * * 0'
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
call-codeQL-analysis:
|
|
||||||
name: CodeQL analysis
|
|
||||||
uses: actions/reusable-workflows/.github/workflows/codeql-analysis.yml@main
|
|
14
.github/workflows/licensed.yml
vendored
14
.github/workflows/licensed.yml
vendored
@ -1,14 +0,0 @@
|
|||||||
name: Licensed
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
pull_request:
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
call-licensed:
|
|
||||||
name: Licensed
|
|
||||||
uses: actions/reusable-workflows/.github/workflows/licensed.yml@main
|
|
28
.github/workflows/release-new-action-version.yml
vendored
28
.github/workflows/release-new-action-version.yml
vendored
@ -1,28 +0,0 @@
|
|||||||
name: Release new action version
|
|
||||||
|
|
||||||
on:
|
|
||||||
release:
|
|
||||||
types: [released]
|
|
||||||
workflow_dispatch:
|
|
||||||
inputs:
|
|
||||||
TAG_NAME:
|
|
||||||
description: 'Tag name that the major tag will point to'
|
|
||||||
required: true
|
|
||||||
|
|
||||||
env:
|
|
||||||
TAG_NAME: ${{ github.event.inputs.TAG_NAME || github.event.release.tag_name }}
|
|
||||||
permissions:
|
|
||||||
contents: write
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
update_tag:
|
|
||||||
name: Update the major tag to include the ${{ github.event.inputs.TAG_NAME || github.event.release.tag_name }} changes
|
|
||||||
environment:
|
|
||||||
name: releaseNewActionVersion
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Update the ${{ env.TAG_NAME }} tag
|
|
||||||
uses: actions/publish-action@v0.2.2
|
|
||||||
with:
|
|
||||||
source-tag: ${{ env.TAG_NAME }}
|
|
||||||
slack-webhook: ${{ secrets.SLACK_WEBHOOK }}
|
|
11
.github/workflows/update-config-files.yml
vendored
11
.github/workflows/update-config-files.yml
vendored
@ -1,11 +0,0 @@
|
|||||||
name: Update configuration files
|
|
||||||
|
|
||||||
on:
|
|
||||||
schedule:
|
|
||||||
- cron: '0 3 * * 0'
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
call-update-configuration-files:
|
|
||||||
name: Update configuration files
|
|
||||||
uses: actions/reusable-workflows/.github/workflows/update-config-files.yml@main
|
|
194
.github/workflows/versions.yml
vendored
194
.github/workflows/versions.yml
vendored
@ -1,194 +0,0 @@
|
|||||||
name: Validate 'setup-go'
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
paths-ignore:
|
|
||||||
- '**.md'
|
|
||||||
pull_request:
|
|
||||||
paths-ignore:
|
|
||||||
- '**.md'
|
|
||||||
schedule:
|
|
||||||
- cron: 0 0 * * *
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
stable:
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
os: [ubuntu-latest, windows-latest, macos-latest]
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- name: Setup Go Stable
|
|
||||||
uses: ./
|
|
||||||
with:
|
|
||||||
go-version: stable
|
|
||||||
- name: Verify Go
|
|
||||||
run: go version
|
|
||||||
|
|
||||||
oldstable:
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
os: [ubuntu-latest, windows-latest, macos-latest]
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- name: Setup Go oldStable
|
|
||||||
uses: ./
|
|
||||||
with:
|
|
||||||
go-version: oldstable
|
|
||||||
- name: Verify Go
|
|
||||||
run: go version
|
|
||||||
|
|
||||||
aliases-arch:
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
os: [ubuntu-latest, windows-latest, macos-latest]
|
|
||||||
version: [stable, oldstable]
|
|
||||||
architecture: [x64, x32]
|
|
||||||
exclude:
|
|
||||||
- os: macos-latest
|
|
||||||
architecture: x32
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- name: Setup Go ${{ matrix.version }} ${{ matrix.architecture }}
|
|
||||||
uses: ./
|
|
||||||
with:
|
|
||||||
go-version: ${{ matrix.version }}
|
|
||||||
architecture: ${{ matrix.architecture }}
|
|
||||||
- name: Verify Go
|
|
||||||
run: go version
|
|
||||||
|
|
||||||
local-cache:
|
|
||||||
name: Setup local-cache version
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
os: [macos-latest, windows-latest, ubuntu-latest]
|
|
||||||
go: [1.20.14, 1.21.10, 1.22.3]
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: setup-go ${{ matrix.go }}
|
|
||||||
uses: ./
|
|
||||||
with:
|
|
||||||
go-version: ${{ matrix.go }}
|
|
||||||
|
|
||||||
- name: verify go
|
|
||||||
run: __tests__/verify-go.sh ${{ matrix.go }}
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
check-latest:
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
os: [ubuntu-latest, windows-latest, macos-latest]
|
|
||||||
go-version: [1.20.14, 1.21]
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- name: Setup Go and check latest
|
|
||||||
uses: ./
|
|
||||||
with:
|
|
||||||
go-version: ${{ matrix.go-version }}
|
|
||||||
check-latest: true
|
|
||||||
- name: Verify Go
|
|
||||||
run: go version
|
|
||||||
|
|
||||||
go-version-file:
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
os: [ubuntu-latest, windows-latest, macos-latest]
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- name: Setup Go and check latest
|
|
||||||
uses: ./
|
|
||||||
with:
|
|
||||||
go-version-file: __tests__/data/go.mod
|
|
||||||
- name: verify go
|
|
||||||
run: __tests__/verify-go.sh 1.20.14
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
go-version-file-with-gowork:
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
os: [ubuntu-latest, windows-latest, macos-latest]
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- name: Setup Go and check latest
|
|
||||||
uses: ./
|
|
||||||
with:
|
|
||||||
go-version-file: __tests__/data/go.work
|
|
||||||
- name: verify go
|
|
||||||
run: __tests__/verify-go.sh 1.21
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
setup-versions-from-manifest:
|
|
||||||
name: Setup ${{ matrix.go }} ${{ matrix.os }}
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
os: [macos-latest, windows-latest, ubuntu-latest]
|
|
||||||
go: [1.20.14, 1.21.10, 1.22.3]
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: setup-go ${{ matrix.go }}
|
|
||||||
uses: ./
|
|
||||||
with:
|
|
||||||
go-version: ${{ matrix.go }}
|
|
||||||
|
|
||||||
- name: verify go
|
|
||||||
run: __tests__/verify-go.sh ${{ matrix.go }}
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
setup-versions-from-dist:
|
|
||||||
name: Setup ${{ matrix.go }} ${{ matrix.os }}
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
os: [macos-latest, windows-latest, ubuntu-latest]
|
|
||||||
go: [1.20.14, 1.21]
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: setup-go ${{ matrix.go }}
|
|
||||||
uses: ./
|
|
||||||
with:
|
|
||||||
go-version: ${{ matrix.go }}
|
|
||||||
|
|
||||||
- name: verify go
|
|
||||||
run: __tests__/verify-go.sh ${{ matrix.go }}
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
architecture:
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
os: [ubuntu-latest, windows-latest, macos-latest]
|
|
||||||
go-version: [1.20.14, 1.21]
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- name: Setup Go and check latest
|
|
||||||
uses: ./
|
|
||||||
with:
|
|
||||||
go-version: ${{ matrix.go-version }}
|
|
||||||
architecture: x64
|
|
||||||
- name: Verify Go
|
|
||||||
run: go version
|
|
136
.github/workflows/windows-validation.yml
vendored
136
.github/workflows/windows-validation.yml
vendored
@ -1,136 +0,0 @@
|
|||||||
name: Validate Windows installation
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
paths-ignore:
|
|
||||||
- '**.md'
|
|
||||||
pull_request:
|
|
||||||
paths-ignore:
|
|
||||||
- '**.md'
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
create-link-if-not-default:
|
|
||||||
runs-on: windows-latest
|
|
||||||
name: 'Validate if symlink is created'
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
cache: [false, true]
|
|
||||||
go: [1.20.1]
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: 'Setup ${{ matrix.cache }}, cache: ${{ matrix.go }}'
|
|
||||||
uses: ./
|
|
||||||
with:
|
|
||||||
go-version: ${{ matrix.go }}
|
|
||||||
cache: ${{ matrix.cache }}
|
|
||||||
|
|
||||||
- name: 'Drive C: should have zero size link'
|
|
||||||
run: |
|
|
||||||
du -m -s 'C:\hostedtoolcache\windows\go\${{ matrix.go }}\x64'
|
|
||||||
# make sure drive c: contains only a link
|
|
||||||
size=$(du -m -s 'C:\hostedtoolcache\windows\go\${{ matrix.go }}\x64'|cut -f1 -d$'\t')
|
|
||||||
if [ $size -ne 0 ];then
|
|
||||||
echo 'Size of the link created on drive c: must be 0'
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
# Drive D: is small, take care the action does not eat up the space
|
|
||||||
- name: 'Drive D: space usage should be below 1G'
|
|
||||||
run: |
|
|
||||||
du -m -s 'D:\hostedtoolcache\windows\go\${{ matrix.go }}\x64'
|
|
||||||
size=$(du -m -s 'D:\hostedtoolcache\windows\go\${{ matrix.go }}\x64'|cut -f1 -d$'\t')
|
|
||||||
# make sure archive does not take lot of space
|
|
||||||
if [ $size -gt 999 ];then
|
|
||||||
echo 'Size of installed on drive d: go is too big';
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
# make sure the Go installation has not been changed to the end user
|
|
||||||
- name: Test paths and environments
|
|
||||||
run: |
|
|
||||||
echo $PATH
|
|
||||||
which go
|
|
||||||
go version
|
|
||||||
go env
|
|
||||||
if [ $(which go) != '/c/hostedtoolcache/windows/go/${{ matrix.go }}/x64/bin/go' ];then
|
|
||||||
echo 'which go should return "/c/hostedtoolcache/windows/go/${{ matrix.go }}/x64/bin/go"'
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
if [ $(go env GOROOT) != 'C:\hostedtoolcache\windows\go\${{ matrix.go }}\x64' ];then
|
|
||||||
echo 'go env GOROOT should return "C:\hostedtoolcache\windows\go\${{ matrix.go }}\x64"'
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
find-default-go:
|
|
||||||
name: 'Find default go version'
|
|
||||||
runs-on: windows-latest
|
|
||||||
outputs:
|
|
||||||
version: ${{ steps.goversion.outputs.version }}
|
|
||||||
steps:
|
|
||||||
- run: |
|
|
||||||
version=`go env GOVERSION|sed s/^go//`
|
|
||||||
echo "default go version: $version"
|
|
||||||
echo "version=$version" >> "$GITHUB_OUTPUT"
|
|
||||||
id: goversion
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
dont-create-link-if-default:
|
|
||||||
name: 'Validate if symlink is not created for default go'
|
|
||||||
runs-on: windows-latest
|
|
||||||
needs: find-default-go
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
cache: [false, true]
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: 'Setup default go, cache: ${{ matrix.cache }}'
|
|
||||||
uses: ./
|
|
||||||
with:
|
|
||||||
go-version: ${{ needs.find-default-go.outputs.version }}
|
|
||||||
cache: ${{ matrix.cache }}
|
|
||||||
|
|
||||||
- name: 'Drive C: should have Go installation, cache: ${{ matrix.cache}}'
|
|
||||||
run: |
|
|
||||||
size=$(du -m -s 'C:\hostedtoolcache\windows\go\${{ needs.find-default-go.outputs.version }}\x64'|cut -f1 -d$'\t')
|
|
||||||
if [ $size -eq 0 ];then
|
|
||||||
echo 'Size of the hosted go installed on drive c: must be above zero'
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
- name: 'Drive D: should not have Go installation, cache: ${{ matrix.cache }}'
|
|
||||||
run: |
|
|
||||||
if [ -e 'D:\hostedtoolcache\windows\go\${{ needs.find-default-go.outputs.version }}\x64' ];then
|
|
||||||
echo 'D:\hostedtoolcache\windows\go\${{ needs.find-default-go.outputs.version }}\x64 should not exist for hosted version of go';
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
hostedtoolcache:
|
|
||||||
name: 'Validate if hostedtoolcache works as expected'
|
|
||||||
runs-on: windows-latest
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
cache: [false]
|
|
||||||
go: [1.20.1]
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: 'Setup ${{ matrix.go }}, cache: ${{ matrix.cache }}'
|
|
||||||
uses: ./
|
|
||||||
with:
|
|
||||||
go-version: ${{ matrix.go }}
|
|
||||||
cache: ${{ matrix.cache }}
|
|
||||||
|
|
||||||
- name: 'Setup ${{ matrix.go }}, cache: ${{ matrix.cache }} (from hostedtoolcache)'
|
|
||||||
uses: ./
|
|
||||||
with:
|
|
||||||
go-version: ${{ matrix.go }}
|
|
||||||
cache: ${{ matrix.cache }}
|
|
26
.github/workflows/workflow.yml
vendored
Normal file
26
.github/workflows/workflow.yml
vendored
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
name: Main workflow
|
||||||
|
on: [push]
|
||||||
|
jobs:
|
||||||
|
run:
|
||||||
|
name: Run
|
||||||
|
runs-on: ${{ matrix.operating-system }}
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
operating-system: [ubuntu-latest, windows-latest]
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@master
|
||||||
|
|
||||||
|
- name: Set Node.js 10.x
|
||||||
|
uses: actions/setup-node@master
|
||||||
|
with:
|
||||||
|
version: 10.x
|
||||||
|
|
||||||
|
- name: npm install
|
||||||
|
run: npm install
|
||||||
|
|
||||||
|
- name: Lint
|
||||||
|
run: npm run format-check
|
||||||
|
|
||||||
|
- name: npm test
|
||||||
|
run: npm test
|
5
.gitignore
vendored
5
.gitignore
vendored
@ -1,5 +1,6 @@
|
|||||||
node_modules/
|
# Explicitly not ignoring node_modules so that they are included in package downloaded by runner
|
||||||
lib
|
!node_modules/
|
||||||
|
__tests__/runner/*
|
||||||
|
|
||||||
# Rest of the file pulled from https://github.com/github/gitignore/blob/master/Node.gitignore
|
# Rest of the file pulled from https://github.com/github/gitignore/blob/master/Node.gitignore
|
||||||
# Logs
|
# Logs
|
||||||
|
@ -1,15 +0,0 @@
|
|||||||
sources:
|
|
||||||
npm: true
|
|
||||||
|
|
||||||
allowed:
|
|
||||||
- apache-2.0
|
|
||||||
- bsd-2-clause
|
|
||||||
- bsd-3-clause
|
|
||||||
- isc
|
|
||||||
- mit
|
|
||||||
- cc0-1.0
|
|
||||||
- unlicense
|
|
||||||
- 0bsd
|
|
||||||
|
|
||||||
reviewed:
|
|
||||||
npm:
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,7 +0,0 @@
|
|||||||
# Ignore list
|
|
||||||
/*
|
|
||||||
|
|
||||||
# Do not ignore these folders:
|
|
||||||
!__tests__/
|
|
||||||
!.github/
|
|
||||||
!src/
|
|
@ -1,11 +0,0 @@
|
|||||||
// This is a reusable configuration file copied from https://github.com/actions/reusable-workflows/tree/main/reusable-configurations. Please don't make changes to this file as it's the subject of an automatic update.
|
|
||||||
module.exports = {
|
|
||||||
printWidth: 80,
|
|
||||||
tabWidth: 2,
|
|
||||||
useTabs: false,
|
|
||||||
semi: true,
|
|
||||||
singleQuote: true,
|
|
||||||
trailingComma: 'none',
|
|
||||||
bracketSpacing: false,
|
|
||||||
arrowParens: 'avoid'
|
|
||||||
};
|
|
11
.prettierrc.json
Normal file
11
.prettierrc.json
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"printWidth": 80,
|
||||||
|
"tabWidth": 2,
|
||||||
|
"useTabs": false,
|
||||||
|
"semi": true,
|
||||||
|
"singleQuote": true,
|
||||||
|
"trailingComma": "none",
|
||||||
|
"bracketSpacing": false,
|
||||||
|
"arrowParens": "avoid",
|
||||||
|
"parser": "typescript"
|
||||||
|
}
|
@ -1 +0,0 @@
|
|||||||
* @actions/setup-actions-team
|
|
@ -1,76 +0,0 @@
|
|||||||
# Contributor Covenant Code of Conduct
|
|
||||||
|
|
||||||
## Our Pledge
|
|
||||||
|
|
||||||
In the interest of fostering an open and welcoming environment, we as
|
|
||||||
contributors and maintainers pledge to make participation in our project and
|
|
||||||
our community a harassment-free experience for everyone, regardless of age, body
|
|
||||||
size, disability, ethnicity, sex characteristics, gender identity and expression,
|
|
||||||
level of experience, education, socio-economic status, nationality, personal
|
|
||||||
appearance, race, religion, or sexual identity and orientation.
|
|
||||||
|
|
||||||
## Our Standards
|
|
||||||
|
|
||||||
Examples of behavior that contributes to creating a positive environment
|
|
||||||
include:
|
|
||||||
|
|
||||||
* Using welcoming and inclusive language
|
|
||||||
* Being respectful of differing viewpoints and experiences
|
|
||||||
* Gracefully accepting constructive criticism
|
|
||||||
* Focusing on what is best for the community
|
|
||||||
* Showing empathy towards other community members
|
|
||||||
|
|
||||||
Examples of unacceptable behavior by participants include:
|
|
||||||
|
|
||||||
* The use of sexualized language or imagery and unwelcome sexual attention or
|
|
||||||
advances
|
|
||||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
|
||||||
* Public or private harassment
|
|
||||||
* Publishing others' private information, such as a physical or electronic
|
|
||||||
address, without explicit permission
|
|
||||||
* Other conduct which could reasonably be considered inappropriate in a
|
|
||||||
professional setting
|
|
||||||
|
|
||||||
## Our Responsibilities
|
|
||||||
|
|
||||||
Project maintainers are responsible for clarifying the standards of acceptable
|
|
||||||
behavior and are expected to take appropriate and fair corrective action in
|
|
||||||
response to any instances of unacceptable behavior.
|
|
||||||
|
|
||||||
Project maintainers have the right and responsibility to remove, edit, or
|
|
||||||
reject comments, commits, code, wiki edits, issues, and other contributions
|
|
||||||
that are not aligned to this Code of Conduct, or to ban temporarily or
|
|
||||||
permanently any contributor for other behaviors that they deem inappropriate,
|
|
||||||
threatening, offensive, or harmful.
|
|
||||||
|
|
||||||
## Scope
|
|
||||||
|
|
||||||
This Code of Conduct applies within all project spaces, and it also applies when
|
|
||||||
an individual is representing the project or its community in public spaces.
|
|
||||||
Examples of representing a project or community include using an official
|
|
||||||
project e-mail address, posting via an official social media account, or acting
|
|
||||||
as an appointed representative at an online or offline event. Representation of
|
|
||||||
a project may be further defined and clarified by project maintainers.
|
|
||||||
|
|
||||||
## Enforcement
|
|
||||||
|
|
||||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
|
||||||
reported by contacting the project team at opensource+actions/setup-go@github.com. All
|
|
||||||
complaints will be reviewed and investigated and will result in a response that
|
|
||||||
is deemed necessary and appropriate to the circumstances. The project team is
|
|
||||||
obligated to maintain confidentiality with regard to the reporter of an incident.
|
|
||||||
Further details of specific enforcement policies may be posted separately.
|
|
||||||
|
|
||||||
Project maintainers who do not follow or enforce the Code of Conduct in good
|
|
||||||
faith may face temporary or permanent repercussions as determined by other
|
|
||||||
members of the project's leadership.
|
|
||||||
|
|
||||||
## Attribution
|
|
||||||
|
|
||||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
|
||||||
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
|
|
||||||
|
|
||||||
[homepage]: https://www.contributor-covenant.org
|
|
||||||
|
|
||||||
For answers to common questions about this code of conduct, see
|
|
||||||
https://www.contributor-covenant.org/faq
|
|
264
README.md
264
README.md
@ -1,280 +1,50 @@
|
|||||||
# setup-go
|
# setup-go
|
||||||
|
|
||||||
[![Basic validation](https://github.com/actions/setup-go/actions/workflows/basic-validation.yml/badge.svg)](https://github.com/actions/setup-go/actions/workflows/basic-validation.yml)
|
<p align="left">
|
||||||
[![Validate 'setup-go'](https://github.com/actions/setup-go/actions/workflows/versions.yml/badge.svg)](https://github.com/actions/setup-go/actions/workflows/versions.yml)
|
<a href="https://github.com/actions/setup-go"><img alt="GitHub Actions status" src="https://github.com/actions/setup-go/workflows/Main%20workflow/badge.svg"></a>
|
||||||
|
</p>
|
||||||
|
|
||||||
This action sets up a go environment for use in actions by:
|
This action sets up a go environment for use in actions by:
|
||||||
|
|
||||||
- Optionally downloading and caching a version of Go by version and adding to `PATH`.
|
- optionally downloading and caching a version of Go by version and adding to PATH
|
||||||
- Registering problem matchers for error output.
|
- registering problem matchers for error output
|
||||||
|
|
||||||
# V5
|
|
||||||
|
|
||||||
The V5 edition of the action offers:
|
|
||||||
|
|
||||||
- Upgraded Node.js runtime from node16 to node20
|
|
||||||
|
|
||||||
See full release notes on the [releases page](https://github.com/actions/setup-go/releases).
|
|
||||||
|
|
||||||
# V4
|
|
||||||
|
|
||||||
The V4 edition of the action offers:
|
|
||||||
|
|
||||||
- Enabled caching by default
|
|
||||||
|
|
||||||
The action will try to enable caching unless the `cache` input is explicitly set to false.
|
|
||||||
|
|
||||||
Please see "[Caching dependency files and build outputs](https://github.com/actions/setup-go#caching-dependency-files-and-build-outputs)" for more information.
|
|
||||||
|
|
||||||
# V3
|
|
||||||
|
|
||||||
The V3 edition of the action offers:
|
|
||||||
|
|
||||||
- Adds `GOBIN` to the `PATH`
|
|
||||||
- Proxy support
|
|
||||||
- Check latest version
|
|
||||||
- Caching packages dependencies
|
|
||||||
- stable and oldstable aliases
|
|
||||||
- Bug Fixes (including issues around version matching and semver)
|
|
||||||
|
|
||||||
The action will first check the local cache for a version match. If a version is not found locally, it will pull it from
|
|
||||||
the `main` branch of the [go-versions](https://github.com/actions/go-versions/blob/main/versions-manifest.json)
|
|
||||||
repository. On miss or failure, it will fall back to downloading directly
|
|
||||||
from [go dist](https://storage.googleapis.com/golang). To change the default behavior, please use
|
|
||||||
the [check-latest input](#check-latest-version).
|
|
||||||
|
|
||||||
**Note:** The `setup-go` action uses executable binaries which are built by Golang side. The action does not build
|
|
||||||
golang from source code.
|
|
||||||
|
|
||||||
Matching by [semver spec](https://github.com/npm/node-semver):
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- uses: actions/setup-go@v5
|
|
||||||
with:
|
|
||||||
go-version: '^1.13.1' # The Go version to download (if necessary) and use.
|
|
||||||
- run: go version
|
|
||||||
```
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- uses: actions/setup-go@v5
|
|
||||||
with:
|
|
||||||
go-version: '>=1.17.0'
|
|
||||||
- run: go version
|
|
||||||
```
|
|
||||||
|
|
||||||
> **Note**: Due to the peculiarities of YAML parsing, it is recommended to wrap the version in single quotation marks:
|
|
||||||
>
|
|
||||||
> ```yaml
|
|
||||||
> go-version: '1.20'
|
|
||||||
> ```
|
|
||||||
>
|
|
||||||
> The recommendation is based on the YAML parser's behavior, which interprets non-wrapped values as numbers and, in the case of version 1.20, trims it down to 1.2, which may not be very obvious.
|
|
||||||
|
|
||||||
Matching an unstable pre-release:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- uses: actions/setup-go@v5
|
|
||||||
with:
|
|
||||||
go-version: '1.18.0-rc.1' # The Go version to download (if necessary) and use.
|
|
||||||
- run: go version
|
|
||||||
```
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- uses: actions/setup-go@v5
|
|
||||||
with:
|
|
||||||
go-version: '1.16.0-beta.1' # The Go version to download (if necessary) and use.
|
|
||||||
- run: go version
|
|
||||||
```
|
|
||||||
|
|
||||||
# Usage
|
# Usage
|
||||||
|
|
||||||
See [action.yml](action.yml)
|
See [action.yml](action.yml)
|
||||||
|
|
||||||
## Basic
|
Basic:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v1
|
||||||
- uses: actions/setup-go@v5
|
- uses: actions/setup-go@v1
|
||||||
with:
|
with:
|
||||||
go-version: '1.16.1' # The Go version to download (if necessary) and use.
|
go-version: '1.9.3' # The Go version to download (if necessary) and use.
|
||||||
- run: go run hello.go
|
- run: go run hello.go
|
||||||
```
|
```
|
||||||
|
|
||||||
## Check latest version
|
Matrix Testing:
|
||||||
|
|
||||||
The `check-latest` flag defaults to `false`. Use the default or set `check-latest` to `false` if you prefer stability
|
|
||||||
and if you want to ensure a specific Go version is always used.
|
|
||||||
|
|
||||||
If `check-latest` is set to `true`, the action first checks if the cached version is the latest one. If the locally
|
|
||||||
cached version is not the most up-to-date, a Go version will then be downloaded. Set `check-latest` to `true` if you
|
|
||||||
want the most up-to-date Go version to always be used.
|
|
||||||
|
|
||||||
> Setting `check-latest` to `true` has performance implications as downloading Go versions is slower than using cached
|
|
||||||
> versions.
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- uses: actions/setup-go@v5
|
|
||||||
with:
|
|
||||||
go-version: '1.14'
|
|
||||||
check-latest: true
|
|
||||||
- run: go run hello.go
|
|
||||||
```
|
|
||||||
|
|
||||||
## Using stable/oldstable aliases
|
|
||||||
|
|
||||||
If `stable` is provided, action will get the latest stable version from
|
|
||||||
the [`go-versions`](https://github.com/actions/go-versions/blob/main/versions-manifest.json) repository manifest.
|
|
||||||
|
|
||||||
If `oldstable` is provided, when current release is 1.19.x, action will resolve version as 1.18.x, where x is the latest
|
|
||||||
patch release.
|
|
||||||
|
|
||||||
**Note:** using these aliases will result in same version as using corresponding minor release with `check-latest` input
|
|
||||||
set to `true`
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- uses: actions/setup-go@v5
|
|
||||||
with:
|
|
||||||
go-version: 'stable'
|
|
||||||
- run: go run hello.go
|
|
||||||
```
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- uses: actions/setup-go@v5
|
|
||||||
with:
|
|
||||||
go-version: 'oldstable'
|
|
||||||
- run: go run hello.go
|
|
||||||
```
|
|
||||||
|
|
||||||
## Caching dependency files and build outputs:
|
|
||||||
|
|
||||||
The action has a built-in functionality for caching and restoring go modules and build outputs. It
|
|
||||||
uses [toolkit/cache](https://github.com/actions/toolkit/tree/main/packages/cache) under the hood but requires less configuration settings.
|
|
||||||
The `cache` input is optional, and caching is turned on by default.
|
|
||||||
|
|
||||||
The action defaults to search for the dependency file - go.sum in the repository root, and uses its hash as a part of
|
|
||||||
the cache key. Use `cache-dependency-path` input for cases when multiple dependency files are used, or they are located
|
|
||||||
in different subdirectories. The input supports glob patterns.
|
|
||||||
|
|
||||||
If some problem that prevents success caching happens then the action issues the warning in the log and continues the execution of the pipeline.
|
|
||||||
|
|
||||||
**Caching in monorepos**
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- uses: actions/setup-go@v5
|
|
||||||
with:
|
|
||||||
go-version: '1.17'
|
|
||||||
check-latest: true
|
|
||||||
cache-dependency-path: |
|
|
||||||
subdir/go.sum
|
|
||||||
tools/go.sum
|
|
||||||
# cache-dependency-path: "**/*.sum"
|
|
||||||
|
|
||||||
- run: go run hello.go
|
|
||||||
```
|
|
||||||
|
|
||||||
## Getting go version from the go.mod file
|
|
||||||
|
|
||||||
The `go-version-file` input accepts a path to a `go.mod` file or a `go.work` file that contains the version of Go to be used by a project.
|
|
||||||
|
|
||||||
The `go` directive in `go.mod` can specify a patch version or omit it altogether (e.g., `go 1.22.0` or `go 1.22`).
|
|
||||||
If a patch version is specified, that specific patch version will be used.
|
|
||||||
If no patch version is specified, it will search for the latest available patch version in the cache,
|
|
||||||
[versions-manifest.json](https://github.com/actions/go-versions/blob/main/versions-manifest.json), and the
|
|
||||||
[official Go language website](https://golang.org/dl/?mode=json&include=all), in that order.
|
|
||||||
|
|
||||||
If both the `go-version` and the `go-version-file` inputs are provided then the `go-version` input is used.
|
|
||||||
> The action will search for the `go.mod` file relative to the repository root
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- uses: actions/setup-go@v5
|
|
||||||
with:
|
|
||||||
go-version-file: 'path/to/go.mod'
|
|
||||||
- run: go version
|
|
||||||
```
|
|
||||||
|
|
||||||
## Matrix testing
|
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-16.04
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
go: [ '1.14', '1.13' ]
|
go: [ '1.8', '1.9.3', '1.10.x' ]
|
||||||
name: Go ${{ matrix.go }} sample
|
name: Go ${{ matrix.go }} sample
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v1
|
||||||
- name: Setup go
|
- name: Setup go
|
||||||
uses: actions/setup-go@v5
|
uses: actions/setup-go@v1
|
||||||
with:
|
with:
|
||||||
go-version: ${{ matrix.go }}
|
go-version: ${{ matrix.go }}
|
||||||
- run: go run hello.go
|
- run: go run hello.go
|
||||||
```
|
```
|
||||||
|
|
||||||
### Supported version syntax
|
|
||||||
|
|
||||||
The `go-version` input supports the following syntax:
|
|
||||||
|
|
||||||
- Specific versions: `1.15`, `1.16.1`, `1.17.0-rc.2`, `1.16.0-beta.1`
|
|
||||||
- SemVer's version range syntax: `^1.13.1`, `>=1.18.0-rc.1`
|
|
||||||
|
|
||||||
For more information about semantic versioning, please refer to [semver](https://github.com/npm/node-semver)
|
|
||||||
documentation.
|
|
||||||
|
|
||||||
## Using `setup-go` on GHES
|
|
||||||
|
|
||||||
`setup-go` comes pre-installed on the appliance with GHES if Actions is enabled. When dynamically downloading Go
|
|
||||||
distributions, `setup-go` downloads distributions from [`actions/go-versions`](https://github.com/actions/go-versions)
|
|
||||||
on github.com (outside of the appliance). These calls to `actions/go-versions` are made via unauthenticated requests,
|
|
||||||
which are limited
|
|
||||||
to [60 requests per hour per IP](https://docs.github.com/en/rest/overview/resources-in-the-rest-api#rate-limiting). If
|
|
||||||
more requests are made within the time frame, then you will start to see rate-limit errors during downloading that looks
|
|
||||||
like: `##[error]API rate limit exceeded for...`. After that error the action will try to download versions directly
|
|
||||||
from https://storage.googleapis.com/golang, but it also can have rate limit so it's better to put token.
|
|
||||||
|
|
||||||
To get a higher rate limit, you
|
|
||||||
can [generate a personal access token on github.com](https://github.com/settings/tokens/new) and pass it as the `token`
|
|
||||||
input for the action:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
uses: actions/setup-go@v5
|
|
||||||
with:
|
|
||||||
token: ${{ secrets.GH_DOTCOM_TOKEN }}
|
|
||||||
go-version: '1.18'
|
|
||||||
```
|
|
||||||
|
|
||||||
If the runner is not able to access github.com, any Go versions requested during a workflow run must come from the
|
|
||||||
runner's tool cache.
|
|
||||||
See "[Setting up the tool cache on self-hosted runners without internet access](https://docs.github.com/en/enterprise-server@3.2/admin/github-actions/managing-access-to-actions-from-githubcom/setting-up-the-tool-cache-on-self-hosted-runners-without-internet-access)"
|
|
||||||
for more information.
|
|
||||||
|
|
||||||
# License
|
# License
|
||||||
|
|
||||||
The scripts and documentation in this project are released under the [MIT License](LICENSE)
|
The scripts and documentation in this project are released under the [MIT License](LICENSE)
|
||||||
|
|
||||||
# Contributions
|
# Contributions
|
||||||
|
|
||||||
Contributions are welcome! See [Contributor's Guide](docs/contributors.md)
|
Contributions are welcome! See [Contributor's Guide](docs/contributors.md)
|
||||||
|
|
||||||
## Code of Conduct
|
|
||||||
|
|
||||||
:wave: Be nice. See [our code of conduct](CODE_OF_CONDUCT.md)
|
|
||||||
|
@ -1,99 +0,0 @@
|
|||||||
import * as cache from '@actions/cache';
|
|
||||||
import * as core from '@actions/core';
|
|
||||||
import * as glob from '@actions/glob';
|
|
||||||
|
|
||||||
import * as cacheRestore from '../src/cache-restore';
|
|
||||||
import * as cacheUtils from '../src/cache-utils';
|
|
||||||
import {PackageManagerInfo} from '../src/package-managers';
|
|
||||||
|
|
||||||
describe('restoreCache', () => {
|
|
||||||
//Arrange
|
|
||||||
const hashFilesSpy = jest.spyOn(glob, 'hashFiles');
|
|
||||||
const getCacheDirectoryPathSpy = jest.spyOn(
|
|
||||||
cacheUtils,
|
|
||||||
'getCacheDirectoryPath'
|
|
||||||
);
|
|
||||||
const restoreCacheSpy = jest.spyOn(cache, 'restoreCache');
|
|
||||||
const infoSpy = jest.spyOn(core, 'info');
|
|
||||||
const setOutputSpy = jest.spyOn(core, 'setOutput');
|
|
||||||
|
|
||||||
const versionSpec = '1.13.1';
|
|
||||||
const packageManager = 'default';
|
|
||||||
const cacheDependencyPath = 'path';
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
getCacheDirectoryPathSpy.mockImplementation(
|
|
||||||
(PackageManager: PackageManagerInfo) => {
|
|
||||||
return new Promise<string[]>(resolve => {
|
|
||||||
resolve(['cache_directory_path', 'cache_directory_path']);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should throw if dependency file path is not valid', async () => {
|
|
||||||
//Arrange
|
|
||||||
hashFilesSpy.mockImplementation((somePath: string) => {
|
|
||||||
return new Promise<string>(resolve => {
|
|
||||||
resolve('');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
//Act + Assert
|
|
||||||
await expect(async () => {
|
|
||||||
await cacheRestore.restoreCache(
|
|
||||||
versionSpec,
|
|
||||||
packageManager,
|
|
||||||
cacheDependencyPath
|
|
||||||
);
|
|
||||||
}).rejects.toThrow(
|
|
||||||
'Some specified paths were not resolved, unable to cache dependencies.'
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should inform if cache hit is not occured', async () => {
|
|
||||||
//Arrange
|
|
||||||
hashFilesSpy.mockImplementation((somePath: string) => {
|
|
||||||
return new Promise<string>(resolve => {
|
|
||||||
resolve('file_hash');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
restoreCacheSpy.mockImplementation(() => {
|
|
||||||
return new Promise<string>(resolve => {
|
|
||||||
resolve('');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
//Act + Assert
|
|
||||||
await cacheRestore.restoreCache(
|
|
||||||
versionSpec,
|
|
||||||
packageManager,
|
|
||||||
cacheDependencyPath
|
|
||||||
);
|
|
||||||
expect(infoSpy).toHaveBeenCalledWith(`Cache is not found`);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should set output if cache hit is occured', async () => {
|
|
||||||
//Arrange
|
|
||||||
hashFilesSpy.mockImplementation((somePath: string) => {
|
|
||||||
return new Promise<string>(resolve => {
|
|
||||||
resolve('file_hash');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
restoreCacheSpy.mockImplementation(() => {
|
|
||||||
return new Promise<string>(resolve => {
|
|
||||||
resolve('cache_key');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
//Act + Assert
|
|
||||||
await cacheRestore.restoreCache(
|
|
||||||
versionSpec,
|
|
||||||
packageManager,
|
|
||||||
cacheDependencyPath
|
|
||||||
);
|
|
||||||
expect(setOutputSpy).toHaveBeenCalledWith('cache-hit', true);
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,211 +0,0 @@
|
|||||||
import * as exec from '@actions/exec';
|
|
||||||
import * as cache from '@actions/cache';
|
|
||||||
import * as core from '@actions/core';
|
|
||||||
import * as cacheUtils from '../src/cache-utils';
|
|
||||||
import {PackageManagerInfo} from '../src/package-managers';
|
|
||||||
|
|
||||||
describe('getCommandOutput', () => {
|
|
||||||
//Arrange
|
|
||||||
const getExecOutputSpy = jest.spyOn(exec, 'getExecOutput');
|
|
||||||
|
|
||||||
it('should return trimmed stdout in case of successful exit code', async () => {
|
|
||||||
//Arrange
|
|
||||||
const stdoutResult = ' stdout ';
|
|
||||||
const trimmedStdout = stdoutResult.trim();
|
|
||||||
|
|
||||||
getExecOutputSpy.mockImplementation((commandLine: string) => {
|
|
||||||
return new Promise<exec.ExecOutput>(resolve => {
|
|
||||||
resolve({exitCode: 0, stdout: stdoutResult, stderr: ''});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
//Act + Assert
|
|
||||||
return cacheUtils
|
|
||||||
.getCommandOutput('command')
|
|
||||||
.then(data => expect(data).toBe(trimmedStdout));
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return error in case of unsuccessful exit code', async () => {
|
|
||||||
//Arrange
|
|
||||||
const stderrResult = 'error message';
|
|
||||||
|
|
||||||
getExecOutputSpy.mockImplementation((commandLine: string) => {
|
|
||||||
return new Promise<exec.ExecOutput>(resolve => {
|
|
||||||
resolve({exitCode: 10, stdout: '', stderr: stderrResult});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
//Act + Assert
|
|
||||||
await expect(async () => {
|
|
||||||
await cacheUtils.getCommandOutput('command');
|
|
||||||
}).rejects.toThrow();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('getPackageManagerInfo', () => {
|
|
||||||
it('should return package manager info in case of valid package manager name', async () => {
|
|
||||||
//Arrange
|
|
||||||
const packageManagerName = 'default';
|
|
||||||
const expectedResult = {
|
|
||||||
dependencyFilePattern: 'go.sum',
|
|
||||||
cacheFolderCommandList: ['go env GOMODCACHE', 'go env GOCACHE']
|
|
||||||
};
|
|
||||||
|
|
||||||
//Act + Assert
|
|
||||||
return cacheUtils
|
|
||||||
.getPackageManagerInfo(packageManagerName)
|
|
||||||
.then(data => expect(data).toEqual(expectedResult));
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should throw the error in case of invalid package manager name', async () => {
|
|
||||||
//Arrange
|
|
||||||
const packageManagerName = 'invalidName';
|
|
||||||
|
|
||||||
//Act + Assert
|
|
||||||
await expect(async () => {
|
|
||||||
await cacheUtils.getPackageManagerInfo(packageManagerName);
|
|
||||||
}).rejects.toThrow();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('getCacheDirectoryPath', () => {
|
|
||||||
//Arrange
|
|
||||||
const getExecOutputSpy = jest.spyOn(exec, 'getExecOutput');
|
|
||||||
|
|
||||||
const validPackageManager: PackageManagerInfo = {
|
|
||||||
dependencyFilePattern: 'go.sum',
|
|
||||||
cacheFolderCommandList: ['go env GOMODCACHE', 'go env GOCACHE']
|
|
||||||
};
|
|
||||||
|
|
||||||
it('should return path to the cache folders which specified package manager uses', async () => {
|
|
||||||
//Arrange
|
|
||||||
getExecOutputSpy.mockImplementation((commandLine: string) => {
|
|
||||||
return new Promise<exec.ExecOutput>(resolve => {
|
|
||||||
resolve({exitCode: 0, stdout: 'path/to/cache/folder', stderr: ''});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
const expectedResult = ['path/to/cache/folder', 'path/to/cache/folder'];
|
|
||||||
|
|
||||||
//Act + Assert
|
|
||||||
return cacheUtils
|
|
||||||
.getCacheDirectoryPath(validPackageManager)
|
|
||||||
.then(data => expect(data).toEqual(expectedResult));
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return path to the cache folder if one command return empty str', async () => {
|
|
||||||
//Arrange
|
|
||||||
getExecOutputSpy.mockImplementationOnce((commandLine: string) => {
|
|
||||||
return new Promise<exec.ExecOutput>(resolve => {
|
|
||||||
resolve({exitCode: 0, stdout: 'path/to/cache/folder', stderr: ''});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
getExecOutputSpy.mockImplementationOnce((commandLine: string) => {
|
|
||||||
return new Promise<exec.ExecOutput>(resolve => {
|
|
||||||
resolve({exitCode: 0, stdout: '', stderr: ''});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
const expectedResult = ['path/to/cache/folder'];
|
|
||||||
|
|
||||||
//Act + Assert
|
|
||||||
return cacheUtils
|
|
||||||
.getCacheDirectoryPath(validPackageManager)
|
|
||||||
.then(data => expect(data).toEqual(expectedResult));
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should throw if the both commands return empty str', async () => {
|
|
||||||
getExecOutputSpy.mockImplementation((commandLine: string) => {
|
|
||||||
return new Promise<exec.ExecOutput>(resolve => {
|
|
||||||
resolve({exitCode: 10, stdout: '', stderr: ''});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
//Act + Assert
|
|
||||||
await expect(async () => {
|
|
||||||
await cacheUtils.getCacheDirectoryPath(validPackageManager);
|
|
||||||
}).rejects.toThrow();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should throw if the specified package name is invalid', async () => {
|
|
||||||
getExecOutputSpy.mockImplementation((commandLine: string) => {
|
|
||||||
return new Promise<exec.ExecOutput>(resolve => {
|
|
||||||
resolve({exitCode: 10, stdout: '', stderr: 'Error message'});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
//Act + Assert
|
|
||||||
await expect(async () => {
|
|
||||||
await cacheUtils.getCacheDirectoryPath(validPackageManager);
|
|
||||||
}).rejects.toThrow();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('isCacheFeatureAvailable', () => {
|
|
||||||
//Arrange
|
|
||||||
const isFeatureAvailableSpy = jest.spyOn(cache, 'isFeatureAvailable');
|
|
||||||
const warningSpy = jest.spyOn(core, 'warning');
|
|
||||||
|
|
||||||
it('should return true when cache feature is available', () => {
|
|
||||||
//Arrange
|
|
||||||
isFeatureAvailableSpy.mockImplementation(() => {
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
//Act
|
|
||||||
const functionResult = cacheUtils.isCacheFeatureAvailable();
|
|
||||||
|
|
||||||
//Assert
|
|
||||||
expect(functionResult).toBeTruthy();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should warn when cache feature is unavailable and GHES is not used', () => {
|
|
||||||
//Arrange
|
|
||||||
isFeatureAvailableSpy.mockImplementation(() => {
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
process.env['GITHUB_SERVER_URL'] = 'https://github.com';
|
|
||||||
|
|
||||||
const warningMessage =
|
|
||||||
'The runner was not able to contact the cache service. Caching will be skipped';
|
|
||||||
|
|
||||||
//Act
|
|
||||||
cacheUtils.isCacheFeatureAvailable();
|
|
||||||
|
|
||||||
//Assert
|
|
||||||
expect(warningSpy).toHaveBeenCalledWith(warningMessage);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return false when cache feature is unavailable', () => {
|
|
||||||
//Arrange
|
|
||||||
isFeatureAvailableSpy.mockImplementation(() => {
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
process.env['GITHUB_SERVER_URL'] = 'https://github.com';
|
|
||||||
|
|
||||||
//Act
|
|
||||||
const functionResult = cacheUtils.isCacheFeatureAvailable();
|
|
||||||
|
|
||||||
//Assert
|
|
||||||
expect(functionResult).toBeFalsy();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should warn when cache feature is unavailable and GHES is used', () => {
|
|
||||||
//Arrange
|
|
||||||
isFeatureAvailableSpy.mockImplementation(() => {
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
process.env['GITHUB_SERVER_URL'] = 'https://nongithub.com';
|
|
||||||
|
|
||||||
const warningMessage =
|
|
||||||
'Cache action is only supported on GHES version >= 3.5. If you are on version >=3.5 Please check with GHES admin if Actions cache service is enabled or not.';
|
|
||||||
|
|
||||||
//Act + Assert
|
|
||||||
expect(cacheUtils.isCacheFeatureAvailable()).toBeFalsy();
|
|
||||||
expect(warningSpy).toHaveBeenCalledWith(warningMessage);
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,12 +0,0 @@
|
|||||||
module example.com/mymodule
|
|
||||||
|
|
||||||
go 1.20
|
|
||||||
|
|
||||||
require (
|
|
||||||
example.com/othermodule v1.2.3
|
|
||||||
example.com/thismodule v1.2.3
|
|
||||||
example.com/thatmodule v1.2.3
|
|
||||||
)
|
|
||||||
|
|
||||||
replace example.com/thatmodule => ../thatmodule
|
|
||||||
exclude example.com/thismodule v1.3.0
|
|
@ -1,3 +0,0 @@
|
|||||||
go 1.21
|
|
||||||
|
|
||||||
use .
|
|
File diff suppressed because it is too large
Load Diff
@ -1,102 +0,0 @@
|
|||||||
[
|
|
||||||
{
|
|
||||||
"version": "1.17.6",
|
|
||||||
"stable": true,
|
|
||||||
"release_url": "https://github.com/actions/go-versions/releases/tag/1.17.6-1668090892",
|
|
||||||
"files": [
|
|
||||||
{
|
|
||||||
"filename": "go-1.17.6-darwin-x64.tar.gz",
|
|
||||||
"arch": "x64",
|
|
||||||
"platform": "darwin",
|
|
||||||
"download_url": "https://github.com/actions/go-versions/releases/download/1.17.6-1668090892/go-1.17.6-darwin-x64.tar.gz"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"filename": "go-1.17.6-linux-x64.tar.gz",
|
|
||||||
"arch": "x64",
|
|
||||||
"platform": "linux",
|
|
||||||
"download_url": "https://github.com/actions/go-versions/releases/download/1.17.6-1668090892/go-1.17.6-linux-x64.tar.gz"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"filename": "go-1.17.6-win32-x64.zip",
|
|
||||||
"arch": "x64",
|
|
||||||
"platform": "win32",
|
|
||||||
"download_url": "https://github.com/actions/go-versions/releases/download/1.17.6-1668090892/go-1.17.6-win32-x64.zip"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "1.12.17",
|
|
||||||
"stable": true,
|
|
||||||
"release_url": "https://github.com/actions/go-versions/releases/tag/1.12.17-20200616.21",
|
|
||||||
"files": [
|
|
||||||
{
|
|
||||||
"filename": "go-1.12.17-darwin-x64.tar.gz",
|
|
||||||
"arch": "x64",
|
|
||||||
"platform": "darwin",
|
|
||||||
"download_url": "https://github.com/actions/go-versions/releases/download/1.12.17-20200616.21/go-1.12.17-darwin-x64.tar.gz"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"filename": "go-1.12.17-linux-x64.tar.gz",
|
|
||||||
"arch": "x64",
|
|
||||||
"platform": "linux",
|
|
||||||
"download_url": "https://github.com/actions/go-versions/releases/download/1.12.17-20200616.21/go-1.12.17-linux-x64.tar.gz"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"filename": "go-1.12.17-win32-x64.zip",
|
|
||||||
"arch": "x64",
|
|
||||||
"platform": "win32",
|
|
||||||
"download_url": "https://github.com/actions/go-versions/releases/download/1.12.17-20200616.21/go-1.12.17-win32-x64.zip"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "1.12.16",
|
|
||||||
"stable": true,
|
|
||||||
"release_url": "https://github.com/actions/go-versions/releases/tag/1.12.16-20200616.20",
|
|
||||||
"files": [
|
|
||||||
{
|
|
||||||
"filename": "go-1.12.16-darwin-x64.tar.gz",
|
|
||||||
"arch": "x64",
|
|
||||||
"platform": "darwin",
|
|
||||||
"download_url": "https://github.com/actions/go-versions/releases/download/1.12.16-20200616.20/go-1.12.16-darwin-x64.tar.gz"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"filename": "go-1.12.16-linux-x64.tar.gz",
|
|
||||||
"arch": "x64",
|
|
||||||
"platform": "linux",
|
|
||||||
"download_url": "https://github.com/actions/go-versions/releases/download/1.12.16-20200616.20/go-1.12.16-linux-x64.tar.gz"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"filename": "go-1.12.16-win32-x64.zip",
|
|
||||||
"arch": "x64",
|
|
||||||
"platform": "win32",
|
|
||||||
"download_url": "https://github.com/actions/go-versions/releases/download/1.12.16-20200616.20/go-1.12.16-win32-x64.zip"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "1.9.7",
|
|
||||||
"stable": true,
|
|
||||||
"release_url": "https://github.com/actions/go-versions/releases/tag/1.9.7-20200616.1",
|
|
||||||
"files": [
|
|
||||||
{
|
|
||||||
"filename": "go-1.9.7-darwin-x64.tar.gz",
|
|
||||||
"arch": "x64",
|
|
||||||
"platform": "darwin",
|
|
||||||
"download_url": "https://github.com/actions/go-versions/releases/download/1.9.7/go-1.9.7-darwin-x64.tar.gz"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"filename": "go-1.9.7-linux-x64.tar.gz",
|
|
||||||
"arch": "x64",
|
|
||||||
"platform": "linux",
|
|
||||||
"download_url": "https://github.com/actions/go-versions/releases/download/1.9.7/go-1.9.7-linux-x64.tar.gz"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"filename": "go-1.9.7-win32-x64.zip",
|
|
||||||
"arch": "x64",
|
|
||||||
"platform": "win32",
|
|
||||||
"download_url": "https://github.com/actions/go-versions/releases/download/1.9.7/go-1.9.7-win32-x64.zip"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
126
__tests__/installer.test.ts
Normal file
126
__tests__/installer.test.ts
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
import io = require('@actions/io');
|
||||||
|
import fs = require('fs');
|
||||||
|
import os = require('os');
|
||||||
|
import path = require('path');
|
||||||
|
import nock = require('nock');
|
||||||
|
|
||||||
|
const toolDir = path.join(__dirname, 'runner', 'tools');
|
||||||
|
const tempDir = path.join(__dirname, 'runner', 'temp');
|
||||||
|
const dataDir = path.join(__dirname, 'data');
|
||||||
|
|
||||||
|
process.env['RUNNER_TOOL_CACHE'] = toolDir;
|
||||||
|
process.env['RUNNER_TEMP'] = tempDir;
|
||||||
|
import * as installer from '../src/installer';
|
||||||
|
|
||||||
|
const IS_WINDOWS = process.platform === 'win32';
|
||||||
|
|
||||||
|
describe('installer tests', () => {
|
||||||
|
beforeAll(async () => {
|
||||||
|
await io.rmRF(toolDir);
|
||||||
|
await io.rmRF(tempDir);
|
||||||
|
}, 100000);
|
||||||
|
|
||||||
|
afterAll(async () => {
|
||||||
|
try {
|
||||||
|
await io.rmRF(toolDir);
|
||||||
|
await io.rmRF(tempDir);
|
||||||
|
} catch {
|
||||||
|
console.log('Failed to remove test directories');
|
||||||
|
}
|
||||||
|
}, 100000);
|
||||||
|
|
||||||
|
it('Acquires version of go if no matching version is installed', async () => {
|
||||||
|
await installer.getGo('1.10.8');
|
||||||
|
const goDir = path.join(toolDir, 'go', '1.10.8', os.arch());
|
||||||
|
|
||||||
|
expect(fs.existsSync(`${goDir}.complete`)).toBe(true);
|
||||||
|
if (IS_WINDOWS) {
|
||||||
|
expect(fs.existsSync(path.join(goDir, 'bin', 'go.exe'))).toBe(true);
|
||||||
|
} else {
|
||||||
|
expect(fs.existsSync(path.join(goDir, 'bin', 'go'))).toBe(true);
|
||||||
|
}
|
||||||
|
}, 100000);
|
||||||
|
|
||||||
|
describe('the latest release of a go version', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
nock('https://golang.org')
|
||||||
|
.get('/dl/')
|
||||||
|
.query({mode: 'json', include: 'all'})
|
||||||
|
.replyWithFile(200, path.join(dataDir, 'golang-dl.json'));
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
nock.cleanAll();
|
||||||
|
nock.enableNetConnect();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Acquires latest release version of go 1.10 if using 1.10 and no matching version is installed', async () => {
|
||||||
|
await installer.getGo('1.10');
|
||||||
|
const goDir = path.join(toolDir, 'go', '1.10.8', os.arch());
|
||||||
|
|
||||||
|
expect(fs.existsSync(`${goDir}.complete`)).toBe(true);
|
||||||
|
if (IS_WINDOWS) {
|
||||||
|
expect(fs.existsSync(path.join(goDir, 'bin', 'go.exe'))).toBe(true);
|
||||||
|
} else {
|
||||||
|
expect(fs.existsSync(path.join(goDir, 'bin', 'go'))).toBe(true);
|
||||||
|
}
|
||||||
|
}, 100000);
|
||||||
|
|
||||||
|
it('Acquires latest release version of go 1.10 if using 1.10.x and no matching version is installed', async () => {
|
||||||
|
await installer.getGo('1.10.x');
|
||||||
|
const goDir = path.join(toolDir, 'go', '1.10.8', os.arch());
|
||||||
|
|
||||||
|
expect(fs.existsSync(`${goDir}.complete`)).toBe(true);
|
||||||
|
if (IS_WINDOWS) {
|
||||||
|
expect(fs.existsSync(path.join(goDir, 'bin', 'go.exe'))).toBe(true);
|
||||||
|
} else {
|
||||||
|
expect(fs.existsSync(path.join(goDir, 'bin', 'go'))).toBe(true);
|
||||||
|
}
|
||||||
|
}, 100000);
|
||||||
|
|
||||||
|
it('Acquires latest release version of go if using 1.x and no matching version is installed', async () => {
|
||||||
|
await installer.getGo('1.x');
|
||||||
|
const goDir = path.join(toolDir, 'go', '1.13.0', os.arch());
|
||||||
|
|
||||||
|
expect(fs.existsSync(`${goDir}.complete`)).toBe(true);
|
||||||
|
if (IS_WINDOWS) {
|
||||||
|
expect(fs.existsSync(path.join(goDir, 'bin', 'go.exe'))).toBe(true);
|
||||||
|
} else {
|
||||||
|
expect(fs.existsSync(path.join(goDir, 'bin', 'go'))).toBe(true);
|
||||||
|
}
|
||||||
|
}, 100000);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Throws if no location contains correct go version', async () => {
|
||||||
|
let thrown = false;
|
||||||
|
try {
|
||||||
|
await installer.getGo('1000.0');
|
||||||
|
} catch {
|
||||||
|
thrown = true;
|
||||||
|
}
|
||||||
|
expect(thrown).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Uses version of go installed in cache', async () => {
|
||||||
|
const goDir: string = path.join(toolDir, 'go', '250.0.0', os.arch());
|
||||||
|
await io.mkdirP(goDir);
|
||||||
|
fs.writeFileSync(`${goDir}.complete`, 'hello');
|
||||||
|
// This will throw if it doesn't find it in the cache (because no such version exists)
|
||||||
|
await installer.getGo('250.0');
|
||||||
|
return;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Doesnt use version of go that was only partially installed in cache', async () => {
|
||||||
|
const goDir: string = path.join(toolDir, 'go', '251.0.0', os.arch());
|
||||||
|
await io.mkdirP(goDir);
|
||||||
|
let thrown = false;
|
||||||
|
try {
|
||||||
|
// This will throw if it doesn't find it in the cache (because no such version exists)
|
||||||
|
await installer.getGo('251.0');
|
||||||
|
} catch {
|
||||||
|
thrown = true;
|
||||||
|
}
|
||||||
|
expect(thrown).toBe(true);
|
||||||
|
return;
|
||||||
|
});
|
||||||
|
});
|
@ -1,969 +0,0 @@
|
|||||||
import * as core from '@actions/core';
|
|
||||||
import * as io from '@actions/io';
|
|
||||||
import * as tc from '@actions/tool-cache';
|
|
||||||
import fs from 'fs';
|
|
||||||
import cp from 'child_process';
|
|
||||||
import osm, {type} from 'os';
|
|
||||||
import path from 'path';
|
|
||||||
import * as main from '../src/main';
|
|
||||||
import * as im from '../src/installer';
|
|
||||||
|
|
||||||
import goJsonData from './data/golang-dl.json';
|
|
||||||
import matchers from '../matchers.json';
|
|
||||||
import goTestManifest from './data/versions-manifest.json';
|
|
||||||
const matcherPattern = matchers.problemMatcher[0].pattern[0];
|
|
||||||
const matcherRegExp = new RegExp(matcherPattern.regexp);
|
|
||||||
const win32Join = path.win32.join;
|
|
||||||
const posixJoin = path.posix.join;
|
|
||||||
|
|
||||||
jest.setTimeout(10000);
|
|
||||||
|
|
||||||
describe('setup-go', () => {
|
|
||||||
let inputs = {} as any;
|
|
||||||
let os = {} as any;
|
|
||||||
|
|
||||||
let inSpy: jest.SpyInstance;
|
|
||||||
let getBooleanInputSpy: jest.SpyInstance;
|
|
||||||
let exportVarSpy: jest.SpyInstance;
|
|
||||||
let findSpy: jest.SpyInstance;
|
|
||||||
let cnSpy: jest.SpyInstance;
|
|
||||||
let logSpy: jest.SpyInstance;
|
|
||||||
let getSpy: jest.SpyInstance;
|
|
||||||
let platSpy: jest.SpyInstance;
|
|
||||||
let archSpy: jest.SpyInstance;
|
|
||||||
let joinSpy: jest.SpyInstance;
|
|
||||||
let dlSpy: jest.SpyInstance;
|
|
||||||
let extractTarSpy: jest.SpyInstance;
|
|
||||||
let extractZipSpy: jest.SpyInstance;
|
|
||||||
let cacheSpy: jest.SpyInstance;
|
|
||||||
let dbgSpy: jest.SpyInstance;
|
|
||||||
let whichSpy: jest.SpyInstance;
|
|
||||||
let existsSpy: jest.SpyInstance;
|
|
||||||
let readFileSpy: jest.SpyInstance;
|
|
||||||
let mkdirpSpy: jest.SpyInstance;
|
|
||||||
let mkdirSpy: jest.SpyInstance;
|
|
||||||
let symlinkSpy: jest.SpyInstance;
|
|
||||||
let execSpy: jest.SpyInstance;
|
|
||||||
let getManifestSpy: jest.SpyInstance;
|
|
||||||
let getAllVersionsSpy: jest.SpyInstance;
|
|
||||||
|
|
||||||
beforeAll(async () => {
|
|
||||||
process.env['GITHUB_ENV'] = ''; // Stub out Environment file functionality so we can verify it writes to standard out (toolkit is backwards compatible)
|
|
||||||
}, 100000);
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
process.env['GITHUB_PATH'] = ''; // Stub out ENV file functionality so we can verify it writes to standard out
|
|
||||||
|
|
||||||
// @actions/core
|
|
||||||
inputs = {};
|
|
||||||
inSpy = jest.spyOn(core, 'getInput');
|
|
||||||
inSpy.mockImplementation(name => inputs[name]);
|
|
||||||
getBooleanInputSpy = jest.spyOn(core, 'getBooleanInput');
|
|
||||||
getBooleanInputSpy.mockImplementation(name => inputs[name]);
|
|
||||||
exportVarSpy = jest.spyOn(core, 'exportVariable');
|
|
||||||
|
|
||||||
// node
|
|
||||||
os = {};
|
|
||||||
platSpy = jest.spyOn(osm, 'platform');
|
|
||||||
platSpy.mockImplementation(() => os['platform']);
|
|
||||||
archSpy = jest.spyOn(osm, 'arch');
|
|
||||||
archSpy.mockImplementation(() => os['arch']);
|
|
||||||
execSpy = jest.spyOn(cp, 'execSync');
|
|
||||||
|
|
||||||
// switch path join behaviour based on set os.platform
|
|
||||||
joinSpy = jest.spyOn(path, 'join');
|
|
||||||
joinSpy.mockImplementation((...paths: string[]): string => {
|
|
||||||
if (os['platform'] == 'win32') {
|
|
||||||
return win32Join(...paths);
|
|
||||||
}
|
|
||||||
|
|
||||||
return posixJoin(...paths);
|
|
||||||
});
|
|
||||||
|
|
||||||
// @actions/tool-cache
|
|
||||||
findSpy = jest.spyOn(tc, 'find');
|
|
||||||
dlSpy = jest.spyOn(tc, 'downloadTool');
|
|
||||||
extractTarSpy = jest.spyOn(tc, 'extractTar');
|
|
||||||
extractZipSpy = jest.spyOn(tc, 'extractZip');
|
|
||||||
cacheSpy = jest.spyOn(tc, 'cacheDir');
|
|
||||||
getSpy = jest.spyOn(im, 'getVersionsDist');
|
|
||||||
getManifestSpy = jest.spyOn(tc, 'getManifestFromRepo');
|
|
||||||
getAllVersionsSpy = jest.spyOn(im, 'getManifest');
|
|
||||||
|
|
||||||
// io
|
|
||||||
whichSpy = jest.spyOn(io, 'which');
|
|
||||||
existsSpy = jest.spyOn(fs, 'existsSync');
|
|
||||||
readFileSpy = jest.spyOn(fs, 'readFileSync');
|
|
||||||
mkdirpSpy = jest.spyOn(io, 'mkdirP');
|
|
||||||
|
|
||||||
// fs
|
|
||||||
mkdirSpy = jest.spyOn(fs, 'mkdir');
|
|
||||||
symlinkSpy = jest.spyOn(fs, 'symlinkSync');
|
|
||||||
symlinkSpy.mockImplementation(() => {});
|
|
||||||
|
|
||||||
// gets
|
|
||||||
getManifestSpy.mockImplementation(() => <tc.IToolRelease[]>goTestManifest);
|
|
||||||
|
|
||||||
// writes
|
|
||||||
cnSpy = jest.spyOn(process.stdout, 'write');
|
|
||||||
logSpy = jest.spyOn(core, 'info');
|
|
||||||
dbgSpy = jest.spyOn(core, 'debug');
|
|
||||||
getSpy.mockImplementation(() => <im.IGoVersion[] | null>goJsonData);
|
|
||||||
cnSpy.mockImplementation(line => {
|
|
||||||
// uncomment to debug
|
|
||||||
// process.stderr.write('write:' + line + '\n');
|
|
||||||
});
|
|
||||||
logSpy.mockImplementation(line => {
|
|
||||||
// uncomment to debug
|
|
||||||
//process.stderr.write('log:' + line + '\n');
|
|
||||||
});
|
|
||||||
dbgSpy.mockImplementation(msg => {
|
|
||||||
// uncomment to see debug output
|
|
||||||
// process.stderr.write(msg + '\n');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
afterEach(() => {
|
|
||||||
//jest.resetAllMocks();
|
|
||||||
jest.clearAllMocks();
|
|
||||||
//jest.restoreAllMocks();
|
|
||||||
});
|
|
||||||
|
|
||||||
afterAll(async () => {
|
|
||||||
jest.restoreAllMocks();
|
|
||||||
}, 100000);
|
|
||||||
|
|
||||||
it('can extract the major.minor.patch version from a given Go version string', async () => {
|
|
||||||
const goVersionOutput = 'go version go1.16.6 darwin/amd64';
|
|
||||||
expect(main.parseGoVersion(goVersionOutput)).toBe('1.16.6');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('can find 1.9.7 from manifest on osx', async () => {
|
|
||||||
os.platform = 'darwin';
|
|
||||||
os.arch = 'x64';
|
|
||||||
|
|
||||||
const match = await im.getInfoFromManifest('1.9.7', true, 'mocktoken');
|
|
||||||
expect(match).toBeDefined();
|
|
||||||
expect(match!.resolvedVersion).toBe('1.9.7');
|
|
||||||
expect(match!.type).toBe('manifest');
|
|
||||||
expect(match!.downloadUrl).toBe(
|
|
||||||
'https://github.com/actions/go-versions/releases/download/1.9.7/go-1.9.7-darwin-x64.tar.gz'
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('can find 1.9 from manifest on linux', async () => {
|
|
||||||
os.platform = 'linux';
|
|
||||||
os.arch = 'x64';
|
|
||||||
|
|
||||||
const match = await im.getInfoFromManifest('1.9.7', true, 'mocktoken');
|
|
||||||
expect(match).toBeDefined();
|
|
||||||
expect(match!.resolvedVersion).toBe('1.9.7');
|
|
||||||
expect(match!.type).toBe('manifest');
|
|
||||||
expect(match!.downloadUrl).toBe(
|
|
||||||
'https://github.com/actions/go-versions/releases/download/1.9.7/go-1.9.7-linux-x64.tar.gz'
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('can find 1.9 from manifest on windows', async () => {
|
|
||||||
os.platform = 'win32';
|
|
||||||
os.arch = 'x64';
|
|
||||||
|
|
||||||
const match = await im.getInfoFromManifest('1.9.7', true, 'mocktoken');
|
|
||||||
expect(match).toBeDefined();
|
|
||||||
expect(match!.resolvedVersion).toBe('1.9.7');
|
|
||||||
expect(match!.type).toBe('manifest');
|
|
||||||
expect(match!.downloadUrl).toBe(
|
|
||||||
'https://github.com/actions/go-versions/releases/download/1.9.7/go-1.9.7-win32-x64.zip'
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('finds stable match for exact dot zero version', async () => {
|
|
||||||
os.platform = 'darwin';
|
|
||||||
os.arch = 'x64';
|
|
||||||
|
|
||||||
// spec: 1.13.0 => 1.13
|
|
||||||
const match: im.IGoVersion | undefined = await im.findMatch('1.13.0');
|
|
||||||
expect(match).toBeDefined();
|
|
||||||
const version: string = match ? match.version : '';
|
|
||||||
expect(version).toBe('go1.13');
|
|
||||||
const fileName = match ? match.files[0].filename : '';
|
|
||||||
expect(fileName).toBe('go1.13.darwin-amd64.tar.gz');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('finds latest patch version for minor version spec', async () => {
|
|
||||||
os.platform = 'linux';
|
|
||||||
os.arch = 'x64';
|
|
||||||
|
|
||||||
// spec: 1.13 => 1.13.7 (latest)
|
|
||||||
const match: im.IGoVersion | undefined = await im.findMatch('1.13');
|
|
||||||
expect(match).toBeDefined();
|
|
||||||
const version: string = match ? match.version : '';
|
|
||||||
expect(version).toBe('go1.13.7');
|
|
||||||
const fileName = match ? match.files[0].filename : '';
|
|
||||||
expect(fileName).toBe('go1.13.7.linux-amd64.tar.gz');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('finds latest patch version for caret version spec', async () => {
|
|
||||||
os.platform = 'linux';
|
|
||||||
os.arch = 'x64';
|
|
||||||
|
|
||||||
// spec: ^1.13.6 => 1.13.7
|
|
||||||
const match: im.IGoVersion | undefined = await im.findMatch('^1.13.6');
|
|
||||||
expect(match).toBeDefined();
|
|
||||||
const version: string = match ? match.version : '';
|
|
||||||
expect(version).toBe('go1.13.7');
|
|
||||||
const fileName = match ? match.files[0].filename : '';
|
|
||||||
expect(fileName).toBe('go1.13.7.linux-amd64.tar.gz');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('finds latest version for major version spec', async () => {
|
|
||||||
os.platform = 'win32';
|
|
||||||
os.arch = 'x32';
|
|
||||||
|
|
||||||
// spec: 1 => 1.13.7 (latest)
|
|
||||||
const match: im.IGoVersion | undefined = await im.findMatch('1');
|
|
||||||
expect(match).toBeDefined();
|
|
||||||
const version: string = match ? match.version : '';
|
|
||||||
expect(version).toBe('go1.13.7');
|
|
||||||
const fileName = match ? match.files[0].filename : '';
|
|
||||||
expect(fileName).toBe('go1.13.7.windows-386.zip');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('finds unstable pre-release version', async () => {
|
|
||||||
os.platform = 'linux';
|
|
||||||
os.arch = 'x64';
|
|
||||||
|
|
||||||
// spec: 1.14, stable=false => go1.14rc1
|
|
||||||
const match: im.IGoVersion | undefined = await im.findMatch('1.14.0-rc.1');
|
|
||||||
expect(match).toBeDefined();
|
|
||||||
const version: string = match ? match.version : '';
|
|
||||||
expect(version).toBe('go1.14rc1');
|
|
||||||
const fileName = match ? match.files[0].filename : '';
|
|
||||||
expect(fileName).toBe('go1.14rc1.linux-amd64.tar.gz');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('evaluates to stable with input as true', async () => {
|
|
||||||
inputs['go-version'] = '1.13.0';
|
|
||||||
inputs.stable = 'true';
|
|
||||||
|
|
||||||
const toolPath = path.normalize('/cache/go/1.13.0/x64');
|
|
||||||
findSpy.mockImplementation(() => toolPath);
|
|
||||||
await main.run();
|
|
||||||
|
|
||||||
expect(logSpy).toHaveBeenCalledWith(`Setup go version spec 1.13.0`);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('evaluates to stable with no input', async () => {
|
|
||||||
inputs['go-version'] = '1.13.0';
|
|
||||||
|
|
||||||
inSpy.mockImplementation(name => inputs[name]);
|
|
||||||
|
|
||||||
const toolPath = path.normalize('/cache/go/1.13.0/x64');
|
|
||||||
findSpy.mockImplementation(() => toolPath);
|
|
||||||
await main.run();
|
|
||||||
|
|
||||||
expect(logSpy).toHaveBeenCalledWith(`Setup go version spec 1.13.0`);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('does not export any variables for Go versions >=1.9', async () => {
|
|
||||||
inputs['go-version'] = '1.13.0';
|
|
||||||
inSpy.mockImplementation(name => inputs[name]);
|
|
||||||
|
|
||||||
const toolPath = path.normalize('/cache/go/1.13.0/x64');
|
|
||||||
findSpy.mockImplementation(() => toolPath);
|
|
||||||
|
|
||||||
const vars: {[key: string]: string} = {};
|
|
||||||
exportVarSpy.mockImplementation((name: string, val: string) => {
|
|
||||||
vars[name] = val;
|
|
||||||
});
|
|
||||||
|
|
||||||
await main.run();
|
|
||||||
expect(vars).toStrictEqual({});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('exports GOROOT for Go versions <1.9', async () => {
|
|
||||||
inputs['go-version'] = '1.8';
|
|
||||||
inSpy.mockImplementation(name => inputs[name]);
|
|
||||||
|
|
||||||
const toolPath = path.normalize('/cache/go/1.8.0/x64');
|
|
||||||
findSpy.mockImplementation(() => toolPath);
|
|
||||||
|
|
||||||
const vars: {[key: string]: string} = {};
|
|
||||||
exportVarSpy.mockImplementation((name: string, val: string) => {
|
|
||||||
vars[name] = val;
|
|
||||||
});
|
|
||||||
|
|
||||||
await main.run();
|
|
||||||
expect(vars).toStrictEqual({
|
|
||||||
GOROOT: toolPath
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('finds a version of go already in the cache', async () => {
|
|
||||||
inputs['go-version'] = '1.13.0';
|
|
||||||
|
|
||||||
const toolPath = path.normalize('/cache/go/1.13.0/x64');
|
|
||||||
findSpy.mockImplementation(() => toolPath);
|
|
||||||
await main.run();
|
|
||||||
|
|
||||||
expect(logSpy).toHaveBeenCalledWith(`Found in cache @ ${toolPath}`);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('finds a version in the cache and adds it to the path', async () => {
|
|
||||||
inputs['go-version'] = '1.13.0';
|
|
||||||
const toolPath = path.normalize('/cache/go/1.13.0/x64');
|
|
||||||
findSpy.mockImplementation(() => toolPath);
|
|
||||||
await main.run();
|
|
||||||
|
|
||||||
const expPath = path.join(toolPath, 'bin');
|
|
||||||
expect(cnSpy).toHaveBeenCalledWith(`::add-path::${expPath}${osm.EOL}`);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('handles unhandled error and reports error', async () => {
|
|
||||||
const errMsg = 'unhandled error message';
|
|
||||||
inputs['go-version'] = '1.13.0';
|
|
||||||
|
|
||||||
findSpy.mockImplementation(() => {
|
|
||||||
throw new Error(errMsg);
|
|
||||||
});
|
|
||||||
await main.run();
|
|
||||||
expect(cnSpy).toHaveBeenCalledWith('::error::' + errMsg + osm.EOL);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('downloads a version not in the cache', async () => {
|
|
||||||
os.platform = 'linux';
|
|
||||||
os.arch = 'x64';
|
|
||||||
|
|
||||||
inputs['go-version'] = '1.13.1';
|
|
||||||
|
|
||||||
findSpy.mockImplementation(() => '');
|
|
||||||
dlSpy.mockImplementation(() => '/some/temp/path');
|
|
||||||
const toolPath = path.normalize('/cache/go/1.13.0/x64');
|
|
||||||
extractTarSpy.mockImplementation(() => '/some/other/temp/path');
|
|
||||||
cacheSpy.mockImplementation(() => toolPath);
|
|
||||||
await main.run();
|
|
||||||
|
|
||||||
const expPath = path.join(toolPath, 'bin');
|
|
||||||
|
|
||||||
expect(dlSpy).toHaveBeenCalled();
|
|
||||||
expect(extractTarSpy).toHaveBeenCalled();
|
|
||||||
expect(cnSpy).toHaveBeenCalledWith(`::add-path::${expPath}${osm.EOL}`);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('downloads a version not in the cache (windows)', async () => {
|
|
||||||
os.platform = 'win32';
|
|
||||||
os.arch = 'x64';
|
|
||||||
|
|
||||||
inputs['go-version'] = '1.13.1';
|
|
||||||
process.env['RUNNER_TEMP'] = 'C:\\temp\\';
|
|
||||||
|
|
||||||
findSpy.mockImplementation(() => '');
|
|
||||||
dlSpy.mockImplementation(() => 'C:\\temp\\some\\path');
|
|
||||||
extractZipSpy.mockImplementation(() => 'C:\\temp\\some\\other\\path');
|
|
||||||
|
|
||||||
const toolPath = path.normalize('C:\\cache\\go\\1.13.0\\x64');
|
|
||||||
cacheSpy.mockImplementation(() => toolPath);
|
|
||||||
|
|
||||||
await main.run();
|
|
||||||
|
|
||||||
const expPath = path.win32.join(toolPath, 'bin');
|
|
||||||
expect(dlSpy).toHaveBeenCalledWith(
|
|
||||||
'https://storage.googleapis.com/golang/go1.13.1.windows-amd64.zip',
|
|
||||||
'C:\\temp\\go1.13.1.windows-amd64.zip',
|
|
||||||
undefined
|
|
||||||
);
|
|
||||||
expect(cnSpy).toHaveBeenCalledWith(`::add-path::${expPath}${osm.EOL}`);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('does not find a version that does not exist', async () => {
|
|
||||||
os.platform = 'linux';
|
|
||||||
os.arch = 'x64';
|
|
||||||
|
|
||||||
inputs['go-version'] = '9.99.9';
|
|
||||||
|
|
||||||
findSpy.mockImplementation(() => '');
|
|
||||||
await main.run();
|
|
||||||
|
|
||||||
expect(cnSpy).toHaveBeenCalledWith(
|
|
||||||
`::error::Unable to find Go version '9.99.9' for platform linux and architecture x64.${osm.EOL}`
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('downloads a version from a manifest match', async () => {
|
|
||||||
os.platform = 'linux';
|
|
||||||
os.arch = 'x64';
|
|
||||||
|
|
||||||
const versionSpec = '1.12.16';
|
|
||||||
|
|
||||||
inputs['go-version'] = versionSpec;
|
|
||||||
inputs['token'] = 'faketoken';
|
|
||||||
|
|
||||||
const expectedUrl =
|
|
||||||
'https://github.com/actions/go-versions/releases/download/1.12.16-20200616.20/go-1.12.16-linux-x64.tar.gz';
|
|
||||||
|
|
||||||
// ... but not in the local cache
|
|
||||||
findSpy.mockImplementation(() => '');
|
|
||||||
|
|
||||||
dlSpy.mockImplementation(async () => '/some/temp/path');
|
|
||||||
const toolPath = path.normalize('/cache/go/1.12.16/x64');
|
|
||||||
extractTarSpy.mockImplementation(async () => '/some/other/temp/path');
|
|
||||||
cacheSpy.mockImplementation(async () => toolPath);
|
|
||||||
|
|
||||||
await main.run();
|
|
||||||
|
|
||||||
const expPath = path.join(toolPath, 'bin');
|
|
||||||
|
|
||||||
expect(dlSpy).toHaveBeenCalled();
|
|
||||||
expect(extractTarSpy).toHaveBeenCalled();
|
|
||||||
expect(logSpy).not.toHaveBeenCalledWith(
|
|
||||||
'Not found in manifest. Falling back to download directly from Go'
|
|
||||||
);
|
|
||||||
expect(logSpy).toHaveBeenCalledWith(
|
|
||||||
`Acquiring 1.12.16 from ${expectedUrl}`
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(logSpy).toHaveBeenCalledWith(`Added go to the path`);
|
|
||||||
expect(cnSpy).toHaveBeenCalledWith(`::add-path::${expPath}${osm.EOL}`);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('downloads a major and minor from a manifest match', async () => {
|
|
||||||
os.platform = 'linux';
|
|
||||||
os.arch = 'x64';
|
|
||||||
|
|
||||||
const versionSpec = '1.12';
|
|
||||||
|
|
||||||
inputs['go-version'] = versionSpec;
|
|
||||||
inputs['token'] = 'faketoken';
|
|
||||||
|
|
||||||
const expectedUrl =
|
|
||||||
'https://github.com/actions/go-versions/releases/download/1.12.17-20200616.21/go-1.12.17-linux-x64.tar.gz';
|
|
||||||
|
|
||||||
// ... but not in the local cache
|
|
||||||
findSpy.mockImplementation(() => '');
|
|
||||||
|
|
||||||
dlSpy.mockImplementation(async () => '/some/temp/path');
|
|
||||||
const toolPath = path.normalize('/cache/go/1.12.17/x64');
|
|
||||||
extractTarSpy.mockImplementation(async () => '/some/other/temp/path');
|
|
||||||
cacheSpy.mockImplementation(async () => toolPath);
|
|
||||||
|
|
||||||
await main.run();
|
|
||||||
|
|
||||||
const expPath = path.join(toolPath, 'bin');
|
|
||||||
|
|
||||||
expect(dlSpy).toHaveBeenCalled();
|
|
||||||
expect(extractTarSpy).toHaveBeenCalled();
|
|
||||||
expect(logSpy).not.toHaveBeenCalledWith(
|
|
||||||
'Not found in manifest. Falling back to download directly from Go'
|
|
||||||
);
|
|
||||||
expect(logSpy).toHaveBeenCalledWith(
|
|
||||||
`Acquiring 1.12.17 from ${expectedUrl}`
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(logSpy).toHaveBeenCalledWith(`Added go to the path`);
|
|
||||||
expect(cnSpy).toHaveBeenCalledWith(`::add-path::${expPath}${osm.EOL}`);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('falls back to a version from go dist', async () => {
|
|
||||||
os.platform = 'linux';
|
|
||||||
os.arch = 'x64';
|
|
||||||
|
|
||||||
const versionSpec = '1.12.14';
|
|
||||||
|
|
||||||
inputs['go-version'] = versionSpec;
|
|
||||||
inputs['token'] = 'faketoken';
|
|
||||||
|
|
||||||
// ... but not in the local cache
|
|
||||||
findSpy.mockImplementation(() => '');
|
|
||||||
|
|
||||||
dlSpy.mockImplementation(async () => '/some/temp/path');
|
|
||||||
const toolPath = path.normalize('/cache/go/1.12.14/x64');
|
|
||||||
extractTarSpy.mockImplementation(async () => '/some/other/temp/path');
|
|
||||||
cacheSpy.mockImplementation(async () => toolPath);
|
|
||||||
|
|
||||||
await main.run();
|
|
||||||
|
|
||||||
const expPath = path.join(toolPath, 'bin');
|
|
||||||
expect(logSpy).toHaveBeenCalledWith('Setup go version spec 1.12.14');
|
|
||||||
expect(findSpy).toHaveBeenCalled();
|
|
||||||
expect(logSpy).toHaveBeenCalledWith('Attempting to download 1.12.14...');
|
|
||||||
expect(dlSpy).toHaveBeenCalled();
|
|
||||||
expect(logSpy).toHaveBeenCalledWith('matching 1.12.14...');
|
|
||||||
expect(extractTarSpy).toHaveBeenCalled();
|
|
||||||
expect(logSpy).toHaveBeenCalledWith(
|
|
||||||
'Not found in manifest. Falling back to download directly from Go'
|
|
||||||
);
|
|
||||||
expect(logSpy).toHaveBeenCalledWith(`Install from dist`);
|
|
||||||
expect(logSpy).toHaveBeenCalledWith(`Added go to the path`);
|
|
||||||
expect(cnSpy).toHaveBeenCalledWith(`::add-path::${expPath}${osm.EOL}`);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('reports a failed download', async () => {
|
|
||||||
const errMsg = 'unhandled download message';
|
|
||||||
os.platform = 'linux';
|
|
||||||
os.arch = 'x64';
|
|
||||||
|
|
||||||
inputs['go-version'] = '1.13.1';
|
|
||||||
|
|
||||||
findSpy.mockImplementation(() => '');
|
|
||||||
dlSpy.mockImplementation(() => {
|
|
||||||
throw new Error(errMsg);
|
|
||||||
});
|
|
||||||
await main.run();
|
|
||||||
|
|
||||||
expect(cnSpy).toHaveBeenCalledWith(
|
|
||||||
`::error::Failed to download version 1.13.1: Error: ${errMsg}${osm.EOL}`
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('does not add BIN if go is not in path', async () => {
|
|
||||||
whichSpy.mockImplementation(async () => {
|
|
||||||
return '';
|
|
||||||
});
|
|
||||||
const added = await main.addBinToPath();
|
|
||||||
expect(added).toBeFalsy();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('adds bin if dir not exists', async () => {
|
|
||||||
whichSpy.mockImplementation(async () => {
|
|
||||||
return '/usr/local/go/bin/go';
|
|
||||||
});
|
|
||||||
|
|
||||||
execSpy.mockImplementation(() => {
|
|
||||||
return '/Users/testuser/go';
|
|
||||||
});
|
|
||||||
|
|
||||||
mkdirpSpy.mockImplementation(async () => {});
|
|
||||||
existsSpy.mockImplementation(() => {
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
const added = await main.addBinToPath();
|
|
||||||
expect(added).toBeTruthy();
|
|
||||||
});
|
|
||||||
|
|
||||||
interface Annotation {
|
|
||||||
file: string;
|
|
||||||
line: number;
|
|
||||||
column: number;
|
|
||||||
message: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// problem matcher regex pattern tests
|
|
||||||
|
|
||||||
function testMatch(line: string): Annotation {
|
|
||||||
const annotation = <Annotation>{};
|
|
||||||
|
|
||||||
const match = matcherRegExp.exec(line);
|
|
||||||
if (match) {
|
|
||||||
annotation.line = parseInt(match[matcherPattern.line], 10);
|
|
||||||
annotation.column = parseInt(match[matcherPattern.column], 10);
|
|
||||||
annotation.file = match[matcherPattern.file].trim();
|
|
||||||
annotation.message = match[matcherPattern.message].trim();
|
|
||||||
}
|
|
||||||
|
|
||||||
return annotation;
|
|
||||||
}
|
|
||||||
|
|
||||||
it('matches on relative unix path', async () => {
|
|
||||||
const line = './main.go:13:2: undefined: fmt.Printl';
|
|
||||||
const annotation = testMatch(line);
|
|
||||||
expect(annotation).toBeDefined();
|
|
||||||
expect(annotation.line).toBe(13);
|
|
||||||
expect(annotation.column).toBe(2);
|
|
||||||
expect(annotation.file).toBe('./main.go');
|
|
||||||
expect(annotation.message).toBe('undefined: fmt.Printl');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('matches on unix path up the tree', async () => {
|
|
||||||
const line = '../main.go:13:2: undefined: fmt.Printl';
|
|
||||||
const annotation = testMatch(line);
|
|
||||||
expect(annotation).toBeDefined();
|
|
||||||
expect(annotation.line).toBe(13);
|
|
||||||
expect(annotation.column).toBe(2);
|
|
||||||
expect(annotation.file).toBe('../main.go');
|
|
||||||
expect(annotation.message).toBe('undefined: fmt.Printl');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('matches on unix path down the tree', async () => {
|
|
||||||
const line = 'foo/main.go:13:2: undefined: fmt.Printl';
|
|
||||||
const annotation = testMatch(line);
|
|
||||||
expect(annotation).toBeDefined();
|
|
||||||
expect(annotation.line).toBe(13);
|
|
||||||
expect(annotation.column).toBe(2);
|
|
||||||
expect(annotation.file).toBe('foo/main.go');
|
|
||||||
expect(annotation.message).toBe('undefined: fmt.Printl');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('matches on rooted unix path', async () => {
|
|
||||||
const line = '/assert.go:4:1: missing return at end of function';
|
|
||||||
const annotation = testMatch(line);
|
|
||||||
expect(annotation).toBeDefined();
|
|
||||||
expect(annotation.line).toBe(4);
|
|
||||||
expect(annotation.column).toBe(1);
|
|
||||||
expect(annotation.file).toBe('/assert.go');
|
|
||||||
expect(annotation.message).toBe('missing return at end of function');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('matches on unix path with spaces', async () => {
|
|
||||||
const line = ' ./assert.go:5:2: missing return at end of function ';
|
|
||||||
const annotation = testMatch(line);
|
|
||||||
expect(annotation).toBeDefined();
|
|
||||||
expect(annotation.line).toBe(5);
|
|
||||||
expect(annotation.column).toBe(2);
|
|
||||||
expect(annotation.file).toBe('./assert.go');
|
|
||||||
expect(annotation.message).toBe('missing return at end of function');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('matches on unix path with tabs', async () => {
|
|
||||||
const line = '\t./assert.go:5:2: missing return at end of function ';
|
|
||||||
const annotation = testMatch(line);
|
|
||||||
expect(annotation).toBeDefined();
|
|
||||||
expect(annotation.line).toBe(5);
|
|
||||||
expect(annotation.column).toBe(2);
|
|
||||||
expect(annotation.file).toBe('./assert.go');
|
|
||||||
expect(annotation.message).toBe('missing return at end of function');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('matches on relative windows path', async () => {
|
|
||||||
const line = '.\\main.go:13:2: undefined: fmt.Printl';
|
|
||||||
const annotation = testMatch(line);
|
|
||||||
expect(annotation).toBeDefined();
|
|
||||||
expect(annotation.line).toBe(13);
|
|
||||||
expect(annotation.column).toBe(2);
|
|
||||||
expect(annotation.file).toBe('.\\main.go');
|
|
||||||
expect(annotation.message).toBe('undefined: fmt.Printl');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('matches on windows path up the tree', async () => {
|
|
||||||
const line = '..\\main.go:13:2: undefined: fmt.Printl';
|
|
||||||
const annotation = testMatch(line);
|
|
||||||
expect(annotation).toBeDefined();
|
|
||||||
expect(annotation.line).toBe(13);
|
|
||||||
expect(annotation.column).toBe(2);
|
|
||||||
expect(annotation.file).toBe('..\\main.go');
|
|
||||||
expect(annotation.message).toBe('undefined: fmt.Printl');
|
|
||||||
});
|
|
||||||
|
|
||||||
// 1.13.1 => 1.13.1
|
|
||||||
// 1.13 => 1.13.0
|
|
||||||
// 1.10beta1 => 1.10.0-beta.1, 1.10rc1 => 1.10.0-rc.1
|
|
||||||
// 1.8.5beta1 => 1.8.5-beta.1, 1.8.5rc1 => 1.8.5-rc.1
|
|
||||||
it('converts prerelease versions', async () => {
|
|
||||||
expect(im.makeSemver('1.10beta1')).toBe('1.10.0-beta.1');
|
|
||||||
expect(im.makeSemver('1.10rc1')).toBe('1.10.0-rc.1');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('converts dot zero versions', async () => {
|
|
||||||
expect(im.makeSemver('1.13')).toBe('1.13.0');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('does not convert exact versions', async () => {
|
|
||||||
expect(im.makeSemver('1.13.1')).toBe('1.13.1');
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('check-latest flag', () => {
|
|
||||||
it("use local version and don't check manifest if check-latest is not specified", async () => {
|
|
||||||
os.platform = 'linux';
|
|
||||||
os.arch = 'x64';
|
|
||||||
|
|
||||||
inputs['go-version'] = '1.16';
|
|
||||||
inputs['check-latest'] = false;
|
|
||||||
|
|
||||||
const toolPath = path.normalize('/cache/go/1.16.1/x64');
|
|
||||||
findSpy.mockReturnValue(toolPath);
|
|
||||||
await main.run();
|
|
||||||
|
|
||||||
expect(logSpy).toHaveBeenCalledWith(`Found in cache @ ${toolPath}`);
|
|
||||||
expect(logSpy).not.toHaveBeenCalledWith(
|
|
||||||
'Attempting to resolve the latest version from the manifest...'
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('check latest version and resolve it from local cache', async () => {
|
|
||||||
os.platform = 'linux';
|
|
||||||
os.arch = 'x64';
|
|
||||||
|
|
||||||
inputs['go-version'] = '1.16';
|
|
||||||
inputs['check-latest'] = true;
|
|
||||||
|
|
||||||
const toolPath = path.normalize('/cache/go/1.16.1/x64');
|
|
||||||
findSpy.mockReturnValue(toolPath);
|
|
||||||
dlSpy.mockImplementation(async () => '/some/temp/path');
|
|
||||||
extractTarSpy.mockImplementation(async () => '/some/other/temp/path');
|
|
||||||
cacheSpy.mockImplementation(async () => toolPath);
|
|
||||||
|
|
||||||
await main.run();
|
|
||||||
|
|
||||||
expect(logSpy).toHaveBeenCalledWith('Setup go version spec 1.16');
|
|
||||||
expect(logSpy).toHaveBeenCalledWith(`Found in cache @ ${toolPath}`);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('check latest version and install it from manifest', async () => {
|
|
||||||
os.platform = 'linux';
|
|
||||||
os.arch = 'x64';
|
|
||||||
|
|
||||||
const versionSpec = '1.17';
|
|
||||||
const patchVersion = '1.17.6';
|
|
||||||
inputs['go-version'] = versionSpec;
|
|
||||||
inputs['stable'] = 'true';
|
|
||||||
inputs['check-latest'] = true;
|
|
||||||
|
|
||||||
findSpy.mockImplementation(() => '');
|
|
||||||
dlSpy.mockImplementation(async () => '/some/temp/path');
|
|
||||||
const toolPath = path.normalize('/cache/go/1.17.6/x64');
|
|
||||||
extractTarSpy.mockImplementation(async () => '/some/other/temp/path');
|
|
||||||
cacheSpy.mockImplementation(async () => toolPath);
|
|
||||||
|
|
||||||
await main.run();
|
|
||||||
|
|
||||||
expect(logSpy).toHaveBeenCalledWith(
|
|
||||||
`Setup go version spec ${versionSpec}`
|
|
||||||
);
|
|
||||||
expect(logSpy).toHaveBeenCalledWith(
|
|
||||||
'Attempting to resolve the latest version from the manifest...'
|
|
||||||
);
|
|
||||||
expect(logSpy).toHaveBeenCalledWith(`Resolved as '${patchVersion}'`);
|
|
||||||
expect(logSpy).toHaveBeenCalledWith(
|
|
||||||
`Attempting to download ${patchVersion}...`
|
|
||||||
);
|
|
||||||
expect(logSpy).toHaveBeenCalledWith('Extracting Go...');
|
|
||||||
expect(logSpy).toHaveBeenCalledWith('Adding to the cache ...');
|
|
||||||
expect(logSpy).toHaveBeenCalledWith('Added go to the path');
|
|
||||||
expect(logSpy).toHaveBeenCalledWith(
|
|
||||||
`Successfully set up Go version ${versionSpec}`
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('fallback to dist if version is not found in manifest', async () => {
|
|
||||||
os.platform = 'linux';
|
|
||||||
os.arch = 'x64';
|
|
||||||
|
|
||||||
const versionSpec = '1.13';
|
|
||||||
|
|
||||||
inputs['go-version'] = versionSpec;
|
|
||||||
inputs['check-latest'] = true;
|
|
||||||
inputs['always-auth'] = false;
|
|
||||||
inputs['token'] = 'faketoken';
|
|
||||||
|
|
||||||
// ... but not in the local cache
|
|
||||||
findSpy.mockImplementation(() => '');
|
|
||||||
|
|
||||||
dlSpy.mockImplementation(async () => '/some/temp/path');
|
|
||||||
const toolPath = path.normalize('/cache/go/1.13.7/x64');
|
|
||||||
extractTarSpy.mockImplementation(async () => '/some/other/temp/path');
|
|
||||||
cacheSpy.mockImplementation(async () => toolPath);
|
|
||||||
|
|
||||||
await main.run();
|
|
||||||
|
|
||||||
const expPath = path.join(toolPath, 'bin');
|
|
||||||
|
|
||||||
expect(dlSpy).toHaveBeenCalled();
|
|
||||||
expect(extractTarSpy).toHaveBeenCalled();
|
|
||||||
expect(logSpy).toHaveBeenCalledWith(
|
|
||||||
'Attempting to resolve the latest version from the manifest...'
|
|
||||||
);
|
|
||||||
expect(logSpy).toHaveBeenCalledWith(
|
|
||||||
`Failed to resolve version ${versionSpec} from manifest`
|
|
||||||
);
|
|
||||||
expect(logSpy).toHaveBeenCalledWith(
|
|
||||||
`Attempting to download ${versionSpec}...`
|
|
||||||
);
|
|
||||||
expect(cnSpy).toHaveBeenCalledWith(`::add-path::${expPath}${osm.EOL}`);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('fallback to dist if manifest is not available', async () => {
|
|
||||||
os.platform = 'linux';
|
|
||||||
os.arch = 'x64';
|
|
||||||
|
|
||||||
const versionSpec = '1.13';
|
|
||||||
|
|
||||||
process.env['GITHUB_PATH'] = '';
|
|
||||||
|
|
||||||
inputs['go-version'] = versionSpec;
|
|
||||||
inputs['check-latest'] = true;
|
|
||||||
inputs['always-auth'] = false;
|
|
||||||
inputs['token'] = 'faketoken';
|
|
||||||
|
|
||||||
// ... but not in the local cache
|
|
||||||
findSpy.mockImplementation(() => '');
|
|
||||||
getManifestSpy.mockImplementation(() => {
|
|
||||||
throw new Error('Unable to download manifest');
|
|
||||||
});
|
|
||||||
getAllVersionsSpy.mockImplementationOnce(() => undefined);
|
|
||||||
|
|
||||||
dlSpy.mockImplementation(async () => '/some/temp/path');
|
|
||||||
const toolPath = path.normalize('/cache/go/1.13.7/x64');
|
|
||||||
extractTarSpy.mockImplementation(async () => '/some/other/temp/path');
|
|
||||||
cacheSpy.mockImplementation(async () => toolPath);
|
|
||||||
|
|
||||||
await main.run();
|
|
||||||
|
|
||||||
const expPath = path.join(toolPath, 'bin');
|
|
||||||
|
|
||||||
expect(logSpy).toHaveBeenCalledWith(
|
|
||||||
`Failed to resolve version ${versionSpec} from manifest`
|
|
||||||
);
|
|
||||||
expect(dlSpy).toHaveBeenCalled();
|
|
||||||
expect(extractTarSpy).toHaveBeenCalled();
|
|
||||||
expect(logSpy).toHaveBeenCalledWith(
|
|
||||||
'Attempting to resolve the latest version from the manifest...'
|
|
||||||
);
|
|
||||||
expect(logSpy).toHaveBeenCalledWith(
|
|
||||||
'Unable to resolve a version from the manifest...'
|
|
||||||
);
|
|
||||||
expect(logSpy).toHaveBeenCalledWith(
|
|
||||||
`Failed to resolve version ${versionSpec} from manifest`
|
|
||||||
);
|
|
||||||
expect(logSpy).toHaveBeenCalledWith(
|
|
||||||
`Attempting to download ${versionSpec}...`
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(cnSpy).toHaveBeenCalledWith(`::add-path::${expPath}${osm.EOL}`);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('go-version-file', () => {
|
|
||||||
const goModContents = `module example.com/mymodule
|
|
||||||
|
|
||||||
go 1.14
|
|
||||||
|
|
||||||
require (
|
|
||||||
example.com/othermodule v1.2.3
|
|
||||||
example.com/thismodule v1.2.3
|
|
||||||
example.com/thatmodule v1.2.3
|
|
||||||
)
|
|
||||||
|
|
||||||
replace example.com/thatmodule => ../thatmodule
|
|
||||||
exclude example.com/thismodule v1.3.0
|
|
||||||
`;
|
|
||||||
|
|
||||||
const goWorkContents = `go 1.19
|
|
||||||
|
|
||||||
use .
|
|
||||||
|
|
||||||
`;
|
|
||||||
|
|
||||||
it('reads version from go.mod', async () => {
|
|
||||||
inputs['go-version-file'] = 'go.mod';
|
|
||||||
existsSpy.mockImplementation(() => true);
|
|
||||||
readFileSpy.mockImplementation(() => Buffer.from(goModContents));
|
|
||||||
|
|
||||||
await main.run();
|
|
||||||
|
|
||||||
expect(logSpy).toHaveBeenCalledWith('Setup go version spec 1.14');
|
|
||||||
expect(logSpy).toHaveBeenCalledWith('Attempting to download 1.14...');
|
|
||||||
expect(logSpy).toHaveBeenCalledWith('matching 1.14...');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('reads version from go.work', async () => {
|
|
||||||
inputs['go-version-file'] = 'go.work';
|
|
||||||
existsSpy.mockImplementation(() => true);
|
|
||||||
readFileSpy.mockImplementation(() => Buffer.from(goWorkContents));
|
|
||||||
|
|
||||||
await main.run();
|
|
||||||
|
|
||||||
expect(logSpy).toHaveBeenCalledWith('Setup go version spec 1.19');
|
|
||||||
expect(logSpy).toHaveBeenCalledWith('Attempting to download 1.19...');
|
|
||||||
expect(logSpy).toHaveBeenCalledWith('matching 1.19...');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('reads version from .go-version', async () => {
|
|
||||||
inputs['go-version-file'] = '.go-version';
|
|
||||||
existsSpy.mockImplementation(() => true);
|
|
||||||
readFileSpy.mockImplementation(() => Buffer.from(`1.13.0${osm.EOL}`));
|
|
||||||
|
|
||||||
await main.run();
|
|
||||||
|
|
||||||
expect(logSpy).toHaveBeenCalledWith('Setup go version spec 1.13.0');
|
|
||||||
expect(logSpy).toHaveBeenCalledWith('Attempting to download 1.13.0...');
|
|
||||||
expect(logSpy).toHaveBeenCalledWith('matching 1.13.0...');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('is overwritten by go-version', async () => {
|
|
||||||
inputs['go-version'] = '1.13.1';
|
|
||||||
inputs['go-version-file'] = 'go.mod';
|
|
||||||
existsSpy.mockImplementation(() => true);
|
|
||||||
readFileSpy.mockImplementation(() => Buffer.from(goModContents));
|
|
||||||
|
|
||||||
await main.run();
|
|
||||||
|
|
||||||
expect(logSpy).toHaveBeenCalledWith('Setup go version spec 1.13.1');
|
|
||||||
expect(logSpy).toHaveBeenCalledWith('Attempting to download 1.13.1...');
|
|
||||||
expect(logSpy).toHaveBeenCalledWith('matching 1.13.1...');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('reports a read failure', async () => {
|
|
||||||
inputs['go-version-file'] = 'go.mod';
|
|
||||||
existsSpy.mockImplementation(() => false);
|
|
||||||
|
|
||||||
await main.run();
|
|
||||||
|
|
||||||
expect(cnSpy).toHaveBeenCalledWith(
|
|
||||||
`::error::The specified go version file at: go.mod does not exist${osm.EOL}`
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('acquires specified architecture of go', async () => {
|
|
||||||
for (const {arch, version, osSpec} of [
|
|
||||||
{arch: 'amd64', version: '1.13.7', osSpec: 'linux'},
|
|
||||||
{arch: 'armv6l', version: '1.12.2', osSpec: 'linux'}
|
|
||||||
]) {
|
|
||||||
os.platform = osSpec;
|
|
||||||
os.arch = arch;
|
|
||||||
|
|
||||||
const fileExtension = os.platform === 'win32' ? 'zip' : 'tar.gz';
|
|
||||||
|
|
||||||
const platform = os.platform === 'win32' ? 'win' : os.platform;
|
|
||||||
|
|
||||||
inputs['go-version'] = version;
|
|
||||||
inputs['architecture'] = arch;
|
|
||||||
|
|
||||||
const expectedUrl =
|
|
||||||
platform === 'win32'
|
|
||||||
? `https://github.com/actions/go-versions/releases/download/${version}/go-${version}-${platform}-${arch}.${fileExtension}`
|
|
||||||
: `https://storage.googleapis.com/golang/go${version}.${osSpec}-${arch}.${fileExtension}`;
|
|
||||||
|
|
||||||
// ... but not in the local cache
|
|
||||||
findSpy.mockImplementation(() => '');
|
|
||||||
|
|
||||||
dlSpy.mockImplementation(async () => '/some/temp/path');
|
|
||||||
const toolPath = path.normalize(`/cache/go/${version}/${arch}`);
|
|
||||||
cacheSpy.mockImplementation(async () => toolPath);
|
|
||||||
|
|
||||||
await main.run();
|
|
||||||
|
|
||||||
expect(logSpy).toHaveBeenCalledWith(
|
|
||||||
`Acquiring go${version} from ${expectedUrl}`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}, 100000);
|
|
||||||
|
|
||||||
it.each(['stable', 'oldstable'])(
|
|
||||||
'acquires latest go version with %s go-version input',
|
|
||||||
async (alias: string) => {
|
|
||||||
const arch = 'x64';
|
|
||||||
os.platform = 'darwin';
|
|
||||||
os.arch = arch;
|
|
||||||
|
|
||||||
inputs['go-version'] = alias;
|
|
||||||
inputs['architecture'] = os.arch;
|
|
||||||
|
|
||||||
// ... but not in the local cache
|
|
||||||
findSpy.mockImplementation(() => '');
|
|
||||||
|
|
||||||
dlSpy.mockImplementation(async () => '/some/temp/path');
|
|
||||||
const toolPath = path.normalize(`/cache/go/${alias}/${arch}`);
|
|
||||||
cacheSpy.mockImplementation(async () => toolPath);
|
|
||||||
|
|
||||||
await main.run();
|
|
||||||
|
|
||||||
const releaseIndex = alias === 'stable' ? 0 : 1;
|
|
||||||
|
|
||||||
expect(logSpy).toHaveBeenCalledWith(
|
|
||||||
`${alias} version resolved as ${goTestManifest[releaseIndex].version}`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,14 +0,0 @@
|
|||||||
|
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
if [ -z "$1" ]; then
|
|
||||||
echo "Must supply go version argument"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
go_version="$(go version)"
|
|
||||||
echo "Found go version '$go_version'"
|
|
||||||
if [ -z "$(echo $go_version | grep $1)" ]; then
|
|
||||||
echo "Unexpected version"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
@ -1,62 +0,0 @@
|
|||||||
import fs from 'fs';
|
|
||||||
import * as io from '@actions/io';
|
|
||||||
import * as tc from '@actions/tool-cache';
|
|
||||||
import path from 'path';
|
|
||||||
|
|
||||||
describe('Windows performance workaround', () => {
|
|
||||||
let mkdirSpy: jest.SpyInstance;
|
|
||||||
let symlinkSpy: jest.SpyInstance;
|
|
||||||
let statSpy: jest.SpyInstance;
|
|
||||||
let readdirSpy: jest.SpyInstance;
|
|
||||||
let writeFileSpy: jest.SpyInstance;
|
|
||||||
let rmRFSpy: jest.SpyInstance;
|
|
||||||
let mkdirPSpy: jest.SpyInstance;
|
|
||||||
let cpSpy: jest.SpyInstance;
|
|
||||||
|
|
||||||
let runnerToolCache: string | undefined;
|
|
||||||
beforeEach(() => {
|
|
||||||
mkdirSpy = jest.spyOn(fs, 'mkdir');
|
|
||||||
symlinkSpy = jest.spyOn(fs, 'symlinkSync');
|
|
||||||
statSpy = jest.spyOn(fs, 'statSync');
|
|
||||||
readdirSpy = jest.spyOn(fs, 'readdirSync');
|
|
||||||
writeFileSpy = jest.spyOn(fs, 'writeFileSync');
|
|
||||||
rmRFSpy = jest.spyOn(io, 'rmRF');
|
|
||||||
mkdirPSpy = jest.spyOn(io, 'mkdirP');
|
|
||||||
cpSpy = jest.spyOn(io, 'cp');
|
|
||||||
|
|
||||||
// default implementations
|
|
||||||
// @ts-ignore - not implement unused methods
|
|
||||||
statSpy.mockImplementation(() => ({
|
|
||||||
isDirectory: () => true
|
|
||||||
}));
|
|
||||||
readdirSpy.mockImplementation(() => []);
|
|
||||||
writeFileSpy.mockImplementation(() => {});
|
|
||||||
mkdirSpy.mockImplementation(() => {});
|
|
||||||
symlinkSpy.mockImplementation(() => {});
|
|
||||||
rmRFSpy.mockImplementation(() => Promise.resolve());
|
|
||||||
mkdirPSpy.mockImplementation(() => Promise.resolve());
|
|
||||||
cpSpy.mockImplementation(() => Promise.resolve());
|
|
||||||
|
|
||||||
runnerToolCache = process.env['RUNNER_TOOL_CACHE'];
|
|
||||||
});
|
|
||||||
afterEach(() => {
|
|
||||||
jest.clearAllMocks();
|
|
||||||
process.env['RUNNER_TOOL_CACHE'] = runnerToolCache;
|
|
||||||
});
|
|
||||||
// cacheWindowsToolkitDir depends on implementation of tc.cacheDir
|
|
||||||
// with the assumption that target dir is passed by RUNNER_TOOL_CACHE environment variable
|
|
||||||
// Make sure the implementation has not been changed
|
|
||||||
it('addExecutablesToCache should depend on env[RUNNER_TOOL_CACHE]', async () => {
|
|
||||||
process.env['RUNNER_TOOL_CACHE'] = '/faked-hostedtoolcache1';
|
|
||||||
const cacheDir1 = await tc.cacheDir('/qzx', 'go', '1.2.3', 'arch');
|
|
||||||
expect(cacheDir1).toBe(
|
|
||||||
path.join('/', 'faked-hostedtoolcache1', 'go', '1.2.3', 'arch')
|
|
||||||
);
|
|
||||||
|
|
||||||
process.env['RUNNER_TOOL_CACHE'] = '/faked-hostedtoolcache2';
|
|
||||||
const cacheDir2 = await tc.cacheDir('/qzx', 'go', '1.2.3', 'arch');
|
|
||||||
expect(cacheDir2).toBe(
|
|
||||||
path.join('/', 'faked-hostedtoolcache2', 'go', '1.2.3', 'arch')
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
39
action.yml
39
action.yml
@ -1,31 +1,14 @@
|
|||||||
name: 'Setup Go environment'
|
name: 'Setup Go'
|
||||||
description: 'Setup a Go environment and add it to the PATH'
|
description: 'Set up a specific version of Go and add the command-line tools to the PATH'
|
||||||
author: 'GitHub'
|
author: 'GitHub'
|
||||||
inputs:
|
inputs:
|
||||||
go-version:
|
go-version:
|
||||||
description: 'The Go version to download (if necessary) and use. Supports semver spec and ranges. Be sure to enclose this option in single quotation marks.'
|
description: 'The Go version to download (if necessary) and use. Example: 1.9.3'
|
||||||
go-version-file:
|
default: '1.10'
|
||||||
description: 'Path to the go.mod or go.work file.'
|
# Deprecated option, do not use. Will not be supported after October 1, 2019
|
||||||
check-latest:
|
version:
|
||||||
description: 'Set this option to true if you want the action to always check for the latest available version that satisfies the version spec'
|
description: 'Deprecated. Use go-version instead. Will not be supported after October 1, 2019'
|
||||||
default: false
|
deprecationMessage: 'The version property will not be supported after October 1, 2019. Use go-version instead'
|
||||||
token:
|
|
||||||
description: Used to pull Go distributions from go-versions. Since there's a default, this is typically not supplied by the user. When running this action on github.com, the default value is sufficient. When running on GHES, you can pass a personal access token for github.com if you are experiencing rate limiting.
|
|
||||||
default: ${{ github.server_url == 'https://github.com' && github.token || '' }}
|
|
||||||
cache:
|
|
||||||
description: Used to specify whether caching is needed. Set to true, if you'd like to enable caching.
|
|
||||||
default: true
|
|
||||||
cache-dependency-path:
|
|
||||||
description: 'Used to specify the path to a dependency file - go.sum'
|
|
||||||
architecture:
|
|
||||||
description: 'Target architecture for Go to use. Examples: x86, x64. Will use system architecture by default.'
|
|
||||||
outputs:
|
|
||||||
go-version:
|
|
||||||
description: 'The installed Go version. Useful when given a version range as input.'
|
|
||||||
cache-hit:
|
|
||||||
description: 'A boolean value to indicate if a cache was hit'
|
|
||||||
runs:
|
runs:
|
||||||
using: 'node20'
|
using: 'node12'
|
||||||
main: 'dist/setup/index.js'
|
main: 'lib/setup-go.js'
|
||||||
post: 'dist/cache-save/index.js'
|
|
||||||
post-if: success()
|
|
||||||
|
82956
dist/cache-save/index.js
vendored
82956
dist/cache-save/index.js
vendored
File diff suppressed because one or more lines are too long
90580
dist/setup/index.js
vendored
90580
dist/setup/index.js
vendored
File diff suppressed because one or more lines are too long
@ -1,69 +0,0 @@
|
|||||||
# 0. Caching dependencies
|
|
||||||
Date: 2022-04-13
|
|
||||||
|
|
||||||
Status: Accepted
|
|
||||||
|
|
||||||
# Context
|
|
||||||
`actions/setup-go` is the one of the most popular action related to Golang in GitHub Actions. Many customers use it in conjunction with [actions/cache](https://github.com/actions/cache) to speed up dependency installation process.
|
|
||||||
See more examples on proper usage in [actions/cache documentation](https://github.com/actions/cache/blob/main/examples.md#go---modules).
|
|
||||||
|
|
||||||
# Goals & Anti-Goals
|
|
||||||
Integration of caching functionality into `actions/setup-go` action will bring the following benefits for action users:
|
|
||||||
- Decrease the entry threshold for using the cache for Go dependencies and simplify initial configuration
|
|
||||||
- Simplify YAML pipelines because there will be no need for additional steps to enable caching
|
|
||||||
- More users will use cache for Go so more customers will have fast builds!
|
|
||||||
|
|
||||||
We don't pursue the goal to provide wide customization of caching in scope of `actions/setup-go` action. The purpose of this integration is covering ~90% of basic use-cases. If user needs flexible customization, we should advice them to use `actions/cache` directly.
|
|
||||||
|
|
||||||
# Decision
|
|
||||||
- Add `cache` input parameter to `actions/setup-go`. For now, input will accept the following values:
|
|
||||||
- `true` - enable caching for go dependencies
|
|
||||||
- `false`- disable caching for go dependencies. This value will be set as default value
|
|
||||||
- Cache feature will be disabled by default to make sure that we don't break existing customers. We will consider enabling cache by default in next major releases
|
|
||||||
- Action will try to search a go.sum files in the repository and throw error in the scenario that it was not found
|
|
||||||
- The hash of found file will be used as cache key (the same approach like [actions/cache](https://github.com/actions/cache/blob/main/examples.md#go---modules) recommends)
|
|
||||||
- The following key cache will be used `${{ runner.os }}-go${{ go-version }}-${{ hashFiles('<go.sum-path>') }}`
|
|
||||||
- Action will cache global cache from the `go env GOMODCACHE` and `go env GOCACHE` commands.
|
|
||||||
- Add a `cache-dependency-path` input parameter to `actions/setup-go`. The new input will accept an array or regex of dependency files. The field will accept a path (relative to the repository root) to dependency files. If the provided path contains wildcards, the action will search all matching files and calculate a common hash like the ${{ hashFiles('**/go.sum') }} YAML construction does.
|
|
||||||
|
|
||||||
# Example of real use-cases
|
|
||||||
|
|
||||||
- With cache
|
|
||||||
|
|
||||||
```yml
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- uses: actions/setup-go@v3
|
|
||||||
with:
|
|
||||||
go-version: '18'
|
|
||||||
cache: true
|
|
||||||
```
|
|
||||||
|
|
||||||
- With cache-dependency-path
|
|
||||||
|
|
||||||
```yml
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- uses: actions/setup-go@v3
|
|
||||||
with:
|
|
||||||
go-version: '18'
|
|
||||||
cache: true
|
|
||||||
cache-dependency-path: **/go.sum
|
|
||||||
```
|
|
||||||
|
|
||||||
```yml
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- uses: actions/setup-go@v3
|
|
||||||
with:
|
|
||||||
go-version: '18'
|
|
||||||
cache: true
|
|
||||||
cache-dependency-path: |
|
|
||||||
**/go.sum
|
|
||||||
**/go.mod
|
|
||||||
```
|
|
||||||
|
|
||||||
# Release process
|
|
||||||
|
|
||||||
As soon as functionality is implemented, we will release minor update of action. No need to bump major version since there are no breaking changes for existing users.
|
|
||||||
After that, we will update [starter-workflows](https://github.com/actions/starter-workflows/blob/main/ci/go.yml)
|
|
@ -1,116 +1,17 @@
|
|||||||
# Contributors
|
# Contributors
|
||||||
|
|
||||||
Thank you for contributing!
|
|
||||||
|
|
||||||
We have prepared a short guide so that the process of making your contribution is as simple and clear as possible. Please check it out before you contribute!
|
# Checkin
|
||||||
|
|
||||||
## How can I contribute...
|
- Do checkin source (src)
|
||||||
|
- Do checkin build output (lib)
|
||||||
|
- Do checkin runtime node_modules
|
||||||
|
- Do not checkin
|
||||||
|
|
||||||
* [Contribute Documentation :green_book:](#contribute-documentation)
|
# Adding a dev dependency
|
||||||
|
|
||||||
* [Contribute Code :computer:](#contribute-code)
|
Remember to update .gitignore.
|
||||||
|
|
||||||
* [Provide Support on Issues :pencil:](#provide-support-on-issues)
|
# Updating toolkit dependency
|
||||||
|
|
||||||
* [Review Pull Requests :mag:](#review-pull-requests)
|
Until released publically, update tgz packages in toolkit
|
||||||
|
|
||||||
## Contribute documentation
|
|
||||||
|
|
||||||
Documentation is a super important, critical part of this project. Docs are how we keep track of what we're doing, how, and why. It's how we stay on the same page about our policies and how we tell others everything they need to be able to use this project or contribute to it.
|
|
||||||
|
|
||||||
Documentation contributions of any size are welcome! Feel free to contribute even if you're just rewording a sentence to be more clear, or fixing a spelling mistake!
|
|
||||||
|
|
||||||
**How to contribute:**
|
|
||||||
|
|
||||||
Pull requests are the easiest way to contribute changes to git repos at GitHub. They are the preferred contribution method, as they offer a nice way of commenting and amending the proposed changes.
|
|
||||||
|
|
||||||
- Please check that no one else has already created a pull request with these changes
|
|
||||||
- Use a "feature branch" for your changes. That separates the changes in the pull request from your other changes and makes it easy to edit/amend commits in the pull request
|
|
||||||
- Make sure your changes are formatted correctly and consistently with the rest of the documentation
|
|
||||||
- Re-read what you wrote, and run a spellchecker on it to make sure you didn't miss anything
|
|
||||||
- If your pull request is connected to an open issue, please, leave a link to this issue in the `Related issue:` section
|
|
||||||
- If you later need to add new commits to the pull request, you can simply commit the changes to the local branch and then push them. The pull request gets automatically updated
|
|
||||||
|
|
||||||
**Once you've filed the pull request:**
|
|
||||||
|
|
||||||
- Maintainers will review your pull request
|
|
||||||
- If a maintainer requests changes, first of all, try to think about this request critically and only after that implement and request another review
|
|
||||||
- If your PR gets accepted, it will soon be merged into the main branch. But your contribution will take effect only after the release of a new version of the action
|
|
||||||
> Sometimes maintainers reject pull requests and that's ok! Usually, along with rejection, we supply the reason for it. Nonetheless, we still really appreciate you taking the time to do it, and we don't take that lightly :heart:
|
|
||||||
|
|
||||||
## Contribute code
|
|
||||||
|
|
||||||
We like code commits a lot! They're super handy, and they keep the project going and doing the work it needs to do to be useful to others.
|
|
||||||
|
|
||||||
Code contributions of just about any size are acceptable!
|
|
||||||
|
|
||||||
The main difference between code contributions and documentation contributions is that contributing code requires the inclusion of relevant tests for the code being added or changed. Contributions without accompanying tests will be held off until a test is added unless the maintainers consider the specific tests to be either impossible or way too much of a burden for such a contribution.
|
|
||||||
|
|
||||||
**How to contribute:**
|
|
||||||
|
|
||||||
Pull requests are the easiest way to contribute changes to git repos at GitHub. They are the preferred contribution method, as they offer a nice way of commenting and amending the proposed changes.
|
|
||||||
|
|
||||||
- Please check that no one else has already created a pull request with these changes
|
|
||||||
- Use a "feature branch" for your changes. That separates the changes in the pull request from your other changes and makes it easy to edit/amend commits in the pull request
|
|
||||||
- **Run `pre-checkin` script to format, lint, build and test changes**
|
|
||||||
- Make sure your changes are well formatted and that all tests are passing
|
|
||||||
- If your pull request is connected to an open issue, please, leave a link to this issue in the `Related issue:` section
|
|
||||||
- If you later need to add new commits to the pull request, you can simply commit the changes to the local branch and then push them. The pull request gets automatically updated
|
|
||||||
|
|
||||||
**Learn more about how to work with the repository:**
|
|
||||||
|
|
||||||
- To implement new features or fix bugs, you need to make changes to the `.ts` files, which are located in the `src` folder
|
|
||||||
- To comply with the code style, **you need to run the `format` script**
|
|
||||||
- To lint the code, **you need to run the `lint:fix` script**
|
|
||||||
- To transpile source code to `javascript` we use [NCC](https://github.com/vercel/ncc). **It is very important to run the `build` script after making changes**, otherwise your changes will not get into the final `javascript` build
|
|
||||||
- You can also start formatting, building code, and testing with a single `pre-checkin` command
|
|
||||||
|
|
||||||
**Learn more about how to implement tests:**
|
|
||||||
|
|
||||||
Adding or changing tests is an integral part of making a change to the code.
|
|
||||||
Unit tests are in the `__tests__` folder, and end-to-end tests are in the `workflows` folder (in particular, in the file [versions.yml](https://github.com/actions/setup-go/blob/main/.github/workflows/versions.yml)).
|
|
||||||
|
|
||||||
- The contributor can add various types of tests (like unit tests or end-to-end tests), which, in his opinion, will be necessary and sufficient for testing new or changed functionality
|
|
||||||
- Tests should cover a successful execution, as well as some edge cases and possible errors
|
|
||||||
- As already mentioned, pull requests without tests will be considered more carefully by maintainers. If you are sure that in this situation the tests are not needed or cannot be implemented with a commensurate effort - please add this clarification message to your pull request
|
|
||||||
|
|
||||||
**Once you've filed the pull request:**
|
|
||||||
|
|
||||||
- CI will start automatically with some checks. Wait until the end of the execution and make sure that all checks passed successfully. If some checks fail, you can open them one by one, try to find the reason for failing and make changes to your code to resolve the problem
|
|
||||||
- Maintainers will review your pull request
|
|
||||||
- If a maintainer requests changes, first of all, try to think about his request critically and only after that implement and request another review
|
|
||||||
- If your PR gets accepted, it will soon be merged into the main branch. But your contribution will take effect only after the release of a new version of the action
|
|
||||||
> Sometimes maintainers reject pull requests and that's ok! Usually, along with rejection, we supply the reason for it. Nonetheless, we still really appreciate you taking the time to do it, and we don't take that lightly :heart:
|
|
||||||
|
|
||||||
## Provide support on issues
|
|
||||||
|
|
||||||
Helping out other users with their questions is an awesome way of contributing to any community. It's not uncommon for most of the issues on open source projects to be support-related questions by users trying to understand something they ran into or find their way around a known bug.
|
|
||||||
|
|
||||||
**To help other folks out with their questions:**
|
|
||||||
|
|
||||||
- Go to the [issue tracker](https://github.com/actions/setup-go/issues)
|
|
||||||
- Read through the list until you find something that you're familiar enough with to answer to
|
|
||||||
- Respond to the issue with whatever details are needed to clarify the question, or get more details about what's going on
|
|
||||||
- Once the discussion wraps up and things are clarified, ask the original issue filer (or a maintainer) to close it for you
|
|
||||||
|
|
||||||
*Some notes on picking up support issues:*
|
|
||||||
|
|
||||||
- Avoid responding to issues you don't know you can answer accurately
|
|
||||||
- Try to refer to past issues with accepted answers as much as possible. Link to them from your replies
|
|
||||||
- Be kind and patient with users. Often, folks who have run into confusing things might be upset or impatient. This is natural. If you feel uncomfortable in conversation with them, it's better to stay away or withdraw from the issue.
|
|
||||||
|
|
||||||
> If some user is violating our code of conduct [standards](https://github.com/actions/setup-go/blob/main/CODE_OF_CONDUCT.md#our-standards), refer to the [Enforcement](https://github.com/actions/setup-go/blob/main/CODE_OF_CONDUCT.md#enforcement) section of the Code of Conduct to resolve the conflict
|
|
||||||
|
|
||||||
|
|
||||||
## Review pull requests
|
|
||||||
|
|
||||||
|
|
||||||
Another great way to contribute is pull request reviews. Please, be extra kind: people who submit code/doc contributions are putting themselves in a pretty vulnerable position, and have put time and care into what they've done (even if that's not obvious to you!) Please, always respond with respect, and be understanding, but don't feel like you need to sacrifice your standards for their sake, either.
|
|
||||||
|
|
||||||
**How to review:**
|
|
||||||
|
|
||||||
- Go to the [pull requests](https://github.com/actions/setup-go/pulls)
|
|
||||||
- Make sure you're familiar with the code or documentation is updated, unless it's a minor change (spellchecking, minor formatting, etc.)
|
|
||||||
- Review changes using the GitHub functionality. You can ask a clarifying question, point out an error or suggest an alternative.
|
|
||||||
> Note: You may ask for minor changes - "nitpicks", but consider whether they are real blockers to merging or not
|
|
||||||
- Submit your review, which may include comments, an approval, or a changes request
|
|
204
lib/installer.js
Normal file
204
lib/installer.js
Normal file
@ -0,0 +1,204 @@
|
|||||||
|
"use strict";
|
||||||
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||||
|
return new (P || (P = Promise))(function (resolve, reject) {
|
||||||
|
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||||
|
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||||
|
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
|
||||||
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||||
|
});
|
||||||
|
};
|
||||||
|
var __importStar = (this && this.__importStar) || function (mod) {
|
||||||
|
if (mod && mod.__esModule) return mod;
|
||||||
|
var result = {};
|
||||||
|
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
|
||||||
|
result["default"] = mod;
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
// Load tempDirectory before it gets wiped by tool-cache
|
||||||
|
let tempDirectory = process.env['RUNNER_TEMPDIRECTORY'] || '';
|
||||||
|
const core = __importStar(require("@actions/core"));
|
||||||
|
const tc = __importStar(require("@actions/tool-cache"));
|
||||||
|
const os = __importStar(require("os"));
|
||||||
|
const path = __importStar(require("path"));
|
||||||
|
const util = __importStar(require("util"));
|
||||||
|
const semver = __importStar(require("semver"));
|
||||||
|
const restm = __importStar(require("typed-rest-client/RestClient"));
|
||||||
|
let osPlat = os.platform();
|
||||||
|
let osArch = os.arch();
|
||||||
|
if (!tempDirectory) {
|
||||||
|
let baseLocation;
|
||||||
|
if (process.platform === 'win32') {
|
||||||
|
// On windows use the USERPROFILE env variable
|
||||||
|
baseLocation = process.env['USERPROFILE'] || 'C:\\';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (process.platform === 'darwin') {
|
||||||
|
baseLocation = '/Users';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
baseLocation = '/home';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tempDirectory = path.join(baseLocation, 'actions', 'temp');
|
||||||
|
}
|
||||||
|
function getGo(version) {
|
||||||
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
const selected = yield determineVersion(version);
|
||||||
|
if (selected) {
|
||||||
|
version = selected;
|
||||||
|
}
|
||||||
|
// check cache
|
||||||
|
let toolPath;
|
||||||
|
toolPath = tc.find('go', normalizeVersion(version));
|
||||||
|
if (!toolPath) {
|
||||||
|
// download, extract, cache
|
||||||
|
toolPath = yield acquireGo(version);
|
||||||
|
core.debug('Go tool is cached under ' + toolPath);
|
||||||
|
}
|
||||||
|
setGoEnvironmentVariables(toolPath);
|
||||||
|
toolPath = path.join(toolPath, 'bin');
|
||||||
|
//
|
||||||
|
// prepend the tools path. instructs the agent to prepend for future tasks
|
||||||
|
//
|
||||||
|
core.addPath(toolPath);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
exports.getGo = getGo;
|
||||||
|
function acquireGo(version) {
|
||||||
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
//
|
||||||
|
// Download - a tool installer intimately knows how to get the tool (and construct urls)
|
||||||
|
//
|
||||||
|
let fileName = getFileName(version);
|
||||||
|
let downloadUrl = getDownloadUrl(fileName);
|
||||||
|
let downloadPath = null;
|
||||||
|
try {
|
||||||
|
downloadPath = yield tc.downloadTool(downloadUrl);
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
core.debug(error);
|
||||||
|
throw `Failed to download version ${version}: ${error}`;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Extract
|
||||||
|
//
|
||||||
|
let extPath = tempDirectory;
|
||||||
|
if (!extPath) {
|
||||||
|
throw new Error('Temp directory not set');
|
||||||
|
}
|
||||||
|
if (osPlat == 'win32') {
|
||||||
|
extPath = yield tc.extractZip(downloadPath);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
extPath = yield tc.extractTar(downloadPath);
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Install into the local tool cache - node extracts with a root folder that matches the fileName downloaded
|
||||||
|
//
|
||||||
|
const toolRoot = path.join(extPath, 'go');
|
||||||
|
version = normalizeVersion(version);
|
||||||
|
return yield tc.cacheDir(toolRoot, 'go', version);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function getFileName(version) {
|
||||||
|
const platform = osPlat == 'win32' ? 'windows' : osPlat;
|
||||||
|
const arch = osArch == 'x64' ? 'amd64' : '386';
|
||||||
|
const ext = osPlat == 'win32' ? 'zip' : 'tar.gz';
|
||||||
|
const filename = util.format('go%s.%s-%s.%s', version, platform, arch, ext);
|
||||||
|
return filename;
|
||||||
|
}
|
||||||
|
function getDownloadUrl(filename) {
|
||||||
|
return util.format('https://storage.googleapis.com/golang/%s', filename);
|
||||||
|
}
|
||||||
|
function setGoEnvironmentVariables(goRoot) {
|
||||||
|
core.exportVariable('GOROOT', goRoot);
|
||||||
|
const goPath = process.env['GOPATH'] || '';
|
||||||
|
const goBin = process.env['GOBIN'] || '';
|
||||||
|
// set GOPATH and GOBIN as user value
|
||||||
|
if (goPath) {
|
||||||
|
core.exportVariable('GOPATH', goPath);
|
||||||
|
}
|
||||||
|
if (goBin) {
|
||||||
|
core.exportVariable('GOBIN', goBin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// This function is required to convert the version 1.10 to 1.10.0.
|
||||||
|
// Because caching utility accept only sementic version,
|
||||||
|
// which have patch number as well.
|
||||||
|
function normalizeVersion(version) {
|
||||||
|
const versionPart = version.split('.');
|
||||||
|
if (versionPart[1] == null) {
|
||||||
|
//append minor and patch version if not available
|
||||||
|
return version.concat('.0.0');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// handle beta and rc: 1.10beta1 => 1.10.0-beta1, 1.10rc1 => 1.10.0-rc1
|
||||||
|
if (versionPart[1].includes('beta') || versionPart[1].includes('rc')) {
|
||||||
|
versionPart[1] = versionPart[1]
|
||||||
|
.replace('beta', '.0-beta')
|
||||||
|
.replace('rc', '.0-rc');
|
||||||
|
return versionPart.join('.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (versionPart[2] == null) {
|
||||||
|
//append patch version if not available
|
||||||
|
return version.concat('.0');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// handle beta and rc: 1.8.5beta1 => 1.8.5-beta1, 1.8.5rc1 => 1.8.5-rc1
|
||||||
|
if (versionPart[2].includes('beta') || versionPart[2].includes('rc')) {
|
||||||
|
versionPart[2] = versionPart[2]
|
||||||
|
.replace('beta', '-beta')
|
||||||
|
.replace('rc', '-rc');
|
||||||
|
return versionPart.join('.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
function determineVersion(version) {
|
||||||
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
if (!version.endsWith('.x')) {
|
||||||
|
const versionPart = version.split('.');
|
||||||
|
if (versionPart[1] == null || versionPart[2] == null) {
|
||||||
|
return yield getLatestVersion(version.concat('.x'));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return yield getLatestVersion(version);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function getLatestVersion(version) {
|
||||||
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
// clean .x syntax: 1.10.x -> 1.10
|
||||||
|
const trimmedVersion = version.slice(0, version.length - 2);
|
||||||
|
const versions = yield getPossibleVersions(trimmedVersion);
|
||||||
|
core.debug(`evaluating ${versions.length} versions`);
|
||||||
|
if (version.length === 0) {
|
||||||
|
throw new Error('unable to get latest version');
|
||||||
|
}
|
||||||
|
core.debug(`matched: ${versions[0]}`);
|
||||||
|
return versions[0];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function getAvailableVersions() {
|
||||||
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
let rest = new restm.RestClient('setup-go');
|
||||||
|
let tags = (yield rest.get('https://golang.org/dl/?mode=json&include=all'))
|
||||||
|
.result || [];
|
||||||
|
return tags.map(tag => tag.version.replace('go', ''));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function getPossibleVersions(version) {
|
||||||
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
const versions = yield getAvailableVersions();
|
||||||
|
const possibleVersions = versions.filter(v => v.startsWith(version));
|
||||||
|
const versionMap = new Map();
|
||||||
|
possibleVersions.forEach(v => versionMap.set(normalizeVersion(v), v));
|
||||||
|
return Array.from(versionMap.keys())
|
||||||
|
.sort(semver.rcompare)
|
||||||
|
.map(v => versionMap.get(v));
|
||||||
|
});
|
||||||
|
}
|
44
lib/setup-go.js
Normal file
44
lib/setup-go.js
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
"use strict";
|
||||||
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||||
|
return new (P || (P = Promise))(function (resolve, reject) {
|
||||||
|
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||||
|
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||||
|
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
|
||||||
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||||
|
});
|
||||||
|
};
|
||||||
|
var __importStar = (this && this.__importStar) || function (mod) {
|
||||||
|
if (mod && mod.__esModule) return mod;
|
||||||
|
var result = {};
|
||||||
|
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
|
||||||
|
result["default"] = mod;
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
const core = __importStar(require("@actions/core"));
|
||||||
|
const installer = __importStar(require("./installer"));
|
||||||
|
const path = __importStar(require("path"));
|
||||||
|
function run() {
|
||||||
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
try {
|
||||||
|
//
|
||||||
|
// Version is optional. If supplied, install / use from the tool cache
|
||||||
|
// If not supplied then task is still used to setup proxy, auth, etc...
|
||||||
|
//
|
||||||
|
let version = core.getInput('version');
|
||||||
|
if (!version) {
|
||||||
|
version = core.getInput('go-version');
|
||||||
|
}
|
||||||
|
if (version) {
|
||||||
|
yield installer.getGo(version);
|
||||||
|
}
|
||||||
|
// TODO: setup proxy from runner proxy config
|
||||||
|
const matchersPath = path.join(__dirname, '..', '.github');
|
||||||
|
console.log(`##[add-matcher]${path.join(matchersPath, 'go.json')}`);
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
core.setFailed(error.message);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
run();
|
@ -1,16 +0,0 @@
|
|||||||
{
|
|
||||||
"problemMatcher": [
|
|
||||||
{
|
|
||||||
"owner": "go",
|
|
||||||
"pattern": [
|
|
||||||
{
|
|
||||||
"regexp": "^\\s*(.+\\.go):(?:(\\d+):(\\d+):)? (.*)",
|
|
||||||
"file": 1,
|
|
||||||
"line": 2,
|
|
||||||
"column": 3,
|
|
||||||
"message": 4
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
7
node_modules/@actions/core/LICENSE.md
generated
vendored
Normal file
7
node_modules/@actions/core/LICENSE.md
generated
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
Copyright 2019 GitHub
|
||||||
|
|
||||||
|
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.
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user