Implement -O and -G tests #1181
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
on: [push, pull_request] | |
name: Test | |
jobs: | |
test: | |
strategy: | |
matrix: | |
go-version: [1.21.x, 1.22.x] | |
os: [ubuntu-latest, macos-latest, windows-latest] | |
runs-on: ${{ matrix.os }} | |
steps: | |
- uses: actions/checkout@v4 | |
- uses: actions/setup-go@v5 | |
with: | |
go-version: ${{ matrix.go-version }} | |
cache: false | |
- run: go test ./... | |
- run: go test -race ./... | |
if: matrix.os == 'ubuntu-latest' | |
- run: GOARCH=386 go test -count=1 ./... | |
if: matrix.os == 'ubuntu-latest' | |
- name: confirm tests with Bash 5.2 | |
run: | | |
go install mvdan.cc/dockexec@latest | |
CGO_ENABLED=0 go test -run TestRunnerRunConfirm -exec 'dockexec bash:5.2' ./interp | |
if: matrix.os == 'ubuntu-latest' | |
# Static checks from this point forward. Only run on one Go version and on | |
# Linux, since it's the fastest platform, and the tools behave the same. | |
- if: matrix.os == 'ubuntu-latest' && matrix.go-version == '1.22.x' | |
run: diff <(echo -n) <(gofmt -s -d .) | |
- if: matrix.os == 'ubuntu-latest' && matrix.go-version == '1.22.x' | |
run: go vet ./... | |
test-linux-alpine: | |
runs-on: ubuntu-latest | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Test as root, without cgo, and with busybox | |
run: docker run -v="$PWD:/pwd" -w=/pwd -e=CGO_ENABLED=0 golang:1.22.0-alpine go test ./... | |
docker: | |
name: Build and test Docker images | |
# Only deploy if previous stages pass. | |
needs: [test, test-linux-alpine] | |
runs-on: ubuntu-latest | |
services: | |
registry: | |
image: registry:2 | |
ports: | |
- 5000:5000 | |
# this is needed because we restart the docker daemon for experimental | |
# support | |
options: "--restart always" | |
env: | |
# Export environment variables for all stages. | |
DOCKER_USER: ${{ secrets.DOCKER_USER }} | |
DOCKER_DEPLOY_IMAGES: false | |
DOCKER_TOKEN: ${{ secrets.DOCKER_TOKEN }} | |
DOCKER_REPO: shfmt | |
# We use all platforms for which FROM images in our Dockerfile are | |
# available. | |
DOCKER_PLATFORMS: > | |
linux/386 | |
linux/amd64 | |
linux/arm/v7 | |
linux/arm64/v8 | |
linux/ppc64le | |
# linux/s390x TODO: reenable when we figure out its weird errors when | |
# fetching dependencies, including: | |
# | |
# zip: checksum error | |
# Get "https://proxy.golang.org/...": local error: tls: bad record MAC | |
# Get "https://proxy.golang.org/...": local error: tls: unexpected message | |
# Get "https://proxy.golang.org/...": x509: certificate signed by unknown authority | |
steps: | |
- uses: actions/checkout@v4 | |
with: | |
fetch-depth: 0 # also fetch tags for 'git describe' | |
# Enable docker daemon experimental support (for 'pull --platform'). | |
- name: Enable experimental support | |
run: | | |
config='/etc/docker/daemon.json' | |
if [[ -e "$config" ]]; then | |
sudo sed -i -e 's/{/{ "experimental": true, /' "$config" | |
else | |
echo '{ "experimental": true }' | sudo tee "$config" | |
fi | |
sudo systemctl restart docker | |
- uses: docker/setup-qemu-action@v3 | |
- uses: docker/setup-buildx-action@v3 | |
with: | |
driver-opts: network=host | |
- name: Set up env vars | |
run: | | |
set -vx | |
# Export environment variable for later stages. | |
if echo "$GITHUB_REF" | grep -q '^refs/heads/master$'; then | |
# Pushes to the master branch deploy 'latest'. | |
echo "TAG=latest" >> $GITHUB_ENV | |
elif echo "$GITHUB_REF" | grep -q '^refs/heads/docker-push-test$'; then | |
# Pushes to the test branch deploy 'latest-test'. | |
echo "TAG=latest-test" >> $GITHUB_ENV | |
elif echo "$GITHUB_REF" | grep -q '^refs/tags/'; then | |
# Pushes to a git tag use it as the docker tag. | |
echo "TAG=${GITHUB_REF/refs\/tags\//}" >> $GITHUB_ENV | |
else | |
# Otherwise, we build and test the image locally, but we don't push it. | |
echo "TAG=${GITHUB_SHA::8}" >> $GITHUB_ENV | |
fi | |
echo "DOCKER_BASE=test/${{ env.DOCKER_REPO }}" >> $GITHUB_ENV | |
echo "DOCKER_BUILD_PLATFORMS=${DOCKER_PLATFORMS// /,}" >> $GITHUB_ENV | |
- name: Build and push to local registry | |
uses: docker/build-push-action@v5 | |
with: | |
provenance: false # temporarily work around https://github.com/containers/skopeo/issues/1874 | |
context: . | |
file: ./cmd/shfmt/Dockerfile | |
platforms: ${{ env.DOCKER_BUILD_PLATFORMS }} | |
push: true | |
tags: localhost:5000/${{ env.DOCKER_BASE }}:${{ env.TAG }} | |
- name: Build and push to local registry (alpine) | |
uses: docker/build-push-action@v5 | |
with: | |
provenance: false # temporarily work around https://github.com/containers/skopeo/issues/1874 | |
context: . | |
file: ./cmd/shfmt/Dockerfile | |
platforms: ${{ env.DOCKER_BUILD_PLATFORMS }} | |
push: true | |
tags: localhost:5000/${{ env.DOCKER_BASE }}:${{ env.TAG }}-alpine | |
target: alpine | |
- name: Test multi-arch Docker images locally | |
run: | | |
for platform in $DOCKER_PLATFORMS; do | |
for ext in '' '-alpine'; do | |
image="localhost:5000/${DOCKER_BASE}:${TAG}${ext}" | |
msg="Testing docker image $image on platform $platform" | |
line="${msg//?/=}" | |
printf "\n${line}\n${msg}\n${line}\n" | |
docker pull -q --platform "$platform" "$image" | |
if [[ -n "$ext" ]]; then | |
echo -n "Image architecture: " | |
docker run --rm --entrypoint /bin/sh "$image" -c 'uname -m' | |
fi | |
version=$(docker run --rm "$image" --version) | |
echo "shfmt version: $version" | |
if [[ $TAG != "latest" ]] && | |
[[ $TAG != "latest-test" ]] && | |
[[ $TAG != "$version" ]] && | |
! echo "$version" | grep -q "$TAG"; then | |
echo "Version mismatch: shfmt $version tagged as $TAG" | |
exit 1 | |
fi | |
docker run --rm -v "$PWD:/mnt" -w '/mnt' "$image" -d cmd/shfmt/docker-entrypoint.sh | |
done | |
done | |
- name: Check GitHub settings | |
if: > | |
github.event_name == 'push' && | |
github.repository == 'mvdan/sh' && | |
(github.ref == 'refs/heads/master' || | |
github.ref == 'refs/heads/docker-push-test' || | |
startsWith(github.ref, 'refs/tags/')) | |
run: | | |
missing=() | |
[[ -n "${{ secrets.DOCKER_USER }}" ]] || missing+=(DOCKER_USER) | |
[[ -n "${{ secrets.DOCKER_TOKEN }}" ]] || missing+=(DOCKER_TOKEN) | |
for i in "${missing[@]}"; do | |
echo "Missing github secret: $i" | |
done | |
(( ${#missing[@]} == 0 )) || exit 1 | |
echo "DOCKER_DEPLOY_IMAGES=true" >> $GITHUB_ENV | |
- name: Login to DockerHub | |
if: ${{ env.DOCKER_DEPLOY_IMAGES == 'true' }} | |
uses: docker/login-action@v3 | |
with: | |
username: ${{ secrets.DOCKER_USER }} | |
password: ${{ secrets.DOCKER_TOKEN }} | |
- name: Push images to DockerHub | |
if: ${{ env.DOCKER_DEPLOY_IMAGES == 'true' }} | |
run: | | |
for ext in '' '-alpine'; do | |
image_src="${DOCKER_BASE}:${TAG}${ext}" | |
image_dsts=("${{ secrets.DOCKER_USER }}/${{ env.DOCKER_REPO }}:${TAG}${ext}") | |
if echo $TAG | grep -q '^v3\.[0-9]\+\.[0-9]\+$'; then | |
image_dsts+=("${{ secrets.DOCKER_USER }}/${{ env.DOCKER_REPO }}:v3${ext}") | |
elif [[ $TAG == latest-test ]]; then | |
image_dsts+=("${{ secrets.DOCKER_USER }}/${{ env.DOCKER_REPO }}:v3-test${ext}") | |
fi | |
# Show what we're doing. | |
msg="Copy multi-arch docker images to DockerHub ($image_src with ${#image_dsts[@]} destinations)" | |
line="${msg//?/=}" | |
printf "\n${line}\n${msg}\n${line}\n" | |
for image_dst in "${image_dsts[@]}"; do | |
skopeo copy --all --src-tls-verify=0 docker://localhost:5000/$image_src docker://docker.io/$image_dst | |
done | |
done | |
- name: Update DockerHub description | |
if: ${{ env.DOCKER_DEPLOY_IMAGES == 'true' }} | |
uses: peter-evans/dockerhub-description@v4 | |
with: | |
username: ${{ secrets.DOCKER_USER }} | |
password: ${{ secrets.DOCKER_TOKEN }} | |
repository: ${{ secrets.DOCKER_USER }}/${{ env.DOCKER_REPO }} | |
readme-filepath: README.md |