name: Test, Build & Deploy # Tests + build run on every push/PR; the deploy (WebDAV publish of the # single-file dist/index.html) runs only on the default branch (master). "on": push: branches: - '**' pull_request: jobs: test-and-build: runs-on: host steps: - uses: actions/checkout@v4 - name: Setup Node uses: actions/setup-node@v4 with: node-version: '20' cache: 'npm' - name: Install dependencies run: npm ci - name: Run tests run: npm run test:run - name: Build (single-file bundle) env: VITE_COMMIT_HASH: ${{ github.sha }} run: npm run build - name: Verify build output run: test -f dist/index.html deploy: # Release the built app only when a commit lands on the default branch. needs: test-and-build if: github.ref == 'refs/heads/master' runs-on: host steps: - uses: actions/checkout@v4 - name: Setup Node uses: actions/setup-node@v4 with: node-version: '20' cache: 'npm' - name: Install dependencies run: npm ci - name: Build (single-file bundle) env: VITE_COMMIT_HASH: ${{ github.sha }} run: npm run build - name: Verify build output run: test -f dist/index.html # Publish dist/index.html to the WebDAV mirror. The pretty URL # (…/weather/index.html) 401s without auth; the file is the full # www/static/weather/index.html path with basic auth. - name: Publish to WebDAV (/weather) env: WEBDAV_USER: ${{ secrets.WEBDAV_USER }} WEBDAV_PASS: ${{ secrets.WEBDAV_PASS }} WEBDAV_URL: https://files.thecookiejar.me/www/static/weather/index.html run: | if [ -z "$WEBDAV_USER" ] || [ -z "$WEBDAV_PASS" ]; then echo "::error::WEBDAV_USER / WEBDAV_PASS repo secrets are not set." echo "::error::Add them under Settings → Actions → Secrets, then re-run this job." exit 1 fi # DELETE-then-PUT: the serving layer caches uploaded files, so a plain # PUT over an existing file returns 201 but keeps serving the OLD copy. # Deleting first guarantees the new build is actually served. (Each curl # is a single line -- YAML block scalars don't convert backslash-nl.) curl -sS -u "$WEBDAV_USER:$WEBDAV_PASS" -X DELETE "$WEBDAV_URL" || echo "(DELETE returned non-zero; file may not exist yet -- continuing)" curl -sS --fail -u "$WEBDAV_USER:$WEBDAV_PASS" -X PUT -T dist/index.html -H 'Content-Type: text/html' "$WEBDAV_URL" echo "Published to $WEBDAV_URL" # Pull the freshly uploaded file back and compare it to our build, so a # successful deploy isn't just "curl returned 0" but bytes actually match. - name: Verify deployed file matches build env: WEBDAV_USER: ${{ secrets.WEBDAV_USER }} WEBDAV_PASS: ${{ secrets.WEBDAV_PASS }} WEBDAV_URL: https://files.thecookiejar.me/www/static/weather/index.html run: | curl -sS --fail -u "$WEBDAV_USER:$WEBDAV_PASS" "$WEBDAV_URL" -o /tmp/deployed.html sha1sum dist/index.html /tmp/deployed.html test "$(sha1sum dist/index.html | cut -d' ' -f1)" = \ "$(sha1sum /tmp/deployed.html | cut -d' ' -f1)" \ && echo "Deploy verified: bytes match" \ || { echo "::error::Deployed file does not match build"; exit 1; }