From 85d68c27e39936e9972c5aa375559dd713b0b66e Mon Sep 17 00:00:00 2001 From: Scott Andrews Date: Sun, 20 Sep 2026 15:20:25 -0400 Subject: [PATCH] Publish pre-releases with a semantic version Previously commits on main published with the 'dev' tag. Now the version of the interface is used. The interfaces are now versioned as `0.0.5-dev`. This version will need to be updated to match each release. Signed-off-by: Scott Andrews --- .github/workflows/ci.yaml | 19 +++++++++---- Makefile | 19 +++++++------ .../package.wit | 2 +- components/wit/world.wit | 22 +++++++-------- tests/cli.wac | 10 +++---- tests/host.wac | 2 +- .../package.wit | 2 +- tests/wit/ops.wit | 2 +- tests/wit/world.wit | 28 +++++++++---------- wit/world.wit | 2 +- 10 files changed, 59 insertions(+), 49 deletions(-) rename components/wit/deps/{componentized-services => componentized-services-0.0.5-dev}/package.wit (99%) rename tests/wit/deps/{componentized-services => componentized-services-0.0.5-dev}/package.wit (99%) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index fa94726..1f9c38b 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -107,18 +107,23 @@ jobs: uses: cargo-bins/cargo-binstall@main - name: Install wkg run: cargo binstall --force wkg + - name: Install wasm-tools + run: cargo binstall --force wasm-tools - name: Install cosign uses: sigstore/cosign-installer@v4.1.2 - - name: Get tag version - if: startsWith(github.ref, 'refs/tags/v') - id: get_version - run: echo ::set-output name=VERSION::${GITHUB_REF/refs\/tags\//} - name: Download components.tar uses: actions/download-artifact@v8 with: name: components.tar - name: Extract components run: tar -xvf components.tar -C lib + - name: Get interface version + id: interface_version + run: echo "VERSION=$( wasm-tools component wit lib/interface.wasm --json | jq -r '.packages[0].name' | cut -d'@' -f2 )" >> $GITHUB_OUTPUT + - name: Get tag version + if: startsWith(github.ref, 'refs/tags/') + id: tag_version + run: echo "VERSION=${GITHUB_REF/refs\/tags\//}" >> $GITHUB_OUTPUT - name: Login to GitHub Container Registry uses: docker/login-action@v4 with: @@ -126,12 +131,14 @@ jobs: username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Publish components to gchr.io + # only publish tags and pre-releases from main + if: startsWith(github.ref, 'refs/tags/') || (github.ref == 'refs/heads/main' && contains(steps.interface_version.outputs.VERSION, '-')) run: make publish env: REPOSITORY: "ghcr.io/${{ github.repository }}" - VERSION: "${{ case(github.ref == 'refs/heads/main', 'dev', steps.get_version.outputs.VERSION) }}" + VERSION: "${{ case(github.ref == 'refs/heads/main', steps.interface_version.outputs.VERSION, steps.tag_version.outputs.VERSION) }}" - name: Draft GitHub Release - if: startsWith(github.ref, 'refs/tags/v') + if: startsWith(github.ref, 'refs/tags/') uses: softprops/action-gh-release@v3 with: draft: true diff --git a/Makefile b/Makefile index 9918452..69da124 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ help: ## Display this help. @awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST) .PHONY: publish ## Publish each component in the lib directory -publish: $(shell find lib -type f -name "*.wasm" | sed -e 's:^lib/:publish-:g') +publish: $(shell find lib -type f -name "*.wasm" -depth 1 | sed -e 's:^lib/:publish-:g') .PHONY: publish-% publish-%: @@ -14,26 +14,29 @@ ifndef REPOSITORY $(error REPOSITORY is undefined) endif @$(eval FILE := $(@:publish-%=%)) - @$(eval COMPONENT := $(FILE:%.wasm=%)) + @$(eval COMPONENT := $(if $(filter %.debug.wasm,$(FILE)),$(FILE:%.debug.wasm=%),$(FILE:%.wasm=%))) + @$(eval TITLE := $(if $(filter %.debug.wasm,$(FILE)),$(COMPONENT) (debug),$(COMPONENT))) # @$(eval DESCRIPTION := $(shell head -n 3 "lib/${FILE}.md" | tail -n 1)) @$(eval REVISION := $(shell git rev-parse HEAD)$(shell git diff --quiet HEAD && echo "+dirty")) - @$(eval TAG := $(patsubst v%,%,$(subst +,_,$(VERSION)))) + @$(eval COMPONENT_VERSION := $(if $(filter %.debug.wasm,$(FILE)),${VERSION}+debug,${VERSION})) + @$(eval TAG := $(patsubst v%,%,$(subst +,_,$(COMPONENT_VERSION)))) + @$(eval IMAGE := $(if $(filter interface.wasm,$(FILE)),${REPOSITORY}:${TAG},${REPOSITORY}/${COMPONENT}:${TAG})) # --annotation "org.opencontainers.image.description=${DESCRIPTION}" \ - @echo "::group::${FILE} -> ${REPOSITORY}/${COMPONENT}:${TAG}" + @echo "::group::${FILE} -> ${IMAGE}" @DIGEST=$$( \ wkg oci push \ - --annotation "org.opencontainers.image.title=${COMPONENT}" \ - --annotation "org.opencontainers.image.version=${VERSION}" \ + --annotation "org.opencontainers.image.title=${TITLE}" \ + --annotation "org.opencontainers.image.version=${COMPONENT_VERSION}" \ --annotation "org.opencontainers.image.source=https://github.com/${GITHUB_REPOSITORY}.git" \ --annotation "org.opencontainers.image.revision=${REVISION}" \ --annotation "org.opencontainers.image.licenses=Apache-2.0" \ - "${REPOSITORY}/${COMPONENT}:${TAG}" \ + "${IMAGE}" \ "lib/${FILE}" \ 2>&1 \ | tee /dev/stderr \ | grep -o 'sha256:[a-f0-9]\{64\}' \ ) ; \ - cosign sign --yes "${REPOSITORY}/${COMPONENT}:${TAG}@$${DIGEST}" + cosign sign --yes "${IMAGE}@$${DIGEST}" @echo "::endgroup::" diff --git a/components/wit/deps/componentized-services/package.wit b/components/wit/deps/componentized-services-0.0.5-dev/package.wit similarity index 99% rename from components/wit/deps/componentized-services/package.wit rename to components/wit/deps/componentized-services-0.0.5-dev/package.wit index c90c7fd..8dcc4e0 100644 --- a/components/wit/deps/componentized-services/package.wit +++ b/components/wit/deps/componentized-services-0.0.5-dev/package.wit @@ -1,4 +1,4 @@ -package componentized:services; +package componentized:services@0.0.5-dev; interface types { type service-id = string; diff --git a/components/wit/world.wit b/components/wit/world.wit index dd5f27a..b2a00af 100644 --- a/components/wit/world.wit +++ b/components/wit/world.wit @@ -1,18 +1,18 @@ package componentized:services-components; world filesystem-lifecycle { - include componentized:services/service-lifecycle; + include componentized:services/service-lifecycle@0.0.5-dev; } world valkey-lifecycle { - include componentized:services/service-lifecycle; + include componentized:services/service-lifecycle@0.0.5-dev; import componentized:valkey/store; } world credential-config { export wasi:config/store@0.2.0-rc.1; - import componentized:services/credential-store; + import componentized:services/credential-store@0.0.5-dev; include wasi:config/imports@0.2.0-rc.1; } @@ -21,14 +21,14 @@ world credential-config { world lifecycle-host-cli { export wasi:cli/run@0.2.6; - import componentized:services/lifecycle; + import componentized:services/lifecycle@0.0.5-dev; include wasi:logging/imports@0.1.0-draft; include wasi:cli/imports@0.2.6; } world lifecycle-host-http { - import componentized:services/lifecycle; + import componentized:services/lifecycle@0.0.5-dev; export wasi:http/incoming-handler@0.2.6; include wasi:logging/imports@0.1.0-draft; @@ -37,42 +37,42 @@ world lifecycle-host-http { // credential store implementations world filesystem-credential-store { - export componentized:services/credential-store; + export componentized:services/credential-store@0.0.5-dev; include wasi:config/imports@0.2.0-rc.1; include wasi:filesystem/imports@0.2.6; } world filesystem-credential-admin { - export componentized:services/credential-admin; + export componentized:services/credential-admin@0.0.5-dev; include wasi:config/imports@0.2.0-rc.1; include wasi:filesystem/imports@0.2.6; } world keyvalue-credential-store { - export componentized:services/credential-store; + export componentized:services/credential-store@0.0.5-dev; include wasi:config/imports@0.2.0-rc.1; include wasi:keyvalue/imports@0.2.0-draft2; } world keyvalue-credential-admin { - export componentized:services/credential-admin; + export componentized:services/credential-admin@0.0.5-dev; include wasi:config/imports@0.2.0-rc.1; include wasi:keyvalue/imports@0.2.0-draft2; } world webhook-credential-admin { - export componentized:services/credential-admin; + export componentized:services/credential-admin@0.0.5-dev; include wasi:http/imports@0.2.6; include wasi:config/imports@0.2.0-rc.1; include wasi:logging/imports@0.1.0-draft; } world webhook-credential-store { - export componentized:services/credential-store; + export componentized:services/credential-store@0.0.5-dev; include wasi:http/imports@0.2.6; include wasi:config/imports@0.2.0-rc.1; include wasi:logging/imports@0.1.0-draft; diff --git a/tests/cli.wac b/tests/cli.wac index 44ec32e..9b5e772 100644 --- a/tests/cli.wac +++ b/tests/cli.wac @@ -18,12 +18,12 @@ let ops = new componentized:ops { let static-config-factory = new componentized:static-config-factory {}; export new componentized:cli { - "componentized:services/credential-store": credential-store.credential-store, - "componentized:services/credential-admin": credential-admin.credential-admin, - "componentized:services/lifecycle": lifecycle.lifecycle, + credential-store: credential-store.credential-store, + credential-admin: credential-admin.credential-admin, + lifecycle: lifecycle.lifecycle, - "componentized:services-test-components/ops": ops.ops, - "componentized:config/factory": static-config-factory.factory, + ops: ops.ops, + factory: static-config-factory.factory, ... }.run; diff --git a/tests/host.wac b/tests/host.wac index 1167b3a..711434e 100644 --- a/tests/host.wac +++ b/tests/host.wac @@ -13,7 +13,7 @@ let lifecycle = new componentized:lifecycle { }; export new componentized:lifecycle-host { - "componentized:services/lifecycle": lifecycle.lifecycle, + lifecycle: lifecycle.lifecycle, logging: logging.logging, diff --git a/tests/wit/deps/componentized-services/package.wit b/tests/wit/deps/componentized-services-0.0.5-dev/package.wit similarity index 99% rename from tests/wit/deps/componentized-services/package.wit rename to tests/wit/deps/componentized-services-0.0.5-dev/package.wit index c90c7fd..8dcc4e0 100644 --- a/tests/wit/deps/componentized-services/package.wit +++ b/tests/wit/deps/componentized-services-0.0.5-dev/package.wit @@ -1,4 +1,4 @@ -package componentized:services; +package componentized:services@0.0.5-dev; interface types { type service-id = string; diff --git a/tests/wit/ops.wit b/tests/wit/ops.wit index a2b9e6d..fd34ab4 100644 --- a/tests/wit/ops.wit +++ b/tests/wit/ops.wit @@ -1,5 +1,5 @@ interface ops { - use componentized:services/types.{error}; + use componentized:services/types@0.0.5-dev.{error}; %list: func(path: string) -> result, error>; read: func(path: string) -> result, error>; diff --git a/tests/wit/world.wit b/tests/wit/world.wit index 9015617..7423149 100644 --- a/tests/wit/world.wit +++ b/tests/wit/world.wit @@ -1,16 +1,16 @@ package componentized:services-test-components; world stub-lifecycle { - include componentized:services/service-lifecycle; + include componentized:services/service-lifecycle@0.0.5-dev; } world stub-credential-store { - export componentized:services/credential-store; + export componentized:services/credential-store@0.0.5-dev; include wasi:logging/imports@0.1.0-draft; } world stub-credential-admin { - export componentized:services/credential-admin; + export componentized:services/credential-admin@0.0.5-dev; include wasi:logging/imports@0.1.0-draft; } @@ -23,10 +23,10 @@ world stub-client { } world cli { - import componentized:services/credential-admin; - import componentized:services/credential-store; - import componentized:services/lifecycle; - import componentized:services/types; + import componentized:services/credential-admin@0.0.5-dev; + import componentized:services/credential-store@0.0.5-dev; + import componentized:services/lifecycle@0.0.5-dev; + import componentized:services/types@0.0.5-dev; import ops; import componentized:config/factory; @@ -37,7 +37,7 @@ world cli { world lifecycle-router { import filesystem-lifecycle: interface { - use componentized:services/types.{service-instance-id, service-binding-id, request, scope, tier, error}; + use componentized:services/types@0.0.5-dev.{service-instance-id, service-binding-id, request, scope, tier, error}; provision: func(instance-id: service-instance-id, %type: string, tier: option, requests: option>) -> result<_, error>; update: func(instance-id: service-instance-id, tier: option, requests: option>) -> result<_, error>; @@ -47,7 +47,7 @@ world lifecycle-router { unbind: func(binding-id: service-binding-id, instance-id: service-instance-id) -> result<_, error>; } import keyvalue-lifecycle: interface { - use componentized:services/types.{service-instance-id, service-binding-id, request, scope, tier, error}; + use componentized:services/types@0.0.5-dev.{service-instance-id, service-binding-id, request, scope, tier, error}; provision: func(instance-id: service-instance-id, %type: string, tier: option, requests: option>) -> result<_, error>; update: func(instance-id: service-instance-id, tier: option, requests: option>) -> result<_, error>; @@ -56,15 +56,15 @@ world lifecycle-router { list-bindings: func(instance-id: service-instance-id) -> result, error>; unbind: func(binding-id: service-binding-id, instance-id: service-instance-id) -> result<_, error>; } - import componentized:services/credential-admin; - import componentized:services/credential-store; + import componentized:services/credential-admin@0.0.5-dev; + import componentized:services/credential-store@0.0.5-dev; - export componentized:services/lifecycle; + export componentized:services/lifecycle@0.0.5-dev; } world ops-router { import filesystem-ops: interface { - use componentized:services/types.{error}; + use componentized:services/types@0.0.5-dev.{error}; %list: func(path: string) -> result, error>; read: func(path: string) -> result, error>; @@ -73,7 +73,7 @@ world ops-router { delete: func(path: string) -> result<_, error>; } import keyvalue-ops: interface { - use componentized:services/types.{error}; + use componentized:services/types@0.0.5-dev.{error}; %list: func(path: string) -> result, error>; read: func(path: string) -> result, error>; diff --git a/wit/world.wit b/wit/world.wit index d0a64dd..91aae51 100644 --- a/wit/world.wit +++ b/wit/world.wit @@ -1,4 +1,4 @@ -package componentized:services; +package componentized:services@0.0.5-dev; world service-lifecycle { export lifecycle;