diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml new file mode 100644 index 0000000..f816ec0 --- /dev/null +++ b/.github/workflows/test.yaml @@ -0,0 +1,56 @@ +name: Test +on: + push: + branches: [main] + pull_request: + branches: [main] + +jobs: + test: + runs-on: "ubuntu-latest" + steps: + - uses: actions/checkout@v4 + + - name: Install Wasm Rust target + run: | + rustup target add wasm32-wasip1 + + - name: Install wizer + env: + WIZER_VERSION: v9.0.0 + run: | + wget -O wizer-${{ env.WIZER_VERSION }}-x86_64-linux.tar.xz \ + https://github.com/bytecodealliance/wizer/releases/download/${{ env.WIZER_VERSION }}/wizer-${{ env.WIZER_VERSION }}-x86_64-linux.tar.xz + tar -xf wizer-${{ env.WIZER_VERSION }}-x86_64-linux.tar.xz + mv wizer-${{ env.WIZER_VERSION }}-x86_64-linux/wizer /usr/local/bin/wizer + + - uses: actions/setup-go@v5 + with: + go-version: '1.23' + + - name: Setup TinyGo + uses: acifani/setup-tinygo@v2 + with: + tinygo-version: '0.35.0' + + - name: Install pnpm + run: | + npm install -g pnpm + + - name: Install Spin + uses: fermyon/actions/spin/setup@v1 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + + - name: Build apps + env: + ENABLE_WASM_OPT: false + run: | + make build-samples build-tutorials + + - name: Test apps + env: + ENABLE_WASM_OPT: false + TIMEOUT: 2m + run: | + make test-samples test-tutorials diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..c1c2198 --- /dev/null +++ b/Makefile @@ -0,0 +1,80 @@ +SHELL := /bin/bash +MAKE_DIR := $(dir $(realpath $(lastword $(MAKEFILE_LIST)))) + +default: build-samples build-tutorials + +SAMPLES ?= $(shell ls ./samples) + +# Some samples require extra setup steps +.PHONY: setup-geo-ip +setup-geo-ip: + make -C samples/geo-ip create-test-mmdb + +.PHONY: setup-large-scale-redirects +setup-large-scale-redirects: + make -C samples/large-scale-redirects create-test-redirects + +.PHONY: setup-samples +setup-samples: setup-geo-ip setup-large-scale-redirects + +# Build the samples +.PHONY: build-samples +build-samples: setup-samples + @for dir in $(SAMPLES); do \ + echo "Building sample: $$dir"; \ + cd $(MAKE_DIR)samples/$$dir; \ + spin build || { \ + echo "❌ Error: Build failed for sample: $$dir"; \ + exit 1; \ + }; \ + done + +# Test the samples +# TODO: some samples have specific instructions for their requests, eg headers, paths, variables, etc. +.PHONY: test-samples +test-samples: build-samples + @for dir in $(SAMPLES); do \ + if [[ "$$dir" == "large-scale-redirects" || \ + "$$dir" == "geo-ip" || \ + "$$dir" == "gh-api-token" || \ + "$$dir" == "early-hints-rust" || \ + "$$dir" == "linode-object-storage-streaming" ]]; then \ + echo "TODO: Skipping sample: $$dir" && continue; \ + fi; \ + echo "Testing sample: $$dir"; \ + cd $(MAKE_DIR)samples/$$dir; \ + $(MAKE_DIR)/test-app.sh || { \ + echo "❌ Error: Test failed for sample: $$dir"; \ + exit 1; \ + }; \ + done + +TUTORIALS ?= $(shell ls ./tutorials) + +# Build the tutorials +.PHONY: build-tutorials +build-tutorials: + @for dir in $(TUTORIALS); do \ + echo "Building tutorial: $$dir"; \ + cd $(MAKE_DIR)tutorials/$$dir; \ + spin build || { \ + echo "❌ Error: Build failed for tutorial: $$dir"; \ + exit 1; \ + }; \ + done + +# Test the tutorials +# TODO: some tutorials have specific instructions for their requests, eg headers, paths, variables, etc. +.PHONY: test-tutorials +test-tutorials: build-tutorials + @for dir in $(TUTORIALS); do \ + if [[ "$$dir" == "stream-data-from-linode-object-store-tutorial" ]]; then \ + echo "TODO: Skipping tutorial: $$dir" && continue; \ + fi; \ + echo "Testing tutorial: $$dir"; \ + cd $(MAKE_DIR)tutorials/$$dir; \ + $(MAKE_DIR)/test-app.sh || { \ + echo "❌ Error: Test failed for tutorial: $$dir"; \ + exit 1; \ + }; \ + done \ No newline at end of file diff --git a/samples/geo-ip/.gitignore b/samples/geo-ip/.gitignore index 7152895..3c851fe 100644 --- a/samples/geo-ip/.gitignore +++ b/samples/geo-ip/.gitignore @@ -1,3 +1,4 @@ target/ .spin/ .spin-aka/ +geoip-static-db/geoip.mmdb diff --git a/samples/geo-ip/Makefile b/samples/geo-ip/Makefile index eb4d70f..b57d77c 100644 --- a/samples/geo-ip/Makefile +++ b/samples/geo-ip/Makefile @@ -2,4 +2,9 @@ build: @test -f geoip-static-db/geoip.mmdb || (echo "Error: geoip-static-db/geoip.mmdb not found!" && exit 1) cd geoip-static-db && ./build.sh geoip.mmdb - cargo build --target wasm32-wasip1 --release \ No newline at end of file + cargo build --target wasm32-wasip1 --release + +.PHONY: create-test-mmdb +create-test-mmdb: + cp ./etc/GeoIP2-City-Test.mmdb \ + ./geoip-static-db/geoip.mmdb diff --git a/samples/large-scale-redirects/.gitignore b/samples/large-scale-redirects/.gitignore index 7152895..fb4e7b9 100644 --- a/samples/large-scale-redirects/.gitignore +++ b/samples/large-scale-redirects/.gitignore @@ -1,3 +1,4 @@ target/ .spin/ .spin-aka/ +output/ \ No newline at end of file diff --git a/samples/large-scale-redirects/Makefile b/samples/large-scale-redirects/Makefile new file mode 100644 index 0000000..a0076f9 --- /dev/null +++ b/samples/large-scale-redirects/Makefile @@ -0,0 +1,9 @@ +.PHONY: build-rules-manager +build-rules-manager: + cargo build --release -p rules-manager + +.PHONY: create-test-redirects +create-test-redirects: build-rules-manager + ./target/release/rules-manager \ + --add-rules example-redirects.txt \ + --output-dir output diff --git a/samples/large-scale-redirects/build.sh b/samples/large-scale-redirects/build.sh index b586d49..c9f0839 100755 --- a/samples/large-scale-redirects/build.sh +++ b/samples/large-scale-redirects/build.sh @@ -1,6 +1,8 @@ #!/usr/bin/env bash set -e +ENABLE_WASM_OPT="${ENABLE_WASM_OPT:-true}" + # Check if the correct number of arguments is provided if [ "$#" -ne 4 ]; then echo "Usage: $0 " @@ -11,7 +13,7 @@ fi cargo build --target wasm32-wasip1 --release echo "$1 $2 $3" | wizer --allow-wasi --wasm-bulk-memory true --dir . -o "$4" target/wasm32-wasip1/release/redirects_rs.wasm # If wasm-opt is installed, run it to optimize the output -if command -v wasm-opt &> /dev/null +if [[ "${ENABLE_WASM_OPT}" == "true" ]] && command -v wasm-opt &> /dev/null then wasm-opt -O3 --enable-bulk-memory-opt -o "$4" "$4" fi diff --git a/samples/large-scale-redirects/spin.toml b/samples/large-scale-redirects/spin.toml index d45d49e..6e2bb92 100644 --- a/samples/large-scale-redirects/spin.toml +++ b/samples/large-scale-redirects/spin.toml @@ -14,5 +14,5 @@ component = "redirects-rs" source = "target/redirect.wasm" allowed_outbound_hosts = [] [component.redirects-rs.build] -command = "./build.sh example-redirects.txt" +command = "./build.sh output/sources.fst output/targets.fcsd 302 target/redirect.wasm" watch = ["src/**/*.rs", "Cargo.toml", "build.sh", "redirects.txt"] diff --git a/test-app.sh b/test-app.sh new file mode 100755 index 0000000..45df108 --- /dev/null +++ b/test-app.sh @@ -0,0 +1,8 @@ +#!/bin/bash +set -beuo pipefail + +spin up & + +timeout ${TIMEOUT:-30s} bash -c 'until curl -q 127.0.0.1:3000 &>/dev/null; do sleep 1; done' + +trap 'kill -s SIGTERM $(jobs -p)' EXIT \ No newline at end of file