mirror of
https://github.com/goreleaser/goreleaser-action
synced 2026-09-03 04:18:27 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
73cd4ffe39 | ||
|
|
97a9607547 | ||
|
|
689e48f9ac | ||
|
|
7e6b514c50 | ||
|
|
4ec11830b6 | ||
|
|
59060fdcfd | ||
|
|
177da47714 | ||
|
|
a47e8c32ac | ||
|
|
dcd4e58dba | ||
|
|
57e184bc5a | ||
|
|
ed0d97425c | ||
|
|
f06c13b6b1 | ||
|
|
d3934597ca | ||
|
|
ee731b1700 | ||
|
|
55de448558 | ||
|
|
a4f614e65e | ||
|
|
d2d17a6c5d | ||
|
|
d13def3a6e | ||
|
|
21549b6bea | ||
|
|
47c416d5e8 | ||
|
|
5daf1e915a | ||
|
|
5cc7ebb73d | ||
|
|
702f5f91c9 | ||
|
|
1a80836c5c | ||
|
|
a71152e827 |
+43
-69
@@ -37,25 +37,21 @@ jobs:
|
|||||||
- goreleaser
|
- goreleaser
|
||||||
- goreleaser-pro
|
- goreleaser-pro
|
||||||
steps:
|
steps:
|
||||||
-
|
- name: Checkout
|
||||||
name: Checkout
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
-
|
- name: Set up Go
|
||||||
name: Set up Go
|
uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
|
||||||
uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
|
|
||||||
with:
|
with:
|
||||||
go-version: stable
|
go-version: stable
|
||||||
-
|
- name: Check
|
||||||
name: Check
|
|
||||||
uses: ./
|
uses: ./
|
||||||
with:
|
with:
|
||||||
version: ${{ matrix.version }}
|
version: ${{ matrix.version }}
|
||||||
args: check --verbose
|
args: check --verbose
|
||||||
workdir: ./test
|
workdir: ./test
|
||||||
-
|
- name: GoReleaser
|
||||||
name: GoReleaser
|
|
||||||
if: ${{ !(github.event_name == 'pull_request' && matrix.distribution == 'goreleaser-pro') }}
|
if: ${{ !(github.event_name == 'pull_request' && matrix.distribution == 'goreleaser-pro') }}
|
||||||
uses: ./
|
uses: ./
|
||||||
env:
|
env:
|
||||||
@@ -81,30 +77,25 @@ jobs:
|
|||||||
- true
|
- true
|
||||||
- false
|
- false
|
||||||
steps:
|
steps:
|
||||||
-
|
- name: Checkout
|
||||||
name: Checkout
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
-
|
- name: Set up Go
|
||||||
name: Set up Go
|
uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
|
||||||
uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
|
|
||||||
with:
|
with:
|
||||||
go-version: 1.18
|
go-version: 1.18
|
||||||
-
|
- name: Install cosign
|
||||||
name: Install cosign
|
|
||||||
if: matrix.cosign
|
if: matrix.cosign
|
||||||
uses: sigstore/cosign-installer@d58896d6a1865668819e1d91763c7751a165e159 # v3.9.2
|
uses: sigstore/cosign-installer@6f9f17788090df1f26f669e9d70d6ae9567deba6 # v4.1.2
|
||||||
-
|
- name: GoReleaser
|
||||||
name: GoReleaser
|
|
||||||
if: ${{ !(github.event_name == 'pull_request' && matrix.distribution == 'goreleaser-pro') }}
|
if: ${{ !(github.event_name == 'pull_request' && matrix.distribution == 'goreleaser-pro') }}
|
||||||
uses: ./
|
uses: ./
|
||||||
with:
|
with:
|
||||||
distribution: ${{ matrix.distribution }}
|
distribution: ${{ matrix.distribution }}
|
||||||
version: ${{ matrix.version }}
|
version: ${{ matrix.version }}
|
||||||
install-only: true
|
install-only: true
|
||||||
-
|
- name: Check
|
||||||
name: Check
|
|
||||||
if: ${{ !(github.event_name == 'pull_request' && matrix.distribution == 'goreleaser-pro') }}
|
if: ${{ !(github.event_name == 'pull_request' && matrix.distribution == 'goreleaser-pro') }}
|
||||||
run: |
|
run: |
|
||||||
goreleaser check --verbose
|
goreleaser check --verbose
|
||||||
@@ -120,25 +111,21 @@ jobs:
|
|||||||
- macos-latest
|
- macos-latest
|
||||||
- windows-latest
|
- windows-latest
|
||||||
steps:
|
steps:
|
||||||
-
|
- name: Checkout
|
||||||
name: Checkout
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
-
|
- name: Set up Go
|
||||||
name: Set up Go
|
uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
|
||||||
uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
|
|
||||||
with:
|
with:
|
||||||
go-version: 1.18
|
go-version: 1.18
|
||||||
-
|
- name: Import GPG key
|
||||||
name: Import GPG key
|
|
||||||
id: import_gpg
|
id: import_gpg
|
||||||
uses: crazy-max/ghaction-import-gpg@2dc316deee8e90f13e1a351ab510b4d5bc0c82cd # v7.0.0
|
uses: crazy-max/ghaction-import-gpg@2dc316deee8e90f13e1a351ab510b4d5bc0c82cd # v7.0.0
|
||||||
with:
|
with:
|
||||||
gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY_TEST }}
|
gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY_TEST }}
|
||||||
passphrase: ${{ secrets.PASSPHRASE_TEST }}
|
passphrase: ${{ secrets.PASSPHRASE_TEST }}
|
||||||
-
|
- name: Check
|
||||||
name: Check
|
|
||||||
uses: ./
|
uses: ./
|
||||||
with:
|
with:
|
||||||
version: latest
|
version: latest
|
||||||
@@ -146,8 +133,7 @@ jobs:
|
|||||||
workdir: ./test
|
workdir: ./test
|
||||||
env:
|
env:
|
||||||
GPG_FINGERPRINT: ${{ steps.import_gpg.outputs.fingerprint }}
|
GPG_FINGERPRINT: ${{ steps.import_gpg.outputs.fingerprint }}
|
||||||
-
|
- name: GoReleaser
|
||||||
name: GoReleaser
|
|
||||||
uses: ./
|
uses: ./
|
||||||
with:
|
with:
|
||||||
version: latest
|
version: latest
|
||||||
@@ -159,31 +145,26 @@ jobs:
|
|||||||
upload-artifact:
|
upload-artifact:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
-
|
- name: Checkout
|
||||||
name: Checkout
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
-
|
- name: Set up Go
|
||||||
name: Set up Go
|
uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
|
||||||
uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
|
|
||||||
with:
|
with:
|
||||||
go-version: 1.18
|
go-version: 1.18
|
||||||
-
|
- name: Check
|
||||||
name: Check
|
|
||||||
uses: ./
|
uses: ./
|
||||||
with:
|
with:
|
||||||
args: check --verbose
|
args: check --verbose
|
||||||
workdir: ./test
|
workdir: ./test
|
||||||
-
|
- name: GoReleaser
|
||||||
name: GoReleaser
|
|
||||||
uses: ./
|
uses: ./
|
||||||
with:
|
with:
|
||||||
args: release --skip=publish --clean --snapshot
|
args: release --skip=publish --clean --snapshot
|
||||||
workdir: ./test
|
workdir: ./test
|
||||||
-
|
- name: Upload assets
|
||||||
name: Upload assets
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||||
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
|
|
||||||
with:
|
with:
|
||||||
name: myapp
|
name: myapp
|
||||||
path: ./test/dist/*
|
path: ./test/dist/*
|
||||||
@@ -191,24 +172,20 @@ jobs:
|
|||||||
dist:
|
dist:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
-
|
- name: Checkout
|
||||||
name: Checkout
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
-
|
- name: Set up Go
|
||||||
name: Set up Go
|
uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
|
||||||
uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
|
|
||||||
with:
|
with:
|
||||||
go-version: 1.18
|
go-version: 1.18
|
||||||
-
|
- name: GoReleaser
|
||||||
name: GoReleaser
|
|
||||||
uses: ./
|
uses: ./
|
||||||
with:
|
with:
|
||||||
args: release --config .goreleaser-dist.yml --skip=publish --clean --snapshot
|
args: release --config .goreleaser-dist.yml --skip=publish --clean --snapshot
|
||||||
workdir: ./test
|
workdir: ./test
|
||||||
-
|
- name: Check dist
|
||||||
name: Check dist
|
|
||||||
run: |
|
run: |
|
||||||
tree -nh ./test/_output
|
tree -nh ./test/_output
|
||||||
|
|
||||||
@@ -225,27 +202,24 @@ jobs:
|
|||||||
- goreleaser-pro
|
- goreleaser-pro
|
||||||
- goreleaser
|
- goreleaser
|
||||||
steps:
|
steps:
|
||||||
-
|
- name: Checkout
|
||||||
name: Checkout
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
-
|
- name: Set up Go
|
||||||
name: Set up Go
|
uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
|
||||||
uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
|
|
||||||
with:
|
with:
|
||||||
go-version: 1.18
|
go-version: 1.18
|
||||||
-
|
- name: GoReleaser
|
||||||
name: GoReleaser
|
|
||||||
uses: ./
|
uses: ./
|
||||||
with:
|
with:
|
||||||
install-only: true
|
install-only: true
|
||||||
distribution: ${{ matrix.distribution }}
|
distribution: ${{ matrix.distribution }}
|
||||||
version: nightly
|
version: nightly
|
||||||
-
|
env:
|
||||||
name: Check
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
- name: Check
|
||||||
run: |
|
run: |
|
||||||
goreleaser check -f ./test/.goreleaser.yml
|
goreleaser check -f ./test/.goreleaser.yml
|
||||||
goreleaser --version
|
goreleaser --version
|
||||||
goreleaser --version | grep nightly
|
goreleaser --version | grep nightly
|
||||||
|
|
||||||
|
|||||||
@@ -28,19 +28,15 @@ jobs:
|
|||||||
tag:
|
tag:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
-
|
- name: Checkout
|
||||||
name: Checkout
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
-
|
- name: Git config
|
||||||
name: Git config
|
|
||||||
run: |
|
run: |
|
||||||
git config user.name "github-actions[bot]"
|
git config user.name "github-actions[bot]"
|
||||||
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
||||||
-
|
- name: Move ${{ github.event.inputs.major_version }} to ${{ github.event.inputs.target }}
|
||||||
name: Move ${{ github.event.inputs.major_version }} to ${{ github.event.inputs.target }}
|
|
||||||
run: git tag -f ${{ github.event.inputs.major_version }} ${{ github.event.inputs.target }}
|
run: git tag -f ${{ github.event.inputs.major_version }} ${{ github.event.inputs.target }}
|
||||||
-
|
- name: Push
|
||||||
name: Push
|
|
||||||
run: git push origin ${{ github.event.inputs.major_version }} --force
|
run: git push origin ${{ github.event.inputs.major_version }} --force
|
||||||
|
|||||||
+10
-16
@@ -19,30 +19,24 @@ jobs:
|
|||||||
test:
|
test:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
-
|
- name: Checkout
|
||||||
name: Checkout
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
-
|
- name: Setup Node.js
|
||||||
name: Setup Node.js
|
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
|
||||||
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v6.0.0
|
|
||||||
with:
|
with:
|
||||||
node-version-file: '.node-version'
|
node-version-file: '.node-version'
|
||||||
cache: npm
|
cache: npm
|
||||||
-
|
- name: Install cosign
|
||||||
name: Install cosign
|
uses: sigstore/cosign-installer@6f9f17788090df1f26f669e9d70d6ae9567deba6 # v4.1.2
|
||||||
uses: sigstore/cosign-installer@d58896d6a1865668819e1d91763c7751a165e159 # v3.9.2
|
- name: Install dependencies
|
||||||
-
|
|
||||||
name: Install dependencies
|
|
||||||
run: npm ci
|
run: npm ci
|
||||||
-
|
- name: Test
|
||||||
name: Test
|
|
||||||
run: npm test
|
run: npm test
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
-
|
- name: Upload coverage
|
||||||
name: Upload coverage
|
uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0
|
||||||
uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v6.0.0
|
|
||||||
with:
|
with:
|
||||||
files: ./coverage/clover.xml
|
files: ./coverage/clover.xml
|
||||||
|
|||||||
@@ -19,45 +19,35 @@ jobs:
|
|||||||
lint:
|
lint:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
-
|
- name: Checkout
|
||||||
name: Checkout
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
- name: Setup Node.js
|
||||||
-
|
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
|
||||||
name: Setup Node.js
|
|
||||||
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v6.0.0
|
|
||||||
with:
|
with:
|
||||||
node-version-file: '.node-version'
|
node-version-file: '.node-version'
|
||||||
cache: npm
|
cache: npm
|
||||||
-
|
- name: Install dependencies
|
||||||
name: Install dependencies
|
|
||||||
run: npm ci
|
run: npm ci
|
||||||
-
|
- name: Format check
|
||||||
name: Format check
|
|
||||||
run: npm run format-check
|
run: npm run format-check
|
||||||
-
|
- name: Lint
|
||||||
name: Lint
|
|
||||||
run: npm run lint
|
run: npm run lint
|
||||||
|
|
||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
-
|
- name: Checkout
|
||||||
name: Checkout
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
- name: Setup Node.js
|
||||||
-
|
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v6.0.0
|
||||||
name: Setup Node.js
|
|
||||||
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v6.0.0
|
|
||||||
with:
|
with:
|
||||||
node-version-file: '.node-version'
|
node-version-file: '.node-version'
|
||||||
cache: npm
|
cache: npm
|
||||||
-
|
- name: Install dependencies
|
||||||
name: Install dependencies
|
|
||||||
run: npm ci --ignore-scripts
|
run: npm ci --ignore-scripts
|
||||||
-
|
- name: Rebuild dist
|
||||||
name: Rebuild dist
|
|
||||||
run: npm run build
|
run: npm run build
|
||||||
-
|
- name: Compare dist
|
||||||
name: Compare dist
|
|
||||||
id: diff
|
id: diff
|
||||||
run: |
|
run: |
|
||||||
if [ "$(git diff --ignore-space-at-eol dist | wc -l)" -gt "0" ]; then
|
if [ "$(git diff --ignore-space-at-eol dist | wc -l)" -gt "0" ]; then
|
||||||
@@ -65,10 +55,9 @@ jobs:
|
|||||||
git diff dist
|
git diff dist
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
-
|
- name: Upload built dist on failure
|
||||||
name: Upload built dist on failure
|
|
||||||
if: ${{ failure() && steps.diff.conclusion == 'failure' }}
|
if: ${{ failure() && steps.diff.conclusion == 'failure' }}
|
||||||
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||||
with:
|
with:
|
||||||
name: dist
|
name: dist
|
||||||
path: dist
|
path: dist
|
||||||
@@ -76,20 +65,16 @@ jobs:
|
|||||||
vendor:
|
vendor:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
-
|
- name: Checkout
|
||||||
name: Checkout
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
- name: Setup Node.js
|
||||||
-
|
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v6.0.0
|
||||||
name: Setup Node.js
|
|
||||||
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v6.0.0
|
|
||||||
with:
|
with:
|
||||||
node-version-file: '.node-version'
|
node-version-file: '.node-version'
|
||||||
cache: npm
|
cache: npm
|
||||||
-
|
- name: Refresh package-lock.json
|
||||||
name: Refresh package-lock.json
|
|
||||||
run: npm install --package-lock-only
|
run: npm install --package-lock-only
|
||||||
-
|
- name: Compare package-lock.json
|
||||||
name: Compare package-lock.json
|
|
||||||
run: |
|
run: |
|
||||||
if [ -n "$(git status --porcelain -- package-lock.json)" ]; then
|
if [ -n "$(git status --porcelain -- package-lock.json)" ]; then
|
||||||
echo "package-lock.json is out of sync with package.json. Run 'npm install' and commit." >&2
|
echo "package-lock.json is out of sync with package.json. Run 'npm install' and commit." >&2
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ ___
|
|||||||
* [Signing](#signing)
|
* [Signing](#signing)
|
||||||
* [Upload artifacts](#upload-artifacts)
|
* [Upload artifacts](#upload-artifacts)
|
||||||
* [Install Only](#install-only)
|
* [Install Only](#install-only)
|
||||||
|
* [Cache the binary](#cache-the-binary)
|
||||||
* [Customizing](#customizing)
|
* [Customizing](#customizing)
|
||||||
* [inputs](#inputs)
|
* [inputs](#inputs)
|
||||||
* [outputs](#outputs)
|
* [outputs](#outputs)
|
||||||
@@ -217,6 +218,23 @@ steps:
|
|||||||
run: goreleaser -v
|
run: goreleaser -v
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Cache the binary
|
||||||
|
|
||||||
|
The action looks for GoReleaser in the [runner tool cache][toolcache] before it
|
||||||
|
downloads. A second use of the action in the same job, or any job on a
|
||||||
|
self-hosted runner that already has the version, installs immediately.
|
||||||
|
|
||||||
|
A binary taken from the tool cache is not verified again. The cache records
|
||||||
|
whether checksum or checksum and cosign verification completed. When cosign is
|
||||||
|
available, the action only reuses a signature-verified entry. A binary whose
|
||||||
|
checksum could not be verified is used for that invocation but is not cached.
|
||||||
|
|
||||||
|
On a self-hosted runner the tool cache is kept between jobs, so it must be
|
||||||
|
trusted like the runner itself. GitHub-hosted runners start with an empty tool
|
||||||
|
cache in every job, so they always download and verify.
|
||||||
|
|
||||||
|
[toolcache]: https://github.com/actions/toolkit/tree/main/packages/tool-cache
|
||||||
|
|
||||||
## Customizing
|
## Customizing
|
||||||
|
|
||||||
### inputs
|
### inputs
|
||||||
|
|||||||
@@ -56,12 +56,10 @@ describe('getRelease', () => {
|
|||||||
expect(release?.tag_name).not.toEqual('');
|
expect(release?.tag_name).not.toEqual('');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('resolves nightly to the legacy nightly tag for OSS GoReleaser', async () => {
|
it('resolves nightly to a <version>-<sha>-nightly release for OSS GoReleaser', async () => {
|
||||||
// No <version>-<sha>-nightly release exists in goreleaser/goreleaser yet,
|
|
||||||
// so this should fall back to the legacy moving `nightly` tag.
|
|
||||||
const release = await github.getRelease('goreleaser', 'nightly');
|
const release = await github.getRelease('goreleaser', 'nightly');
|
||||||
expect(release).not.toBeNull();
|
expect(release).not.toBeNull();
|
||||||
expect(release.tag_name).toEqual('nightly');
|
expect(release.tag_name).toMatch(github.nightlyTagRegex);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('resolves nightly to a <version>-<sha>-nightly release for GoReleaser Pro', async () => {
|
it('resolves nightly to a <version>-<sha>-nightly release for GoReleaser Pro', async () => {
|
||||||
@@ -106,3 +104,16 @@ describe('getRelease', () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('latestNightlyRelease', () => {
|
||||||
|
it('returns the newest nightly by published_at even when API order is wrong', () => {
|
||||||
|
const release = github.latestNightlyRelease([
|
||||||
|
{tag_name: 'v2.16.0-c9b458fa-nightly', published_at: '2026-05-12T01:27:50Z'},
|
||||||
|
{tag_name: 'v2.16.0-6724de64-nightly', published_at: '2026-05-13T01:32:53Z'},
|
||||||
|
{tag_name: 'v2.16.0-2827930b-nightly', published_at: '2026-05-17T01:34:11Z'},
|
||||||
|
{tag_name: 'v2.15.4', published_at: '2026-04-21T14:07:57Z'}
|
||||||
|
]);
|
||||||
|
|
||||||
|
expect(release?.tag_name).toEqual('v2.16.0-2827930b-nightly');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
@@ -0,0 +1,121 @@
|
|||||||
|
import {afterEach, beforeEach, describe, expect, it, jest} from '@jest/globals';
|
||||||
|
import * as crypto from 'crypto';
|
||||||
|
import * as fs from 'fs';
|
||||||
|
import * as os from 'os';
|
||||||
|
import * as path from 'path';
|
||||||
|
|
||||||
|
const find = jest.fn<(tool: string, version: string) => string>();
|
||||||
|
const downloadTool = jest.fn<(url: string) => Promise<string>>();
|
||||||
|
const extractTar = jest.fn<(archive: string) => Promise<string>>();
|
||||||
|
const extractZip = jest.fn<(archive: string) => Promise<string>>();
|
||||||
|
const cacheDir = jest.fn<(source: string, tool: string, version: string) => Promise<string>>();
|
||||||
|
const which = jest.fn<(tool: string, check: boolean) => Promise<string>>();
|
||||||
|
const exec = jest.fn<(command: string, args: string[]) => Promise<number>>();
|
||||||
|
|
||||||
|
jest.unstable_mockModule('@actions/tool-cache', () => ({
|
||||||
|
find,
|
||||||
|
downloadTool,
|
||||||
|
extractTar,
|
||||||
|
extractZip,
|
||||||
|
cacheDir
|
||||||
|
}));
|
||||||
|
jest.unstable_mockModule('@actions/io', () => ({which}));
|
||||||
|
jest.unstable_mockModule('@actions/exec', () => ({exec}));
|
||||||
|
|
||||||
|
const goreleaser = await import('../src/goreleaser');
|
||||||
|
|
||||||
|
describe('runner tool cache verification', () => {
|
||||||
|
let tempDir: string;
|
||||||
|
let archivePath: string;
|
||||||
|
let checksumsPath: string;
|
||||||
|
let bundlePath: string;
|
||||||
|
let extractedPath: string;
|
||||||
|
let cosignPath: string;
|
||||||
|
let cache: Map<string, string>;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'goreleaser-cache-'));
|
||||||
|
archivePath = path.join(tempDir, 'archive');
|
||||||
|
checksumsPath = path.join(tempDir, 'checksums.txt');
|
||||||
|
bundlePath = path.join(tempDir, 'checksums.txt.sigstore.json');
|
||||||
|
extractedPath = path.join(tempDir, 'extracted');
|
||||||
|
fs.writeFileSync(archivePath, 'archive');
|
||||||
|
fs.writeFileSync(bundlePath, '{}');
|
||||||
|
fs.mkdirSync(extractedPath);
|
||||||
|
|
||||||
|
const checksum = crypto.createHash('sha256').update('archive').digest('hex');
|
||||||
|
fs.writeFileSync(
|
||||||
|
checksumsPath,
|
||||||
|
[
|
||||||
|
`${checksum} goreleaser_Linux_x86_64.tar.gz`,
|
||||||
|
`${checksum} goreleaser_Darwin_all.tar.gz`,
|
||||||
|
`${checksum} goreleaser_Windows_x86_64.zip`
|
||||||
|
].join('\n')
|
||||||
|
);
|
||||||
|
|
||||||
|
cosignPath = '';
|
||||||
|
cache = new Map();
|
||||||
|
find.mockImplementation((tool, version) => cache.get(`${tool}:${version}`) || '');
|
||||||
|
downloadTool.mockImplementation(async url => {
|
||||||
|
if (url.endsWith('/checksums.txt')) {
|
||||||
|
return checksumsPath;
|
||||||
|
}
|
||||||
|
if (url.endsWith('/checksums.txt.sigstore.json')) {
|
||||||
|
return bundlePath;
|
||||||
|
}
|
||||||
|
return archivePath;
|
||||||
|
});
|
||||||
|
extractTar.mockResolvedValue(extractedPath);
|
||||||
|
extractZip.mockResolvedValue(extractedPath);
|
||||||
|
cacheDir.mockImplementation(async (_source, tool, version) => {
|
||||||
|
const destination = path.join(tempDir, tool, version);
|
||||||
|
cache.set(`${tool}:${version}`, destination);
|
||||||
|
return destination;
|
||||||
|
});
|
||||||
|
which.mockImplementation(async () => cosignPath);
|
||||||
|
exec.mockResolvedValue(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
fs.rmSync(tempDir, {recursive: true, force: true});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not cache a binary when checksum verification is skipped', async () => {
|
||||||
|
downloadTool.mockImplementation(async url => {
|
||||||
|
if (url.endsWith('/checksums.txt')) {
|
||||||
|
throw new Error('checksums unavailable');
|
||||||
|
}
|
||||||
|
return archivePath;
|
||||||
|
});
|
||||||
|
|
||||||
|
await goreleaser.install('goreleaser', 'v2.15.3');
|
||||||
|
await goreleaser.install('goreleaser', 'v2.15.3');
|
||||||
|
|
||||||
|
expect(cacheDir).not.toHaveBeenCalled();
|
||||||
|
expect(downloadTool.mock.calls.filter(([url]) => !url.endsWith('/checksums.txt'))).toHaveLength(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not reuse a checksum-only entry when cosign becomes available', async () => {
|
||||||
|
await goreleaser.install('goreleaser', 'v2.15.3');
|
||||||
|
expect(cacheDir).toHaveBeenLastCalledWith(extractedPath, 'goreleaser-checksum', '2.15.3');
|
||||||
|
|
||||||
|
cosignPath = '/usr/local/bin/cosign';
|
||||||
|
await goreleaser.install('goreleaser', 'v2.15.3');
|
||||||
|
await goreleaser.install('goreleaser', 'v2.15.3');
|
||||||
|
|
||||||
|
expect(exec).toHaveBeenCalledTimes(1);
|
||||||
|
expect(cacheDir).toHaveBeenLastCalledWith(extractedPath, 'goreleaser-cosign', '2.15.3');
|
||||||
|
expect(downloadTool.mock.calls.filter(([url]) => !url.includes('checksums.txt'))).toHaveLength(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('reuses checksum verification for releases without sigstore bundles', async () => {
|
||||||
|
cosignPath = '/usr/local/bin/cosign';
|
||||||
|
|
||||||
|
await goreleaser.install('goreleaser', 'v2.12.4');
|
||||||
|
await goreleaser.install('goreleaser', 'v2.12.4');
|
||||||
|
|
||||||
|
expect(exec).not.toHaveBeenCalled();
|
||||||
|
expect(cacheDir).toHaveBeenCalledTimes(1);
|
||||||
|
expect(downloadTool.mock.calls.filter(([url]) => !url.includes('checksums.txt'))).toHaveLength(1);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -57,6 +57,38 @@ describe('install', () => {
|
|||||||
const bin = await goreleaser.install('goreleaser-pro', 'latest');
|
const bin = await goreleaser.install('goreleaser-pro', 'latest');
|
||||||
expect(fs.existsSync(bin)).toBe(true);
|
expect(fs.existsSync(bin)).toBe(true);
|
||||||
}, 100000);
|
}, 100000);
|
||||||
|
|
||||||
|
it('reuses the runner tool cache instead of downloading again', async () => {
|
||||||
|
const first = await goreleaser.install('goreleaser', 'v2.15.3');
|
||||||
|
|
||||||
|
const written: string[] = [];
|
||||||
|
const stdout = process.stdout.write.bind(process.stdout);
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
process.stdout.write = ((chunk: any, ...rest: any[]): boolean => {
|
||||||
|
written.push(chunk.toString());
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
return (stdout as any)(chunk, ...rest);
|
||||||
|
}) as typeof process.stdout.write;
|
||||||
|
let second: string;
|
||||||
|
try {
|
||||||
|
second = await goreleaser.install('goreleaser', 'v2.15.3');
|
||||||
|
} finally {
|
||||||
|
process.stdout.write = stdout;
|
||||||
|
}
|
||||||
|
|
||||||
|
const logs = written.join('');
|
||||||
|
expect(logs).toContain('found in the runner tool cache');
|
||||||
|
expect(logs).not.toContain('Downloading https://github.com/goreleaser');
|
||||||
|
expect(second).toEqual(first);
|
||||||
|
expect(fs.existsSync(second)).toBe(true);
|
||||||
|
}, 100000);
|
||||||
|
|
||||||
|
it('does not share the tool cache between distributions', async () => {
|
||||||
|
const oss = await goreleaser.install('goreleaser', 'v2.15.3');
|
||||||
|
const pro = await goreleaser.install('goreleaser-pro', 'v2.15.3');
|
||||||
|
expect(pro).not.toEqual(oss);
|
||||||
|
expect(fs.existsSync(pro)).toBe(true);
|
||||||
|
}, 100000);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('distribSuffix', () => {
|
describe('distribSuffix', () => {
|
||||||
@@ -104,18 +136,6 @@ describe('getCertificateIdentity', () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('uses nightly-oss.yml@refs/heads/main for OSS legacy nightly tag', () => {
|
|
||||||
expect(goreleaser.getCertificateIdentity('goreleaser', 'nightly')).toEqual(
|
|
||||||
'https://github.com/goreleaser/goreleaser/.github/workflows/nightly-oss.yml@refs/heads/main'
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('uses nightly-pro.yml@refs/heads/main for Pro legacy nightly tag', () => {
|
|
||||||
expect(goreleaser.getCertificateIdentity('goreleaser-pro', 'nightly')).toEqual(
|
|
||||||
'https://github.com/goreleaser/goreleaser-pro-internal/.github/workflows/nightly-pro.yml@refs/heads/main'
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('uses nightly-oss.yml@refs/heads/main for OSS nightly tag', () => {
|
it('uses nightly-oss.yml@refs/heads/main for OSS nightly tag', () => {
|
||||||
expect(goreleaser.getCertificateIdentity('goreleaser', 'v2.16.0-abc1234-nightly')).toEqual(
|
expect(goreleaser.getCertificateIdentity('goreleaser', 'v2.16.0-abc1234-nightly')).toEqual(
|
||||||
'https://github.com/goreleaser/goreleaser/.github/workflows/nightly-oss.yml@refs/heads/main'
|
'https://github.com/goreleaser/goreleaser/.github/workflows/nightly-oss.yml@refs/heads/main'
|
||||||
|
|||||||
+8
-8
File diff suppressed because one or more lines are too long
Generated
+127
-28
@@ -7,13 +7,13 @@
|
|||||||
"name": "goreleaser-action",
|
"name": "goreleaser-action",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/core": "^3.0.0",
|
"@actions/core": "^3.0.1",
|
||||||
"@actions/exec": "^3.0.0",
|
"@actions/exec": "^3.0.0",
|
||||||
"@actions/http-client": "^4.0.0",
|
"@actions/http-client": "^4.0.1",
|
||||||
"@actions/tool-cache": "^4.0.0",
|
"@actions/tool-cache": "^4.0.0",
|
||||||
"js-yaml": "^4.1.1",
|
"js-yaml": "^5.4.1",
|
||||||
"semver": "^7.7.4",
|
"semver": "^7.8.5",
|
||||||
"yargs": "^18.0.0"
|
"yargs": "^18.1.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^24.0.0",
|
"@types/node": "^24.0.0",
|
||||||
@@ -34,9 +34,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@actions/core": {
|
"node_modules/@actions/core": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/@actions/core/-/core-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/@actions/core/-/core-3.0.1.tgz",
|
||||||
"integrity": "sha512-zYt6cz+ivnTmiT/ksRVriMBOiuoUpDCJJlZ5KPl2/FRdvwU3f7MPh9qftvbkXJThragzUZieit2nyHUyw53Seg==",
|
"integrity": "sha512-a6d/Nwahm9fliVGRhdhofo40HjHQasUPusmc7vBfyky+7Z+P2A1J68zyFVaNcEclc/Se+eO595oAr5nwEIoIUA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/exec": "^3.0.0",
|
"@actions/exec": "^3.0.0",
|
||||||
@@ -53,9 +53,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@actions/http-client": {
|
"node_modules/@actions/http-client": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-4.0.1.tgz",
|
||||||
"integrity": "sha512-QuwPsgVMsD6qaPD57GLZi9sqzAZCtiJT8kVBCDpLtxhL5MydQ4gS+DrejtZZPdIYyB1e95uCK9Luyds7ybHI3g==",
|
"integrity": "sha512-+Nvd1ImaOZBSoPbsUtEhv+1z99H12xzncCkz0a3RuehINE81FZSe2QTj3uvAPTcJX/SCzUQHQ0D1GrPMbrPitg==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"tunnel": "^0.0.6",
|
"tunnel": "^0.0.6",
|
||||||
@@ -685,6 +685,29 @@
|
|||||||
"concat-map": "0.0.1"
|
"concat-map": "0.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@eslint/eslintrc/node_modules/js-yaml": {
|
||||||
|
"version": "4.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.0.tgz",
|
||||||
|
"integrity": "sha512-1td788aAnnZ5qs7V2QIRl1owjtYpbKt749Y3xauqQgwIIGF/xXWz1wMTEBx5O3LK3lXLVuqXPdPxj2BoFHaW9Q==",
|
||||||
|
"dev": true,
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/puzrin"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/nodeca"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"argparse": "^2.0.1"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"js-yaml": "bin/js-yaml.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@eslint/eslintrc/node_modules/minimatch": {
|
"node_modules/@eslint/eslintrc/node_modules/minimatch": {
|
||||||
"version": "3.1.2",
|
"version": "3.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||||
@@ -2757,6 +2780,29 @@
|
|||||||
"concat-map": "0.0.1"
|
"concat-map": "0.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/eslint/node_modules/js-yaml": {
|
||||||
|
"version": "4.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.0.tgz",
|
||||||
|
"integrity": "sha512-1td788aAnnZ5qs7V2QIRl1owjtYpbKt749Y3xauqQgwIIGF/xXWz1wMTEBx5O3LK3lXLVuqXPdPxj2BoFHaW9Q==",
|
||||||
|
"dev": true,
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/puzrin"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/nodeca"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"argparse": "^2.0.1"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"js-yaml": "bin/js-yaml.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/eslint/node_modules/minimatch": {
|
"node_modules/eslint/node_modules/minimatch": {
|
||||||
"version": "3.1.2",
|
"version": "3.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||||
@@ -3093,9 +3139,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/get-east-asian-width": {
|
"node_modules/get-east-asian-width": {
|
||||||
"version": "1.4.0",
|
"version": "1.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.6.0.tgz",
|
||||||
"integrity": "sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==",
|
"integrity": "sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18"
|
"node": ">=18"
|
||||||
@@ -4217,15 +4263,25 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/js-yaml": {
|
"node_modules/js-yaml": {
|
||||||
"version": "4.1.1",
|
"version": "5.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-5.4.1.tgz",
|
||||||
"integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==",
|
"integrity": "sha512-28R/k+NAjeuf7+CKlTxWZVExJGwVVLwY06DgEnOMz2gEpfNkDcD7QvyiVPT0xy0XXhU8vHsd4Ot42OOPdJG7dQ==",
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/puzrin"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/nodeca"
|
||||||
|
}
|
||||||
|
],
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"argparse": "^2.0.1"
|
"argparse": "^2.0.1"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
"js-yaml": "bin/js-yaml.js"
|
"js-yaml": "bin/js-yaml.mjs"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/jsesc": {
|
"node_modules/jsesc": {
|
||||||
@@ -5058,9 +5114,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/semver": {
|
"node_modules/semver": {
|
||||||
"version": "7.7.4",
|
"version": "7.8.5",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz",
|
||||||
"integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==",
|
"integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"bin": {
|
"bin": {
|
||||||
"semver": "bin/semver.js"
|
"semver": "bin/semver.js"
|
||||||
@@ -5609,9 +5665,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/undici": {
|
"node_modules/undici": {
|
||||||
"version": "6.24.1",
|
"version": "6.28.0",
|
||||||
"resolved": "https://registry.npmjs.org/undici/-/undici-6.24.1.tgz",
|
"resolved": "https://registry.npmjs.org/undici/-/undici-6.28.0.tgz",
|
||||||
"integrity": "sha512-sC+b0tB1whOCzbtlx20fx3WgCXwkW627p4EA9uM+/tNNPkSS+eSEld6pAs9nDv7WbY1UUljBMYPtu9BCOrCWKA==",
|
"integrity": "sha512-LIY910g9TI13YS95lrMFrs8Rm/u/irgHeTWoKCoteeJ04CUJ92eEfj0rVn+7VKMPBpUPiUoBKfhNyLI23EE/KA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18.17"
|
"node": ">=18.17"
|
||||||
@@ -5824,15 +5880,15 @@
|
|||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
"node_modules/yargs": {
|
"node_modules/yargs": {
|
||||||
"version": "18.0.0",
|
"version": "18.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-18.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/yargs/-/yargs-18.1.0.tgz",
|
||||||
"integrity": "sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg==",
|
"integrity": "sha512-2rAgRKu54VsHkqI0/tYkmluGXHD4KW7yZoycuqDQ15QOTnc2VVfy0nN/1eMhnQLO00A+dwtK20xuCnc1YGeUyg==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"cliui": "^9.0.1",
|
"cliui": "^9.0.1",
|
||||||
"escalade": "^3.1.1",
|
"escalade": "^3.1.1",
|
||||||
"get-caller-file": "^2.0.5",
|
"get-caller-file": "^2.0.5",
|
||||||
"string-width": "^7.2.0",
|
"string-width": "^8.2.1",
|
||||||
"y18n": "^5.0.5",
|
"y18n": "^5.0.5",
|
||||||
"yargs-parser": "^22.0.0"
|
"yargs-parser": "^22.0.0"
|
||||||
},
|
},
|
||||||
@@ -5850,6 +5906,49 @@
|
|||||||
"node": ">=12"
|
"node": ">=12"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/yargs/node_modules/ansi-regex": {
|
||||||
|
"version": "6.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz",
|
||||||
|
"integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/chalk/ansi-regex?sponsor=1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/yargs/node_modules/string-width": {
|
||||||
|
"version": "8.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/string-width/-/string-width-8.2.2.tgz",
|
||||||
|
"integrity": "sha512-GaPUh5gfdrYzqeVNZvUfT23vYYxXzKYidUcnMtJg/3rxRV63EFZy3k6xfKlmfeJD0176lnUV/Usr3XcwSvFzpg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"get-east-asian-width": "^1.5.0",
|
||||||
|
"strip-ansi": "^7.1.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=20"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/yargs/node_modules/strip-ansi": {
|
||||||
|
"version": "7.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz",
|
||||||
|
"integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"ansi-regex": "^6.2.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/chalk/strip-ansi?sponsor=1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/yargs/node_modules/yargs-parser": {
|
"node_modules/yargs/node_modules/yargs-parser": {
|
||||||
"version": "22.0.0",
|
"version": "22.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-22.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-22.0.0.tgz",
|
||||||
|
|||||||
+5
-6
@@ -23,15 +23,14 @@
|
|||||||
],
|
],
|
||||||
"author": "CrazyMax",
|
"author": "CrazyMax",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/core": "^3.0.0",
|
"@actions/core": "^3.0.1",
|
||||||
"@actions/exec": "^3.0.0",
|
"@actions/exec": "^3.0.0",
|
||||||
"@actions/http-client": "^4.0.0",
|
"@actions/http-client": "^4.0.1",
|
||||||
"@actions/tool-cache": "^4.0.0",
|
"@actions/tool-cache": "^4.0.0",
|
||||||
"js-yaml": "^4.1.1",
|
"js-yaml": "^5.4.1",
|
||||||
"semver": "^7.7.4",
|
"semver": "^7.8.5",
|
||||||
"yargs": "^18.0.0"
|
"yargs": "^18.1.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^24.0.0",
|
"@types/node": "^24.0.0",
|
||||||
|
|||||||
+13
-9
@@ -28,13 +28,21 @@ const withRetry = async <T>(operation: () => Promise<T>): Promise<T> => {
|
|||||||
|
|
||||||
export interface GitHubRelease {
|
export interface GitHubRelease {
|
||||||
tag_name: string;
|
tag_name: string;
|
||||||
|
published_at?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Matches the new-style nightly release tag pattern: vX.Y.Z-<sha>-nightly
|
// Matches the new-style nightly release tag pattern: vX.Y.Z-<sha>-nightly
|
||||||
export const nightlyTagRegex = /^v\d+\.\d+\.\d+-[0-9a-f]+-nightly$/i;
|
export const nightlyTagRegex = /^v\d+\.\d+\.\d+-[0-9a-f]+-nightly$/i;
|
||||||
|
|
||||||
export const isNightlyTag = (tag: string): boolean => {
|
export const isNightlyTag = (tag: string): boolean => {
|
||||||
return tag === 'nightly' || nightlyTagRegex.test(tag);
|
return nightlyTagRegex.test(tag);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const latestNightlyRelease = (releases: Array<GitHubRelease>): GitHubRelease | undefined => {
|
||||||
|
return releases
|
||||||
|
.filter(r => nightlyTagRegex.test(r.tag_name))
|
||||||
|
.sort((a, b) => (b.published_at || '').localeCompare(a.published_at || ''))
|
||||||
|
.shift();
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getRelease = async (distribution: string, version: string): Promise<GitHubRelease> => {
|
export const getRelease = async (distribution: string, version: string): Promise<GitHubRelease> => {
|
||||||
@@ -113,16 +121,12 @@ const resolveNightly = async (distribution: string): Promise<GitHubRelease> => {
|
|||||||
return <Array<GitHubRelease>>JSON.parse(body);
|
return <Array<GitHubRelease>>JSON.parse(body);
|
||||||
});
|
});
|
||||||
|
|
||||||
const match = releases.find(r => nightlyTagRegex.test(r.tag_name));
|
const match = latestNightlyRelease(releases);
|
||||||
if (match) {
|
if (!match) {
|
||||||
|
throw new Error(`No '<version>-<sha>-nightly' release found in ${url}`);
|
||||||
|
}
|
||||||
core.info(`Resolved nightly to ${match.tag_name}`);
|
core.info(`Resolved nightly to ${match.tag_name}`);
|
||||||
return match;
|
return match;
|
||||||
}
|
|
||||||
|
|
||||||
// Fallback to the legacy moving `nightly` tag during the transition period,
|
|
||||||
// until goreleaser stops publishing it.
|
|
||||||
core.warning(`No '<version>-<sha>-nightly' release found in ${url}, falling back to 'nightly' tag`);
|
|
||||||
return {tag_name: 'nightly'};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const resolveVersion = async (distribution: string, version: string): Promise<string | null> => {
|
const resolveVersion = async (distribution: string, version: string): Promise<string | null> => {
|
||||||
|
|||||||
+77
-27
@@ -1,56 +1,90 @@
|
|||||||
import * as crypto from 'crypto';
|
import * as crypto from 'crypto';
|
||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import yaml from 'js-yaml';
|
import * as yaml from 'js-yaml';
|
||||||
import * as context from './context';
|
import * as context from './context';
|
||||||
import * as github from './github';
|
import * as github from './github';
|
||||||
import * as core from '@actions/core';
|
import * as core from '@actions/core';
|
||||||
import * as exec from '@actions/exec';
|
import * as exec from '@actions/exec';
|
||||||
import * as io from '@actions/io';
|
import * as io from '@actions/io';
|
||||||
import * as tc from '@actions/tool-cache';
|
import * as tc from '@actions/tool-cache';
|
||||||
|
import * as semver from 'semver';
|
||||||
|
|
||||||
|
type VerificationLevel = 'checksum' | 'cosign';
|
||||||
|
|
||||||
export async function install(distribution: string, version: string): Promise<string> {
|
export async function install(distribution: string, version: string): Promise<string> {
|
||||||
const release: github.GitHubRelease = await github.getRelease(distribution, version);
|
const release: github.GitHubRelease = await github.getRelease(distribution, version);
|
||||||
|
const tag = release.tag_name;
|
||||||
|
const toolVersion = tag.replace(/^v/, '');
|
||||||
|
const cosign = await io.which('cosign', false);
|
||||||
|
const verificationLevel = cosign && supportsCosignBundle(tag) ? 'cosign' : 'checksum';
|
||||||
|
|
||||||
|
const toolPath = findCachedTool(distribution, toolVersion, verificationLevel);
|
||||||
|
if (toolPath) {
|
||||||
|
core.info(`GoReleaser ${tag} found in the runner tool cache: ${toolPath}`);
|
||||||
|
return getExePath(toolPath);
|
||||||
|
}
|
||||||
|
|
||||||
const filename = getFilename(distribution);
|
const filename = getFilename(distribution);
|
||||||
const baseUrl = `https://github.com/goreleaser/${distribution}/releases/download/${release.tag_name}`;
|
const baseUrl = `https://github.com/goreleaser/${distribution}/releases/download/${tag}`;
|
||||||
const downloadUrl = `${baseUrl}/${filename}`;
|
const downloadUrl = `${baseUrl}/${filename}`;
|
||||||
|
|
||||||
core.info(`Downloading ${downloadUrl}`);
|
core.info(`Downloading ${downloadUrl}`);
|
||||||
const downloadPath: string = await tc.downloadTool(downloadUrl);
|
const downloadPath: string = await tc.downloadTool(downloadUrl);
|
||||||
core.debug(`Downloaded to ${downloadPath}`);
|
core.debug(`Downloaded to ${downloadPath}`);
|
||||||
|
|
||||||
await verifyChecksum(distribution, release.tag_name, downloadPath, filename);
|
const verified = await verifyChecksum(distribution, tag, downloadPath, filename, cosign);
|
||||||
|
|
||||||
core.info('Extracting GoReleaser');
|
core.info('Extracting GoReleaser');
|
||||||
let extPath: string;
|
let extPath: string;
|
||||||
if (context.osPlat == 'win32') {
|
if (context.osPlat == 'win32') {
|
||||||
if (!downloadPath.endsWith('.zip')) {
|
let zipPath = downloadPath;
|
||||||
const newPath = downloadPath + '.zip';
|
if (!zipPath.endsWith('.zip')) {
|
||||||
fs.renameSync(downloadPath, newPath);
|
zipPath = `${downloadPath}.zip`;
|
||||||
extPath = await tc.extractZip(newPath);
|
fs.renameSync(downloadPath, zipPath);
|
||||||
} else {
|
|
||||||
extPath = await tc.extractZip(downloadPath);
|
|
||||||
}
|
}
|
||||||
|
extPath = await tc.extractZip(zipPath);
|
||||||
} else {
|
} else {
|
||||||
extPath = await tc.extractTar(downloadPath);
|
extPath = await tc.extractTar(downloadPath);
|
||||||
}
|
}
|
||||||
core.debug(`Extracted to ${extPath}`);
|
core.debug(`Extracted to ${extPath}`);
|
||||||
|
|
||||||
const cachePath: string = await tc.cacheDir(extPath, 'goreleaser-action', release.tag_name.replace(/^v/, ''));
|
if (!verified) {
|
||||||
|
return getExePath(extPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
const cachePath: string = await tc.cacheDir(extPath, cacheToolName(distribution, verified), toolVersion);
|
||||||
core.debug(`Cached to ${cachePath}`);
|
core.debug(`Cached to ${cachePath}`);
|
||||||
|
|
||||||
const exePath: string = path.join(cachePath, context.osPlat == 'win32' ? 'goreleaser.exe' : 'goreleaser');
|
return getExePath(cachePath);
|
||||||
core.debug(`Exe path is ${exePath}`);
|
|
||||||
|
|
||||||
return exePath;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const findCachedTool = (distribution: string, version: string, required: VerificationLevel): string => {
|
||||||
|
const levels: VerificationLevel[] = required === 'cosign' ? ['cosign'] : ['cosign', 'checksum'];
|
||||||
|
for (const level of levels) {
|
||||||
|
const toolPath = tc.find(cacheToolName(distribution, level), version);
|
||||||
|
if (toolPath) {
|
||||||
|
return toolPath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
};
|
||||||
|
|
||||||
|
const cacheToolName = (distribution: string, verification: VerificationLevel): string => {
|
||||||
|
return `${distribution}-${verification}`;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getExePath = (dir: string): string => {
|
||||||
|
return path.join(dir, context.osPlat == 'win32' ? 'goreleaser.exe' : 'goreleaser');
|
||||||
|
};
|
||||||
|
|
||||||
export async function verifyChecksum(
|
export async function verifyChecksum(
|
||||||
distribution: string,
|
distribution: string,
|
||||||
tag: string,
|
tag: string,
|
||||||
archivePath: string,
|
archivePath: string,
|
||||||
filename: string
|
filename: string,
|
||||||
): Promise<void> {
|
cosign?: string
|
||||||
|
): Promise<VerificationLevel | undefined> {
|
||||||
const baseUrl = `https://github.com/goreleaser/${distribution}/releases/download/${tag}`;
|
const baseUrl = `https://github.com/goreleaser/${distribution}/releases/download/${tag}`;
|
||||||
let checksumsPath: string;
|
let checksumsPath: string;
|
||||||
try {
|
try {
|
||||||
@@ -71,7 +105,19 @@ export async function verifyChecksum(
|
|||||||
}
|
}
|
||||||
core.info(`Checksum verified for ${filename}`);
|
core.info(`Checksum verified for ${filename}`);
|
||||||
|
|
||||||
await verifyCosignSignature(distribution, tag, baseUrl, checksumsPath);
|
const cosignPath = cosign === undefined ? await io.which('cosign', false) : cosign;
|
||||||
|
if (!cosignPath) {
|
||||||
|
core.info('cosign not found in PATH, skipping signature verification');
|
||||||
|
return 'checksum';
|
||||||
|
}
|
||||||
|
if (!supportsCosignBundle(tag)) {
|
||||||
|
core.info(`GoReleaser ${tag} does not have a sigstore bundle, skipping signature verification`);
|
||||||
|
return 'checksum';
|
||||||
|
}
|
||||||
|
if (!(await verifyCosignSignature(distribution, tag, baseUrl, checksumsPath, cosignPath))) {
|
||||||
|
return 'checksum';
|
||||||
|
}
|
||||||
|
return 'cosign';
|
||||||
}
|
}
|
||||||
|
|
||||||
export const findChecksum = (checksumsContent: string, filename: string): string | undefined => {
|
export const findChecksum = (checksumsContent: string, filename: string): string | undefined => {
|
||||||
@@ -86,21 +132,16 @@ async function verifyCosignSignature(
|
|||||||
distribution: string,
|
distribution: string,
|
||||||
tag: string,
|
tag: string,
|
||||||
baseUrl: string,
|
baseUrl: string,
|
||||||
checksumsPath: string
|
checksumsPath: string,
|
||||||
): Promise<void> {
|
cosign: string
|
||||||
const cosign = await io.which('cosign', false);
|
): Promise<boolean> {
|
||||||
if (!cosign) {
|
|
||||||
core.info('cosign not found in PATH, skipping signature verification');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let bundlePath: string;
|
let bundlePath: string;
|
||||||
try {
|
try {
|
||||||
core.info(`Downloading ${baseUrl}/checksums.txt.sigstore.json`);
|
core.info(`Downloading ${baseUrl}/checksums.txt.sigstore.json`);
|
||||||
bundlePath = await tc.downloadTool(`${baseUrl}/checksums.txt.sigstore.json`);
|
bundlePath = await tc.downloadTool(`${baseUrl}/checksums.txt.sigstore.json`);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
core.warning(`Skipping cosign signature verification: unable to download sigstore bundle: ${e.message}`);
|
core.warning(`Skipping cosign signature verification: unable to download sigstore bundle: ${e.message}`);
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const certificateIdentity = getCertificateIdentity(distribution, tag);
|
const certificateIdentity = getCertificateIdentity(distribution, tag);
|
||||||
@@ -116,8 +157,17 @@ async function verifyCosignSignature(
|
|||||||
checksumsPath
|
checksumsPath
|
||||||
]);
|
]);
|
||||||
core.info('cosign signature verified');
|
core.info('cosign signature verified');
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const supportsCosignBundle = (tag: string): boolean => {
|
||||||
|
if (github.isNightlyTag(tag)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
const version = semver.parse(tag.replace(/^v/, '').replace(/-pro$/, ''));
|
||||||
|
return version !== null && semver.gte(version, '2.13.0');
|
||||||
|
};
|
||||||
|
|
||||||
export const getCertificateIdentity = (distribution: string, tag: string): string => {
|
export const getCertificateIdentity = (distribution: string, tag: string): string => {
|
||||||
const pro = isPro(distribution);
|
const pro = isPro(distribution);
|
||||||
if (github.isNightlyTag(tag)) {
|
if (github.isNightlyTag(tag)) {
|
||||||
@@ -171,7 +221,7 @@ const getFilename = (distribution: string): string => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export async function getDistPath(yamlfile: string): Promise<string> {
|
export async function getDistPath(yamlfile: string): Promise<string> {
|
||||||
const cfg = yaml.load(fs.readFileSync(yamlfile, 'utf8'));
|
const cfg = yaml.load(fs.readFileSync(yamlfile, 'utf8')) as {dist?: string};
|
||||||
return cfg.dist || 'dist';
|
return cfg.dist || 'dist';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user