Skip to content

feat(snapshot): add workspace snapshots #2807

feat(snapshot): add workspace snapshots

feat(snapshot): add workspace snapshots #2807

Workflow file for this run

name: Pull Request
on:
push:
branches: [main]
workflow_dispatch:
pull_request:
# Cancel in-flight runs for the same PR when a new commit is pushed.
# Non-PR events (main pushes, workflow_dispatch) get a unique group per
# run so they bypass concurrency entirely and run independently.
concurrency:
group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.head_ref || github.run_id }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
changes:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: read
outputs:
go: ${{ steps.filter.outputs.go }}
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
- uses: dorny/paths-filter@7b450fff21473bca461d4b92ce414b9d0420d706 # v4
id: filter
with:
filters: |
go:
- '**/*.go'
- 'go.mod'
- 'go.sum'
- '.goreleaser.yml'
- 'e2e/**'
- '.github/workflows/pr-ci.yml'
- 'hack/licenses/**'
- 'THIRD_PARTY_LICENSES.md'
precommit:
name: Pre-commit
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
- uses: j178/prek-action@4e14d07f9231acabce116ccfca13b13dd9755ece # v3.0.0
lint:
name: Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
- name: setup Go
uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7
with:
go-version-file: go.mod
- name: golangci-lint
uses: golangci/golangci-lint-action@ba0d7d2ec06a0ea1cb5fa41b2e4a3ab91d21278a # v9
with:
version: v2.12.2
only-new-issues: true
can-read-secret:
name: Can Read Secret
runs-on: ubuntu-latest
outputs:
secret-set: ${{ steps.check-secret.outputs.secret-set }}
steps:
- name: Check secret
id: check-secret
run: |
if [ -z "${{ secrets.DEVSY_GITHUB_APP_ID }}" ]; then
echo "secret-set=false" >> "$GITHUB_OUTPUT"
else
echo "secret-set=true" >> "$GITHUB_OUTPUT"
fi
build-cli:
name: Build CLI Binary on ${{ matrix.runner }}
needs: [changes, precommit, lint]
if: needs.changes.outputs.go == 'true'
strategy:
matrix:
include:
- runner: ubuntu-latest
- runner: macos-latest
- runner: windows-latest
runs-on: ${{ matrix.runner }}
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
- uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7
with:
go-version-file: go.mod
- name: get operating system lowercase
id: os
shell: bash
run: |
OS=$(echo "${{ runner.os }}" | tr '[:upper:]' '[:lower:]')
if [ "$OS" == "macos" ]; then
OS="darwin"
fi
echo "runner_os=$OS" >> "$GITHUB_OUTPUT"
- uses: goreleaser/goreleaser-action@f06c13b6b1a9625abc9e6e439d9c05a8f2190e94 # v7
with:
distribution: goreleaser
version: "~> v2"
args: build --id devsy-${{ steps.os.outputs.runner_os }} --snapshot
env:
DEVSY_CLI_VERSION: v0.0.0
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: devsy-${{ steps.os.outputs.runner_os }}
path: dist/devsy-${{ steps.os.outputs.runner_os }}_*/devsy-${{ steps.os.outputs.runner_os }}-*
- name: build e2e test binary
if: matrix.runner == 'ubuntu-latest' || matrix.runner == 'windows-latest'
shell: bash
working-directory: ./e2e
env:
CGO_ENABLED: 0
run: |
OUT="e2e.test"
if [ "${{ runner.os }}" == "Windows" ]; then
OUT="e2e.test.exe"
fi
go test -c -o "$OUT" ./
- name: upload e2e test binary
if: matrix.runner == 'ubuntu-latest' || matrix.runner == 'windows-latest'
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: e2e-test-${{ steps.os.outputs.runner_os }}
path: ./e2e/e2e.test*
licenses:
name: Third-party licenses
needs: [changes, precommit, lint]
if: needs.changes.outputs.go == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
- uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7
with:
go-version-file: go.mod
- name: Check license policy and attribution
run: go run ./hack/licenses --check
integration-tests-unprivileged:
name: Test ${{ matrix.label }} on ${{ matrix.runner }}
needs: [changes, build-cli]
if: needs.changes.outputs.go == 'true'
strategy:
fail-fast: false
matrix:
include:
- label: context
runner: ubuntu-latest
- label: extends
runner: ubuntu-latest
- label: outdated
runner: ubuntu-latest
- label: machine
runner: ubuntu-latest
- label: self-update
runner: ubuntu-latest
- label: upgrade
runner: ubuntu-latest
runs-on: ${{ matrix.runner }}
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
- name: get operating system lowercase
id: os
shell: bash
run: |
OS=$(echo "${{ runner.os }}" | tr '[:upper:]' '[:lower:]')
echo "runner_os=$OS" >> "$GITHUB_OUTPUT"
- name: download CLI artifacts
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
with:
pattern: devsy-${{ steps.os.outputs.runner_os }}
path: ${{ runner.temp }}/devsy-bin/
merge-multiple: true
- name: download e2e test binary
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
with:
name: e2e-test-${{ steps.os.outputs.runner_os }}
path: ./e2e/
- name: setup executable
shell: bash
working-directory: ./e2e
run: |
TEMP_DIR="${{ runner.temp }}"
ls -R "$TEMP_DIR/devsy-bin/"
mkdir -p ./bin/
find "$TEMP_DIR/devsy-bin/" -type f -name "devsy-*" -exec cp {} ./bin \;
find ./bin -name "devsy-*" -exec chmod +x {} \;
chmod +x ./e2e.test
ls -R ./bin/
- name: run test
shell: bash
working-directory: ./e2e
env:
GH_USERNAME: ${{ github.repository_owner }}
GH_ACCESS_TOKEN: ${{ github.token }}
GH_CREDENTIAL_USERNAME: x-access-token
run: |
./e2e.test -test.v -ginkgo.v -test.timeout 1500s --ginkgo.label-filter="${{ matrix.label }}"
integration-tests:
name: Test ${{ matrix.label }}${{ matrix.install-podman && format(' ({0})', matrix.install-podman) || '' }} on ${{ matrix.runner }}
needs: [changes, can-read-secret, build-cli]
if: needs.changes.outputs.go == 'true'
strategy:
fail-fast: false
matrix:
include:
- label: ide
runner: ubuntu-latest
free-disk-space: false
install-kind: false
requires-secret: false
- label: machine-provider
runner: ubuntu-latest
free-disk-space: false
install-kind: false
requires-secret: false
- label: integration
runner: ubuntu-latest
free-disk-space: false
install-kind: false
requires-secret: false
- label: tunnel
runner: ubuntu-latest
free-disk-space: false
install-kind: false
requires-secret: false
- label: provider
runner: ubuntu-latest
free-disk-space: true
install-kind: true
requires-secret: false
- label: ssh
runner: ubuntu-latest
free-disk-space: false
install-kind: false
requires-secret: false
- label: build
runner: ubuntu-latest
free-disk-space: true
install-kind: true
requires-secret: true
- label: docker-install
runner: ubuntu-latest
free-disk-space: false
install-kind: false
requires-secret: false
- label: exec
runner: ubuntu-latest
free-disk-space: false
install-kind: false
requires-secret: false
- label: ci
runner: ubuntu-latest
free-disk-space: false
install-kind: false
requires-secret: false
- label: features
runner: ubuntu-latest
free-disk-space: false
install-kind: false
requires-secret: false
- label: extends-up
runner: ubuntu-latest
free-disk-space: false
install-kind: false
requires-secret: false
- label: down
runner: ubuntu-latest
free-disk-space: false
install-kind: false
requires-secret: false
- label: rename
runner: ubuntu-latest
free-disk-space: false
install-kind: false
requires-secret: false
- label: delivery
runner: ubuntu-latest
free-disk-space: false
install-kind: false
requires-secret: false
- label: logs
runner: ubuntu-latest
free-disk-space: false
install-kind: false
requires-secret: false
- label: templates
runner: ubuntu-latest
free-disk-space: false
install-kind: false
requires-secret: false
- label: setup
runner: ubuntu-latest
free-disk-space: false
install-kind: false
requires-secret: false
- label: run-user-commands
runner: ubuntu-latest
free-disk-space: false
install-kind: false
requires-secret: false
- label: config-read
runner: ubuntu-latest
free-disk-space: false
install-kind: false
requires-secret: false
# Up tests
- label: up-workspaces
runner: ubuntu-latest
free-disk-space: true
install-kind: true
requires-secret: false
- label: up-behaviors
runner: ubuntu-latest
free-disk-space: false
install-kind: false
requires-secret: false
- label: up-handle-errors
runner: ubuntu-latest
free-disk-space: true
install-kind: true
requires-secret: false
- label: up-private-token
runner: ubuntu-latest
free-disk-space: false
install-kind: false
requires-secret: true
- label: up-provider-kubernetes
runner: ubuntu-latest
free-disk-space: true
install-kind: true
requires-secret: false
- label: up-provider-podman
runner: ubuntu-latest
free-disk-space: true
install-kind: false
requires-secret: false
install-podman: rootless
- label: up-provider-podman
runner: ubuntu-latest
free-disk-space: true
install-kind: false
requires-secret: false
install-podman: rootful
- label: up-provider-docker
runner: ubuntu-latest
free-disk-space: false
install-kind: true
requires-secret: false
- label: up-provider-microsandbox
runner: ubuntu-latest
free-disk-space: true
install-kind: false
requires-secret: false
install-microsandbox: true
# Snapshot tests
- label: snapshot
runner: ubuntu-latest
free-disk-space: false
install-kind: false
requires-secret: false
configure-insecure-registry: true
# Up Docker Compose tests
- label: up-docker-compose
runner: ubuntu-latest
free-disk-space: false
install-kind: false
requires-secret: false
# Up Docker Feature tests
- label: up-features
runner: ubuntu-latest
free-disk-space: true
install-kind: true
requires-secret: false
# Windows tests
- label: provider
runner: windows-latest
free-disk-space: false
install-kind: true
requires-secret: false
- label: up-docker-wsl
runner: windows-latest
free-disk-space: false
install-kind: true
requires-secret: false
- label: up-features
runner: windows-latest
free-disk-space: false
install-kind: true
requires-secret: false
runs-on: ${{ matrix.runner }}
steps:
- uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be # v1.3.1
if: matrix.free-disk-space == true && runner.os == 'Linux' && (matrix.requires-secret == false || needs.can-read-secret.outputs.secret-set == 'true')
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
if: matrix.requires-secret == false || needs.can-read-secret.outputs.secret-set == 'true'
- name: install gnupg2
if: runner.os == 'Linux' && (matrix.requires-secret == false || needs.can-read-secret.outputs.secret-set == 'true')
run: sudo apt-get install -y gnupg2
- name: get operating system lowercase
if: matrix.requires-secret == false || needs.can-read-secret.outputs.secret-set == 'true'
id: os
shell: bash
run: |
OS=$(echo "${{ runner.os }}" | tr '[:upper:]' '[:lower:]')
if [ "$OS" == "macos" ]; then
OS="darwin"
fi
echo "runner_os=$OS" >> "$GITHUB_OUTPUT"
- name: download CLI artifacts
if: matrix.requires-secret == false || needs.can-read-secret.outputs.secret-set == 'true'
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
with:
pattern: devsy-${{ steps.os.outputs.runner_os }}
path: ${{ runner.temp }}/devsy-bin/
merge-multiple: true
- name: download Linux CLI artifacts for Windows
if: runner.os == 'Windows' && (matrix.requires-secret == false || needs.can-read-secret.outputs.secret-set == 'true')
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
with:
pattern: devsy-linux
path: ${{ runner.temp }}/devsy-bin/
merge-multiple: true
- name: download e2e test binary
if: matrix.requires-secret == false || needs.can-read-secret.outputs.secret-set == 'true'
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
with:
name: e2e-test-${{ steps.os.outputs.runner_os }}
path: ./e2e/
# e2e expects executable to have name defined in e2e/framework/framework.go
- name: setup executable
if: matrix.requires-secret == false || needs.can-read-secret.outputs.secret-set == 'true'
shell: bash
working-directory: ./e2e
run: |
TEMP_DIR="${{ runner.temp }}"
if [ "${{ runner.os }}" == "Windows" ]; then
TEMP_DIR="${TEMP_DIR//\\//}"
fi
ls -R "$TEMP_DIR/devsy-bin/"
mkdir -p ./bin/
find "$TEMP_DIR/devsy-bin/" -type f -name "devsy-*" -exec cp {} ./bin \;
find ./bin -name "devsy-*" -exec chmod +x {} \;
if [ "${{ runner.os }}" == "Linux" ]; then
chmod +x ./e2e.test
fi
ls -R ./bin/
- name: generate uuid
if: matrix.install-kind == true && runner.os != 'Windows' && (matrix.requires-secret == false || needs.can-read-secret.outputs.secret-set == 'true')
id: uuid
shell: bash
run: |
UUID=$(python -c "import uuid; print(uuid.uuid4().hex)")
echo "result=$UUID" >> "$GITHUB_OUTPUT"
- name: cache podman installer (Windows)
if: matrix.install-kind == true && runner.os == 'Windows' && (matrix.requires-secret == false || needs.can-read-secret.outputs.secret-set == 'true')
id: podman-cache-windows
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: ${{ runner.temp }}/podman.msi
key: ${{ runner.os }}-${{ runner.arch }}-podman-v5.8.2
- name: install and start podman (Windows)
if: matrix.install-kind == true && runner.os == 'Windows' && (matrix.requires-secret == false || needs.can-read-secret.outputs.secret-set == 'true')
shell: pwsh
run: |
$msiPath = "$env:RUNNER_TEMP\podman.msi"
if ("${{ steps.podman-cache-windows.outputs.cache-hit }}" -ne "true") {
$msiUrl = "https://github.com/containers/podman/releases/download/v5.8.2/podman-installer-windows-amd64.msi"
Invoke-WebRequest -Uri $msiUrl -OutFile $msiPath
}
$expectedHash = "eda54f26f9695d198d9a679fa45ae24ba35b78444f432b5fe0c122c5a3624c57"
$actualHash = (Get-FileHash -Path $msiPath -Algorithm SHA256).Hash.ToLower()
if ($actualHash -ne $expectedHash) {
throw "SHA256 mismatch for podman MSI! Expected: $expectedHash, Got: $actualHash"
}
Write-Host "Podman MSI checksum verified: $actualHash"
$installDir = "C:\Program Files\RedHat\Podman"
$logFile = "$env:RUNNER_TEMP\podman-install.log"
$proc = Start-Process msiexec.exe -Wait -PassThru -ArgumentList "/i `"$msiPath`" /qn /norestart /l*v `"$logFile`" INSTALLDIR=`"$installDir`""
Write-Host "MSI exit code: $($proc.ExitCode)"
if (!(Test-Path "$installDir\podman.exe")) {
Write-Host "--- MSI install log (last 50 lines) ---"
Get-Content $logFile -Tail 50
Write-Host "--- Searching for podman.exe ---"
Get-ChildItem "C:\" -Filter "podman.exe" -Recurse -Depth 4 -ErrorAction SilentlyContinue | ForEach-Object { Write-Host $_.FullName }
throw "podman.exe not found at $installDir"
}
echo "$installDir" | Out-File -Append -FilePath $env:GITHUB_PATH -Encoding utf8
wsl --set-default-version 2
& "$installDir\podman.exe" machine init
& "$installDir\podman.exe" machine set --rootful
& "$installDir\podman.exe" machine start
- name: cache kind.exe (Windows)
if: matrix.install-kind == true && runner.os == 'Windows' && (matrix.requires-secret == false || needs.can-read-secret.outputs.secret-set == 'true')
id: kind-cache-windows
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: ${{ runner.temp }}/kind.exe
key: ${{ runner.os }}-${{ runner.arch }}-kind-v0.24.0
- name: setup kind (Windows)
if: matrix.install-kind == true && runner.os == 'Windows' && (matrix.requires-secret == false || needs.can-read-secret.outputs.secret-set == 'true')
shell: bash
env:
KIND_EXPERIMENTAL_PROVIDER: podman
DOCKER_HOST: npipe:////./pipe/podman-machine-default
run: |
if [ "${{ steps.kind-cache-windows.outputs.cache-hit }}" != "true" ]; then
curl -Lo "$RUNNER_TEMP/kind.exe" "https://github.com/kubernetes-sigs/kind/releases/download/v0.24.0/kind-windows-amd64"
expected="6f724188289cc79395f45afae0f2b85e0d220c2b84c6ed2f5047d9d0c9a67028"
actual=$(sha256sum "$RUNNER_TEMP/kind.exe" | awk '{print $1}' | sed 's/^[^a-f0-9]*//')
if [ "$actual" != "$expected" ]; then
echo "SHA256 mismatch for kind.exe! Expected: $expected, Got: $actual"
exit 1
fi
echo "kind.exe checksum verified: $actual"
fi
export PATH="$RUNNER_TEMP:$PATH"
echo "$RUNNER_TEMP" >> "$GITHUB_PATH"
CLUSTER_NAME=$(python -c "import uuid; print(uuid.uuid4().hex)")
kind create cluster --name "$CLUSTER_NAME" --image kindest/node:v1.34.0@sha256:7416a61b42b1662ca6ca89f02028ac133a309a2a30ba309614e8ec94d976dc5a
# NOTE: skevetter/setup-kind does not work on Windows runners
- name: setup kind
if: matrix.install-kind == true && runner.os != 'Windows' && (matrix.requires-secret == false || needs.can-read-secret.outputs.secret-set == 'true')
uses: skevetter/setup-kind@7febac2ed35df332069b3bb687c6b1fa00fc0883 # v1
with:
name: ${{ steps.uuid.outputs.result }}
version: v0.24.0
image: kindest/node:v1.34.0@sha256:7416a61b42b1662ca6ca89f02028ac133a309a2a30ba309614e8ec94d976dc5a
skipClusterLogsExport: true
- name: cache apt packages (podman/runc)
if: (matrix.install-podman == 'rootless' || matrix.install-podman == 'rootful') && runner.os == 'Linux'
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: ${{ runner.temp }}/apt-archives
key: apt-podman-runc-${{ runner.os }}-v1
- name: Install Podman (Linux rootless)
if: matrix.install-podman == 'rootless' && runner.os == 'Linux'
env:
APT_CACHE_DIR: ${{ runner.temp }}/apt-archives
run: |
# Cache into a runner-owned dir: /var/cache/apt/archives is root-owned
# and actions/cache (running unprivileged) can't write into it on restore.
mkdir -p "$APT_CACHE_DIR"
sudo apt-get -o Dir::Cache::Archives="$APT_CACHE_DIR" update
sudo apt-get -o Dir::Cache::Archives="$APT_CACHE_DIR" install -y podman runc
# podman defaults to crun, which has been observed to fail with
# "OCI runtime error: crun: unknown version specified" on this
# runner image. Force runc, which is known-good, and fail fast
# with diagnostics if it isn't.
mkdir -p ~/.config/containers
printf '[engine]\nruntime = "runc"\n' > ~/.config/containers/containers.conf
podman info
podman run --rm busybox@sha256:fd8d9aa63ba2f0982b5304e1ee8d3b90a210bc1ffb5314d980eb6962f1a9715d echo "podman runtime preflight OK"
- name: Install Podman (Linux rootful)
if: matrix.install-podman == 'rootful' && runner.os == 'Linux'
env:
APT_CACHE_DIR: ${{ runner.temp }}/apt-archives
run: |
# Cache into a runner-owned dir: /var/cache/apt/archives is root-owned
# and actions/cache (running unprivileged) can't write into it on restore.
mkdir -p "$APT_CACHE_DIR"
sudo apt-get -o Dir::Cache::Archives="$APT_CACHE_DIR" update
sudo apt-get -o Dir::Cache::Archives="$APT_CACHE_DIR" install -y podman runc
# See the rootless step above: force runc over the default crun,
# which has been observed to fail on this runner image.
sudo mkdir -p /etc/containers
printf '[engine]\nruntime = "runc"\n' | sudo tee /etc/containers/containers.conf
sudo systemctl enable --now podman.socket
if ! timeout 30 bash -c 'until sudo podman info >/dev/null 2>&1; do sleep 1; done'; then
echo "::error::podman.socket did not become ready within 30s"
sudo systemctl status podman.socket --no-pager || true
sudo journalctl -u podman.socket --no-pager -n 100 || true
exit 1
fi
echo "DOCKER_HOST=unix:///run/podman/podman.sock" >> "$GITHUB_ENV"
sudo podman info
sudo podman run --rm busybox@sha256:fd8d9aa63ba2f0982b5304e1ee8d3b90a210bc1ffb5314d980eb6962f1a9715d echo "podman runtime preflight OK"
- name: get microsandbox latest version
if: matrix.install-microsandbox == true && runner.os == 'Linux'
id: msb-version
run: |
version=$(curl -fsSL https://api.github.com/repos/superradcompany/microsandbox/releases/latest | grep '"tag_name"' | head -1 | sed 's/.*"tag_name":[[:space:]]*"\([^"]*\)".*/\1/')
echo "version=$version" >> "$GITHUB_OUTPUT"
- name: cache microsandbox (Linux)
if: matrix.install-microsandbox == true && runner.os == 'Linux'
id: msb-cache
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: |
~/.microsandbox
~/.local/bin/msb
~/.local/bin/microsandbox
key: ${{ runner.os }}-${{ runner.arch }}-microsandbox-${{ steps.msb-version.outputs.version }}
- name: Install microsandbox (Linux)
if: matrix.install-microsandbox == true && runner.os == 'Linux' && steps.msb-cache.outputs.cache-hit != 'true'
run: |
curl -fsSL https://install.microsandbox.dev | sh
- name: configure microsandbox (Linux)
if: matrix.install-microsandbox == true && runner.os == 'Linux'
run: |
echo "$HOME/.local/bin" >> "$GITHUB_PATH"
# The e2e test skips gracefully if KVM is unavailable on the runner.
"$HOME/.local/bin/msb" doctor || true
- name: remove docker
if: matrix.label == 'docker-install' && (matrix.requires-secret == false || needs.can-read-secret.outputs.secret-set == 'true')
run: |
sudo systemctl stop docker.socket docker.service
sudo apt-get remove -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo rm -rf /var/lib/docker /var/lib/containerd /usr/bin/docker /usr/bin/dockerd
# The snapshot e2e suite pushes/pulls against a local registry:2
# fixture at host.docker.internal:15500 (see e2e/tests/snapshot/helper.go),
# reachable both from the host CLI and from inside the workspace
# container. Plain-HTTP is only safe here because that address is
# always local to this runner.
#
# host.docker.internal is Docker Desktop/OrbStack magic; plain Linux
# (this runner) resolves it for neither the host CLI process nor
# containers by default. The container side gets it via the fixture
# devcontainer.json's "--add-host=host.docker.internal:host-gateway"
# runArgs; the host side (the devsy CLI's own push-permission checks,
# which run before any container exists) needs an explicit /etc/hosts
# entry, since there's no running container to attach a gateway to yet.
- name: configure insecure registry for snapshot tests (Linux)
if: matrix.configure-insecure-registry == true && runner.os == 'Linux'
run: |
echo "127.0.0.1 host.docker.internal" | sudo tee -a /etc/hosts
sudo mkdir -p /etc/docker
existing="$(sudo cat /etc/docker/daemon.json 2>/dev/null || echo '{}')"
echo "$existing" | jq '.["insecure-registries"] = ((.["insecure-registries"] // []) + ["host.docker.internal:15500"] | unique)' \
| sudo tee /etc/docker/daemon.json > /dev/null
sudo systemctl restart docker
timeout 30 bash -c 'until docker info >/dev/null 2>&1; do sleep 1; done'
- name: generate GitHub App token
if: matrix.requires-secret == true && needs.can-read-secret.outputs.secret-set == 'true'
id: app-token
uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3
with:
app-id: ${{ secrets.DEVSY_GITHUB_APP_ID }}
private-key: ${{ secrets.DEVSY_GITHUB_APP_PRIVATE_KEY }}
owner: ${{ github.repository_owner }}
- name: run test
if: matrix.requires-secret == false || needs.can-read-secret.outputs.secret-set == 'true'
shell: bash
working-directory: ./e2e
env:
# NOTE: GitHub credentials are required for tests using private repos
GH_USERNAME: ${{ github.repository_owner }}
GH_ACCESS_TOKEN: ${{ steps.app-token.outputs.token || github.token }}
GH_CREDENTIAL_USERNAME: x-access-token
run: |
if [ "${{ runner.os }}" == "Linux" ]; then
sudo \
GH_USERNAME="${GH_USERNAME}" \
GH_ACCESS_TOKEN="${GH_ACCESS_TOKEN}" \
GH_CREDENTIAL_USERNAME="${GH_CREDENTIAL_USERNAME}" \
KUBECONFIG="${KUBECONFIG:-$HOME/.kube/config}" \
${DOCKER_HOST:+DOCKER_HOST="${DOCKER_HOST}"} \
PATH="${PATH}" \
./e2e.test -test.v -ginkgo.v -test.timeout 1500s --ginkgo.label-filter="${{ matrix.label }}"
else
GH_USERNAME="${GH_USERNAME}" \
GH_ACCESS_TOKEN="${GH_ACCESS_TOKEN}" \
GH_CREDENTIAL_USERNAME="${GH_CREDENTIAL_USERNAME}" \
KUBECONFIG="${KUBECONFIG:-$HOME/.kube/config}" \
PATH="${PATH}" \
DOCKER_HOST="npipe:////./pipe/podman-machine-default" \
./e2e.test.exe -test.v -ginkgo.v -test.timeout 1500s --ginkgo.label-filter="${{ matrix.label }}"
fi
- name: verify docker is installed
if: matrix.label == 'docker-install' && (matrix.requires-secret == false || needs.can-read-secret.outputs.secret-set == 'true')
run: docker --version && docker ps
ci-success:
name: CI Success
runs-on: ubuntu-latest
if: always()
needs:
- changes
- precommit
- lint
- licenses
- build-cli
- integration-tests-unprivileged
- integration-tests
steps:
- name: Check required jobs
run: |
# Fail if any required job failed (not skipped)
if [[ "${{ needs.changes.result }}" == "failure" ]] || \
[[ "${{ needs.precommit.result }}" == "failure" ]] || \
[[ "${{ needs.lint.result }}" == "failure" ]] || \
[[ "${{ needs.licenses.result }}" == "failure" ]] || \
[[ "${{ needs.build-cli.result }}" == "failure" ]] || \
[[ "${{ needs.integration-tests-unprivileged.result }}" == "failure" ]] || \
[[ "${{ needs.integration-tests.result }}" == "failure" ]]; then
echo "One or more required jobs failed"
exit 1
fi
echo "All required jobs passed or were skipped"