diff --git a/.github/workflows/build-rock.yaml b/.github/workflows/build-rock.yaml index 96598f8..8d3109d 100644 --- a/.github/workflows/build-rock.yaml +++ b/.github/workflows/build-rock.yaml @@ -1,4 +1,4 @@ -name: Build rock +name: Build and test rock on: pull_request: @@ -33,5 +33,32 @@ jobs: - name: Upload rock uses: actions/upload-artifact@v4 with: - name: snapcraft-${{ steps.vars.outputs.rockname }}.rock + name: snapcraft-rock path: '*.rock' + + spread-tests: + runs-on: self-hosted + needs: [build-rock] + + steps: + - name: Cleanup job workspace + run: | + rm -rf "${{ github.workspace }}" + mkdir "${{ github.workspace }}" + + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + submodules: true + + - name: Download rock artifact + uses: actions/download-artifact@v4 + with: + name: snapcraft-rock + path: tests + + # NOTE: Actually running spread is disabled until we have runners that + # support the tool. + # - name: Run spread + # run: spread diff --git a/.gitignore b/.gitignore index 1f3f0b3..a9a9bf8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,5 @@ *.rock +tests/spread/**/parts +tests/spread/**/prime +tests/spread/**/stage diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..0b37986 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,4 @@ +[submodule "tools/external/snapd-testing-tools"] + path = tools/external/snapd-testing-tools + url = https://github.com/snapcore/snapd-testing-tools.git + branch = main diff --git a/spread.yaml b/spread.yaml new file mode 100644 index 0000000..8c4fc68 --- /dev/null +++ b/spread.yaml @@ -0,0 +1,90 @@ +project: snapcraft-rocks + +# note: the `path` is inside /root because the docker snap has issues +# mounting directories that are outside the user's home +path: /root/snapcraft-rocks +environment: + PROJECT_PATH: /root/snapcraft-rocks + SNAPD_TESTING_TOOLS: $PROJECT_PATH/tools/external/snapd-testing-tools/tools + PATH: /snap/bin:$PATH:$SNAPD_TESTING_TOOLS:$PROJECT_PATH/tools/spread + # These variables are used to set the base in multi-base projects + SNAPCRAFT_BASE: core22 + SNAPCRAFT_BUILD_BASE: core22 + +include: + - tests/ + - tools/ + +backends: + google: + key: '$(HOST: echo "$SPREAD_GOOGLE_KEY")' + location: snapd-spread/us-east1-b + halt-timeout: 2h + systems: + - ubuntu-20.04-64: + workers: 1 + storage: 40G + - ubuntu-22.04-64: + workers: 1 + storage: 40G + - fedora-39-64: + workers: 1 + storage: 40G + +prepare: | + # if the 'tools' directory inside the submodule does not exist, then assume the submodule is empty + if [[ ! -d "$SNAPD_TESTING_TOOLS" ]]; then + echo "Cannot run spread because submodule 'snapd-testing-tools' is empty. Fetch with 'git submodule update --init' and rerun spread." + exit 1 + fi + + if os.query is-ubuntu; then + tempfile="$(mktemp)" + if ! apt-get update > "$tempfile" 2>&1; then + cat "$tempfile" + exit 1 + fi + fi + + tests.pkgs install snapd + + snap wait system seed.loaded + + # The /snap directory does not exist in some environments + [ ! -d /snap ] && ln -s /var/lib/snapd/snap /snap + + # Hold snap refreshes. + snap refresh --hold + + if ! snap watch --last=auto-refresh?; then + journalctl -xe + fi + if ! snap watch --last=install?; then + journalctl -xe + fi + + if [ "$SPREAD_SYSTEM" = "fedora-39-64" ]; then + # Latest docker snap needs a more recent version of snapd than Fedora ships + # https://github.com/canonical/rockcraft/pull/277 + snap install docker --channel=core18/stable + else + snap install docker + fi + + # make sure docker is working + retry -n 10 --wait 2 sh -c 'docker run --rm hello-world' + + # install rockcraft just to use its bundled skopeo + snap install --classic --stable rockcraft + + load_snapcraft_rock + + +restore-each: | + # Cleanup after each task. + rm -f *.snap + + +suites: + tests/spread/general/: + summary: general tests that should work on all bases and Snapcraft versions diff --git a/tests/spread/general/hello/snap/snapcraft.yaml b/tests/spread/general/hello/snap/snapcraft.yaml new file mode 100644 index 0000000..aff6955 --- /dev/null +++ b/tests/spread/general/hello/snap/snapcraft.yaml @@ -0,0 +1,17 @@ +name: hello-world +version: "1.0" +summary: test +description: hello-world +grade: devel +confinement: strict +base: SNAPCRAFT_BASE +build-base: SNAPCRAFT_BUILD_BASE + +parts: + hello-world: + plugin: nil + stage-packages: ["hello"] + +apps: + hello-world: + command: usr/bin/hello diff --git a/tests/spread/general/hello/task.yaml b/tests/spread/general/hello/task.yaml new file mode 100644 index 0000000..68d94ea --- /dev/null +++ b/tests/spread/general/hello/task.yaml @@ -0,0 +1,9 @@ +summary: build & run a basic "hello world" snap + +execute: | + # pack the snap + run_snapcraft pack + + # install & run it + snap install --dangerous hello-world_1.0_amd64.snap + hello-world -g "hello-from-snap" | MATCH "hello-from-snap" diff --git a/tools/external/snapd-testing-tools b/tools/external/snapd-testing-tools new file mode 160000 index 0000000..5121bfb --- /dev/null +++ b/tools/external/snapd-testing-tools @@ -0,0 +1 @@ +Subproject commit 5121bfb659bb9602f7d5a8a2f354dd93662270dc diff --git a/tools/spread/load_snapcraft_rock b/tools/spread/load_snapcraft_rock new file mode 100755 index 0000000..ce074c7 --- /dev/null +++ b/tools/spread/load_snapcraft_rock @@ -0,0 +1,13 @@ +#!/bin/bash + +# load_snapcraft_rock: helper to load the Snapcraft rock into docker. +# +# The rock is always loaded as "snapcraft-rock", regardless of supported base. + +if stat ${PROJECT_PATH}/tests/*.rock 2>/dev/null; then + rockname=$(ls ${PROJECT_PATH}/tests/*.rock) + /snap/rockcraft/current/bin/skopeo --insecure-policy copy oci-archive:${rockname} docker-daemon:snapcraft-rock:latest +else + echo "Expected a rock to exist in ${PROJECT_PATH}/tests/" + exit 1 +fi diff --git a/tools/spread/run_snapcraft b/tools/spread/run_snapcraft new file mode 100755 index 0000000..7066032 --- /dev/null +++ b/tools/spread/run_snapcraft @@ -0,0 +1,8 @@ +#!/bin/bash + +# run_snapcraft: helper to run Snapcraft inside a container. + +# replace the SNAPCRAFT_* tokens with the correct values for our Snapcraft image +sed --in-place='' "s/SNAPCRAFT_BASE/$SNAPCRAFT_BASE/" snap/snapcraft.yaml +sed --in-place='' "s/SNAPCRAFT_BUILD_BASE/$SNAPCRAFT_BUILD_BASE/" snap/snapcraft.yaml +docker run --rm -v `pwd`:/project snapcraft-rock:latest "$@"