Skip to content

Split npm release authentication #130

Split npm release authentication

Split npm release authentication #130

Workflow file for this run

name: CI
on:
push:
branches:
- "**"
tags-ignore:
- "v*"
pull_request:
permissions:
contents: read
jobs:
test-and-build:
name: Test and build (${{ matrix.os }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
- ubuntu-latest
- macos-latest
- windows-latest
steps:
- name: Check out repository
uses: actions/checkout@v6
- name: Set up Go
uses: actions/setup-go@v6
with:
go-version-file: go.mod
cache: true
- name: Run tests
# -count=1 disables Go's test result cache so flaky CI nodes never
# surface a stale "PASS" from an earlier run on the same content.
run: go test -count=1 ./...
- name: Check Go formatting
if: runner.os != 'Windows'
shell: bash
run: |
files="$(gofmt -l .)"
if [ -n "$files" ]; then
echo "$files"
exit 1
fi
- name: Audit error code coverage
if: runner.os != 'Windows'
shell: bash
run: ./scripts/check-error-codes.sh
- name: Check docs/commands.md is up to date
if: runner.os == 'Linux'
shell: bash
run: |
# Generated reference must track the cobra tree. If this fails,
# run `make docs-commands` locally and commit the result.
go run ./cmd/gendocs -check
# Prebuilt golangci-lint binaries may be compiled with an older Go than
# go.mod; loading .golangci.yml then fails ("Go language version used to
# build golangci-lint is lower than the targeted Go version"). Building
# from source with setup-go matches the project's toolchain.
- name: golangci-lint
if: runner.os == 'Linux'
uses: golangci/golangci-lint-action@v6
with:
version: v1.64.8
install-mode: goinstall
args: --timeout=5m
- name: Build CLI
shell: bash
run: |
mkdir -p dist
ext=""
if [ "${{ runner.os }}" = "Windows" ]; then
ext=".exe"
fi
go build -trimpath -o "dist/agora${ext}" .
- name: Check Unix installer syntax
if: runner.os != 'Windows'
shell: bash
run: sh -n install.sh
- name: Smoke test installer messages
if: runner.os != 'Windows'
shell: bash
run: sh scripts/test-installer-messages.sh
- name: Check PowerShell installer syntax
if: runner.os == 'Windows'
shell: pwsh
run: |
$tokens = $null
$errors = $null
[void][System.Management.Automation.Language.Parser]::ParseFile(
(Join-Path $PWD 'install.ps1'),
[ref]$tokens,
[ref]$errors
)
if ($errors.Count -gt 0) {
$errors | ForEach-Object { Write-Error $_.Message }
exit 1
}
- name: Smoke test POSIX installer on Windows
if: runner.os == 'Windows'
shell: bash
run: |
set -euo pipefail
VERSION="0.0.0-ci" \
INSTALL_DIR="$PWD/.tmp/install-bin-sh" \
sh ./install.sh --dry-run --force
- name: Smoke test Unix installer
if: runner.os != 'Windows'
shell: bash
run: |
set -euo pipefail
version="0.0.0-ci"
goos="$(uname -s | tr '[:upper:]' '[:lower:]')"
case "$(uname -m)" in
x86_64|amd64) goarch="amd64" ;;
aarch64|arm64) goarch="arm64" ;;
*) echo "Unsupported CI arch: $(uname -m)" >&2; exit 1 ;;
esac
fixture_root="$PWD/.tmp/install-fixture"
download_dir="$fixture_root/download/v${version}"
install_dir="$PWD/.tmp/install-bin"
bad_install_dir="$PWD/.tmp/install-bin-bad"
archive="agora-cli_v${version}_${goos}_${goarch}.tar.gz"
rm -rf "$fixture_root" "$install_dir" "$bad_install_dir"
mkdir -p "$download_dir"
tar -C dist -czf "$download_dir/$archive" agora
if command -v sha256sum >/dev/null 2>&1; then
(cd "$download_dir" && sha256sum "$archive" > checksums.txt)
else
(cd "$download_dir" && shasum -a 256 "$archive" > checksums.txt)
fi
python3 -m http.server 18080 --directory "$fixture_root" >/tmp/agora-install-server.log 2>&1 &
server_pid=$!
trap 'kill "$server_pid"' EXIT
sleep 2
# The installer enforces --proto =https in production. The smoke test
# serves the fixture from a local HTTP server, so we relax the proto
# restriction (test only).
export INSTALLER_CURL_PROTO_OPTS="--proto =http,https"
VERSION="$version" \
RELEASES_DOWNLOAD_BASE_URL="http://127.0.0.1:18080/download" \
RELEASES_PAGE_URL="http://127.0.0.1:18080" \
INSTALL_DIR="$install_dir" \
sh ./install.sh --force
"$install_dir/agora" --help >/dev/null
printf '%064d %s\n' 0 "$archive" > "$download_dir/checksums.txt"
if VERSION="$version" \
RELEASES_DOWNLOAD_BASE_URL="http://127.0.0.1:18080/download" \
RELEASES_PAGE_URL="http://127.0.0.1:18080" \
INSTALL_DIR="$bad_install_dir" \
sh ./install.sh --force; then
echo "Expected checksum verification to fail" >&2
exit 1
fi
- name: Smoke test PowerShell installer
if: runner.os == 'Windows'
shell: pwsh
run: |
$version = '0.0.0-ci'
$arch = switch ([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture.ToString().ToLowerInvariant()) {
'x64' { 'amd64' }
'arm64' { 'arm64' }
default { throw "Unsupported CI arch: $([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture)" }
}
$fixtureRoot = Join-Path $PWD '.tmp/install-fixture'
$downloadDir = Join-Path $fixtureRoot "download/v$version"
$installDir = Join-Path $PWD '.tmp/install-bin'
$badInstallDir = Join-Path $PWD '.tmp/install-bin-bad'
$archive = "agora-cli_v$version" + "_windows_${arch}.zip"
Remove-Item -Recurse -Force $fixtureRoot, $installDir, $badInstallDir -ErrorAction SilentlyContinue
New-Item -ItemType Directory -Force -Path $downloadDir | Out-Null
Compress-Archive -Path (Join-Path $PWD 'dist/agora.exe') -DestinationPath (Join-Path $downloadDir $archive) -Force
$hash = (Get-FileHash -Path (Join-Path $downloadDir $archive) -Algorithm SHA256).Hash.ToLowerInvariant()
Set-Content -Path (Join-Path $downloadDir 'checksums.txt') -Value "$hash $archive"
$serverOutLog = Join-Path $fixtureRoot 'http-server.out.log'
$serverErrLog = Join-Path $fixtureRoot 'http-server.err.log'
$server = Start-Process -FilePath python -ArgumentList '-m', 'http.server', '18081', '--directory', $fixtureRoot -RedirectStandardOutput $serverOutLog -RedirectStandardError $serverErrLog -PassThru
$archiveUrl = "http://127.0.0.1:18081/download/v$version/$archive"
$serverReady = $false
for ($attempt = 1; $attempt -le 20; $attempt++) {
if ($server.HasExited) {
if (Test-Path -LiteralPath $serverOutLog) { Get-Content -Path $serverOutLog | ForEach-Object { Write-Host $_ } }
if (Test-Path -LiteralPath $serverErrLog) { Get-Content -Path $serverErrLog | ForEach-Object { Write-Host $_ } }
throw "Fixture HTTP server exited before serving $archiveUrl."
}
try {
$response = Invoke-WebRequest -Uri $archiveUrl -Method Head -UseBasicParsing
if ($response.StatusCode -eq 200) {
$serverReady = $true
break
}
} catch {
Start-Sleep -Milliseconds 500
}
}
if (-not $serverReady) {
if (Test-Path -LiteralPath $serverOutLog) { Get-Content -Path $serverOutLog | ForEach-Object { Write-Host $_ } }
if (Test-Path -LiteralPath $serverErrLog) { Get-Content -Path $serverErrLog | ForEach-Object { Write-Host $_ } }
throw "Fixture HTTP server did not serve $archiveUrl."
}
try {
$env:VERSION = $version
$env:RELEASES_DOWNLOAD_BASE_URL = 'http://127.0.0.1:18081/download'
$env:RELEASES_PAGE_URL = 'http://127.0.0.1:18081'
& ./install.ps1 -InstallDir $installDir
if ($LASTEXITCODE -ne 0) {
throw "install.ps1 failed with exit code $LASTEXITCODE."
}
& (Join-Path $installDir 'agora.exe') --help *> $null
Set-Content -Path (Join-Path $downloadDir 'checksums.txt') -Value ('0' * 64 + " $archive")
$previousNativePreference = $PSNativeCommandUseErrorActionPreference
$PSNativeCommandUseErrorActionPreference = $false
pwsh -NoProfile -ExecutionPolicy Bypass -File ./install.ps1 -InstallDir $badInstallDir
$badExitCode = $LASTEXITCODE
$PSNativeCommandUseErrorActionPreference = $previousNativePreference
if ($badExitCode -eq 0) {
throw 'Expected checksum verification to fail with a non-zero exit code.'
}
# The expected non-zero $LASTEXITCODE from install.ps1 is good news
# for this assertion, but GitHub Actions' pwsh wrapper appends
# `if (Test-Path variable:\LASTEXITCODE) { exit $LASTEXITCODE }`,
# which would otherwise propagate that non-zero exit and fail the
# whole step. Clear it now that we have what we need.
$global:LASTEXITCODE = 0
} finally {
Stop-Process -Id $server.Id -Force -ErrorAction SilentlyContinue
Remove-Item Env:VERSION, Env:RELEASES_DOWNLOAD_BASE_URL, Env:RELEASES_PAGE_URL -ErrorAction SilentlyContinue
}