ci: add more tests (#466)

Drew Smirnoff created

Change summary

.github/workflows/ci.yml | 204 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 203 insertions(+), 1 deletion(-)

Detailed changes

.github/workflows/ci.yml 🔗

@@ -1,4 +1,4 @@
-name: Go CI
+name: CI
 
 on:
   push:
@@ -32,3 +32,205 @@ jobs:
 
       - name: Build
         run: go build -v ./...
+
+  lint:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v6
+
+      - name: Set up Go
+        uses: actions/setup-go@v6
+        with:
+          go-version: "1.26.2"
+
+      - name: Install system dependencies
+        run: sudo apt-get update && sudo apt-get install -y libpcsclite-dev
+
+      - name: Check formatting
+        run: |
+          unformatted=$(gofmt -l .)
+          if [ -n "$unformatted" ]; then
+            echo "::error::The following files are not formatted with gofmt:"
+            echo "$unformatted"
+            exit 1
+          fi
+
+      - name: Vet
+        run: go vet ./...
+
+  mod-tidy:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v6
+
+      - name: Set up Go
+        uses: actions/setup-go@v6
+        with:
+          go-version: "1.26.2"
+
+      - name: Check go.mod and go.sum are tidy
+        run: |
+          go mod tidy
+          if ! git diff --quiet go.mod go.sum; then
+            echo "::error::go.mod or go.sum are not tidy. Run 'go mod tidy' and commit the changes."
+            git diff go.mod go.sum
+            exit 1
+          fi
+
+  website:
+    runs-on: ubuntu-latest
+    defaults:
+      run:
+        working-directory: docs
+    steps:
+      - uses: actions/checkout@v6
+
+      - name: Set up Node.js
+        uses: actions/setup-node@v4
+        with:
+          node-version: "22"
+          cache: npm
+          cache-dependency-path: docs/package-lock.json
+
+      - name: Install dependencies
+        run: npm ci
+
+      - name: Build
+        run: npx docusaurus build
+
+  snap:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v6
+
+      - name: Validate snapcraft.yaml
+        run: |
+          sudo snap install snapcraft --classic
+          # Verify snapcraft can parse the project file
+          snapcraft list-plugins
+          # Validate YAML structure and required fields
+          python3 << 'PYEOF'
+          import yaml, sys
+
+          with open("snapcraft.yaml") as f:
+              snap = yaml.safe_load(f)
+
+          errors = []
+          for field in ("name", "base", "summary", "description", "parts"):
+              if field not in snap:
+                  errors.append(f"Missing required field: {field}")
+
+          if "apps" in snap:
+              for app_name, app in snap["apps"].items():
+                  if "command" not in app:
+                      errors.append(f"App '{app_name}' missing 'command'")
+
+          if "parts" in snap:
+              for part_name, part in snap["parts"].items():
+                  if "plugin" not in part and "override-build" not in part:
+                      errors.append(f"Part '{part_name}' missing 'plugin' or 'override-build'")
+
+          if errors:
+              for e in errors:
+                  print(f"::error::{e}", file=sys.stderr)
+              sys.exit(1)
+
+          print("snapcraft.yaml is valid.")
+          PYEOF
+
+  flatpak:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v6
+
+      - name: Install dependencies
+        run: |
+          sudo apt-get update
+          sudo apt-get install -y python3-pip
+          pip3 install PyYAML
+
+      - name: Validate Flatpak manifest YAML
+        run: python3 -c "import yaml, sys; yaml.safe_load(open('com.floatpane.matcha.yaml'))"
+
+      - name: Check Flatpak manifest structure
+        run: |
+          python3 << 'EOF'
+          import yaml, sys
+
+          with open("com.floatpane.matcha.yaml") as f:
+              manifest = yaml.safe_load(f)
+
+          errors = []
+          for field in ("id", "runtime", "runtime-version", "sdk", "command", "modules"):
+              if field not in manifest:
+                  errors.append(f"Missing required field: {field}")
+
+          if "modules" in manifest:
+              for mod in manifest["modules"]:
+                  if "name" not in mod:
+                      errors.append(f"Module missing 'name' field: {mod}")
+                  if "sources" not in mod and "buildsystem" not in mod:
+                      errors.append(f"Module '{mod.get('name', '?')}' missing 'sources' or 'buildsystem'")
+
+          if errors:
+              for e in errors:
+                  print(f"::error::{e}", file=sys.stderr)
+              sys.exit(1)
+
+          print("Flatpak manifest is valid.")
+          EOF
+
+  nix:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v6
+
+      - name: Install Nix
+        uses: cachix/install-nix-action@v31
+        with:
+          nix_path: nixpkgs=channel:nixpkgs-unstable
+
+      - name: Check flake
+        run: nix flake check --no-build
+
+  lua-plugins:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v6
+
+      - name: Install Lua
+        run: sudo apt-get update && sudo apt-get install -y lua5.4
+
+      - name: Check Lua syntax
+        run: |
+          failed=0
+          for f in plugins/*.lua; do
+            if ! luac -p "$f" 2>&1; then
+              echo "::error file=$f::Syntax error in $f"
+              failed=1
+            fi
+          done
+          exit $failed
+
+  goreleaser:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v6
+        with:
+          fetch-depth: 0
+
+      - name: Set up Go
+        uses: actions/setup-go@v6
+        with:
+          go-version: "1.26.2"
+
+      - name: Install GoReleaser
+        uses: goreleaser/goreleaser-action@v6
+        with:
+          install-only: true
+
+      - name: Validate release config
+        run: goreleaser check -f .goreleaser.yml
+
+      - name: Validate nightly config
+        run: goreleaser check -f .goreleaser.nightly.yml