diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index c2ce5b3..55dddb1 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -4,10 +4,8 @@ "dockerfile": "Dockerfile", "context": ".." }, - "settings": { - }, - "extensions": [ - ], + "settings": {}, + "extensions": [], "forwardPorts": [8080], "remoteUser": "node" } diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..24f3bb6 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,101 @@ +# This file is based on work by authors of +# https://github.com/bytecodealliance/sample-wasi-http-rust + +name: Build and publish a Wasm Component to GitHub Artifacts + +on: + push: + tags: + - v* + workflow_dispatch: + +env: + IMAGE_NAME: ${{ github.repository }} + +jobs: + publish: + runs-on: ubuntu-latest + permissions: + id-token: write + packages: write + contents: read + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: '23' + cache: 'npm' + + - name: Set up just + uses: extractions/setup-just@v3 + + - name: Extract package information + run: | + echo "COMPONENT_NAME=$(npm pkg get name | tr -d '"')" >> $GITHUB_ENV + echo "COMPONENT_DESCRIPTION=$(npm pkg get description | tr -d '"')" >> $GITHUB_ENV + echo "COMPONENT_SOURCE=$(npm pkg get repository.url | tr -d '"')" >> $GITHUB_ENV + echo "COMPONENT_HOMEPAGE=$(npm pkg get homepage | tr -d '"')" >> $GITHUB_ENV + echo "COMPONENT_LICENSES=$(npm pkg get license | tr -d '"')" >> $GITHUB_ENV + + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: ghcr.io/${{ github.actor }}/${{ env.COMPONENT_NAME }} + tags: | + type=semver,pattern={{version}} + + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build the component + run: just build + + - name: Normalize COMPONENT_NAME and Append .wasm + run: echo "COMPONENT_NAME_UNDERSCORED=${COMPONENT_NAME//-/_}.wasm" >> $GITHUB_ENV + + - name: Install cosign + if: github.event_name != 'workflow_dispatch' + uses: sigstore/cosign-installer@v3.7.0 + + - name: Publish `:` to GitHub Container Registry + if: github.event_name != 'workflow_dispatch' + id: publish_versioned + uses: bytecodealliance/wkg-github-action@v5 + with: + file: dist/${{ env.COMPONENT_NAME_UNDERSCORED }} + oci-reference-without-tag: ghcr.io/${{ env.IMAGE_NAME }}/${{ env.COMPONENT_NAME }} + version: ${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.version'] }} + description: ${{ env.COMPONENT_DESCRIPTION }} + source: ${{ env.COMPONENT_SOURCE }} + homepage: ${{ env.COMPONENT_HOMEPAGE }} + licenses: ${{ env.COMPONENT_LICENSES }} + + - name: Sign the versioned wasm component + if: github.event_name != 'workflow_dispatch' + run: cosign sign --yes ghcr.io/${{ env.IMAGE_NAME }}/${{ env.COMPONENT_NAME }}@${{ steps.publish_versioned.outputs.digest }} + + - name: Publish `:latest` release to GitHub Container Registry + if: github.event_name != 'workflow_dispatch' + id: publish_latest + uses: bytecodealliance/wkg-github-action@v5 + with: + file: dist/${{ env.COMPONENT_NAME_UNDERSCORED }} + oci-reference-without-tag: ghcr.io/${{ env.IMAGE_NAME }}/${{ env.COMPONENT_NAME }} + version: latest + description: ${{ env.COMPONENT_DESCRIPTION }} + source: ${{ env.COMPONENT_SOURCE }} + homepage: ${{ env.COMPONENT_HOMEPAGE }} + licenses: ${{ env.COMPONENT_LICENSES }} + + - name: Sign the latest wasm component + if: github.event_name != 'workflow_dispatch' + run: cosign sign --yes ghcr.io/${{ env.IMAGE_NAME }}/${{ env.COMPONENT_NAME }}@${{ steps.publish_latest.outputs.digest }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 4052dd5..4a70a04 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -17,17 +17,18 @@ jobs: uses: actions/setup-node@v4 with: node-version: '23' - - name: Install dependencies - run: npm install + cache: 'npm' + - name: Set up just + uses: extractions/setup-just@v3 - name: Install Wasmtime run: | curl https://wasmtime.dev/install.sh -sSf | bash echo "$HOME/.wasmtime/bin" >> $GITHUB_PATH - name: Build the project - run: npm run build + run: just build - name: Run tests run: npm test - name: Run format checks - run: npm run format -- --check + run: npm run format-ci - name: Run ESLint run: npm run lint diff --git a/README.md b/README.md index 79fe090..237b4a4 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,7 @@ Alternatively, run: ```bash $ npm install $ npm run build -$ wasmtime serve -S common dist/server.component.wasm +$ wasmtime serve -S common dist/sample-wasi-http-js.wasm ``` ## See Also diff --git a/eslint.config.js b/eslint.config.js index 05bc90d..39b2d67 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -2,8 +2,14 @@ import { defineConfig } from "eslint/config"; import js from "@eslint/js"; import globals from "globals"; - export default defineConfig([ - { files: ["**/*.{js,mjs,cjs}"], plugins: { js }, extends: ["js/recommended"] }, - { files: ["**/*.{js,mjs,cjs}"], languageOptions: { globals: globals.browser } }, -]); \ No newline at end of file + { + files: ["**/*.{js,mjs,cjs}"], + plugins: { js }, + extends: ["js/recommended"], + }, + { + files: ["**/*.{js,mjs,cjs}"], + languageOptions: { globals: globals.browser }, + }, +]); diff --git a/justfile b/justfile index 1b72891..6b91990 100644 --- a/justfile +++ b/justfile @@ -1,3 +1,5 @@ +package-name := trim_start_match(trim_end_match(`npm pkg get name`, "\""), "\"") + alias b := build # List all recipes @@ -27,4 +29,4 @@ test: build serve: build @echo 'Serving guest...' - wasmtime serve -S common dist/server.component.wasm + wasmtime serve -S common dist/{{package-name}}.wasm diff --git a/package.json b/package.json index 148d66c..3365d71 100644 --- a/package.json +++ b/package.json @@ -2,13 +2,19 @@ "name": "sample-wasi-http-js", "version": "0.1.0", "description": "Sample project demonstratingu JS project targeting WASI http", + "homepage": "https://github.com/bytecodealliance/sample-wasi-http-js", "license": "(Apache-2.0 WITH LLVM-exception)", "author": "Tomasz Andrzejak", "type": "module", + "repository": { + "type": "git", + "url": "https://github.com/bytecodealliance/sample-wasi-http-js" + }, "scripts": { "bundle": "rollup -c", - "build": "npm run bundle && componentize-js --aot --wit wit -o dist/server.component.wasm dist/bundle.js", - "format": "prettier --write \"**/*.{js,jsx,ts,tsx,json,css,md}\"", + "build": "npm run bundle && componentize-js --aot --wit wit -o dist/$npm_package_name.wasm dist/bundle.js", + "format": "prettier --write \"**/*.{js,jsx,ts,tsx,json,css}\"", + "format-ci": "prettier --check \"**/*.{js,jsx,ts,tsx,json,css}\"", "lint": "eslint src/**/*.js", "test": "vitest --run" }, diff --git a/src/server.test.js b/src/server.test.js index 8094051..56f55a7 100644 --- a/src/server.test.js +++ b/src/server.test.js @@ -1,7 +1,7 @@ import { describe, it, beforeAll, afterAll, expect } from "vitest"; import { spawn } from "child_process"; -import waitOn from 'wait-on'; +import waitOn from "wait-on"; const PORT = 8080; const timeout = 30000; @@ -13,7 +13,7 @@ describe("Integration tests for the WASI HTTP server endpoints", () => { beforeAll(async () => { serverProcess = spawn( "wasmtime", - ["serve", "-S", "common", "dist/server.component.wasm"], + ["serve", "-S", "common", "dist/sample-wasi-http-js.wasm"], { stdio: "inherit" }, ); @@ -22,7 +22,7 @@ describe("Integration tests for the WASI HTTP server endpoints", () => { resources: [`tcp:localhost:${PORT}`], timeout, delay: 1000, - interval: 500 + interval: 500, }); }, timeout);