This is an automated email from the ASF dual-hosted git repository.

wusheng pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/skywalking-mcp.git


The following commit(s) were added to refs/heads/main by this push:
     new 06d14fc  build: implement the release  scripts (#31)
06d14fc is described below

commit 06d14fc521eb032ec1984efc94136749110818da
Author: Fine0830 <[email protected]>
AuthorDate: Mon Mar 16 13:15:22 2026 +0800

    build: implement the release  scripts (#31)
---
 .github/workflows/publish-binaries.yaml |  69 ++++++++++++
 .github/workflows/publish-docker.yaml   |  37 +++++--
 .gitignore                              |   1 +
 CHANGES.md                              |  17 +++
 Makefile                                |  76 +++++++++-----
 scripts/push-release.sh                 |  94 +++++++++++++++++
 scripts/release.sh                      | 181 ++++++++++++++++++++++++++++++++
 7 files changed, 441 insertions(+), 34 deletions(-)

diff --git a/.github/workflows/publish-binaries.yaml 
b/.github/workflows/publish-binaries.yaml
new file mode 100644
index 0000000..9402546
--- /dev/null
+++ b/.github/workflows/publish-binaries.yaml
@@ -0,0 +1,69 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+name: publish-binaries
+
+on:
+  release:
+    types:
+      - released
+
+jobs:
+  build:
+    if: github.repository == 'apache/skywalking-mcp'
+    runs-on: ubuntu-latest
+    permissions:
+      contents: write
+    strategy:
+      matrix:
+        include:
+          - goos: linux
+            goarch: amd64
+          - goos: linux
+            goarch: arm64
+          - goos: darwin
+            goarch: amd64
+          - goos: darwin
+            goarch: arm64
+    steps:
+      - uses: actions/checkout@v4
+      - name: Set up Go
+        uses: actions/setup-go@v5
+        with:
+          go-version: 1.25
+      - name: Build binary
+        env:
+          GOOS: ${{ matrix.goos }}
+          GOARCH: ${{ matrix.goarch }}
+          CGO_ENABLED: "0"
+          VERSION: ${{ github.event.release.tag_name }}
+          GIT_COMMIT: ${{ github.sha }}
+        run: |
+          BUILD_DATE=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
+          go build \
+            -ldflags "-X main.version=${VERSION} -X main.commit=${GIT_COMMIT} 
-X main.date=${BUILD_DATE}" \
+            -o bin/swmcp \
+            cmd/skywalking-mcp/main.go
+      - name: Create archive
+        env:
+          VERSION: ${{ github.event.release.tag_name }}
+        run: |
+          tar -czf swmcp-${VERSION}-${{ matrix.goos }}-${{ matrix.goarch 
}}.tar.gz -C bin swmcp
+      - name: Upload release asset
+        env:
+          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+          VERSION: ${{ github.event.release.tag_name }}
+        run: gh release upload "${VERSION}" swmcp-${VERSION}-${{ matrix.goos 
}}-${{ matrix.goarch }}.tar.gz
diff --git a/.github/workflows/publish-docker.yaml 
b/.github/workflows/publish-docker.yaml
index 283b2b6..f0a3c66 100644
--- a/.github/workflows/publish-docker.yaml
+++ b/.github/workflows/publish-docker.yaml
@@ -20,10 +20,13 @@ on:
   push:
     branches:
       - main
+  release:
+    types:
+      - released
 
 env:
   SKIP_TEST: true
-  HUB: ghcr.io/apache/skywalking-mcp
+  APP_NAME: skywalking-mcp
 
 jobs:
   build:
@@ -34,21 +37,37 @@ jobs:
       packages: write
     timeout-minutes: 30
     env:
-      VERSION: ${{ github.sha }}
-      APP_NAME: skywalking-mcp
+      VERSION: ${{ github.event_name == 'release' && 
github.event.release.tag_name || github.sha }}
+      PLATFORMS: linux/amd64,linux/arm64
+      HUB: ${{ github.event_name == 'release' && 'docker.io/apache' || 
'ghcr.io/apache' }}
     steps:
-      - uses: actions/checkout@v3
+      - uses: actions/checkout@v4
         with:
-          submodules: true
+          fetch-tags: true
       - name: Set up Go
         uses: actions/setup-go@v5
         with:
           go-version: 1.25
-      - name: Log in to the Container registry
+      - name: Build binary
+        run: make build
+      - name: Build docker image
+        run: |
+          make docker-build
+          docker image ls
+      - name: Log in to GHCR
         uses: docker/login-action@v3
+        if: github.event_name == 'push' && github.ref == 'refs/heads/main'
         with:
-          registry: ${{ env.HUB }}
+          registry: ghcr.io
           username: ${{ github.actor }}
           password: ${{ secrets.GITHUB_TOKEN }}
-      - name: Build and push docker images
-        run: make docker.push || make docker.push
+      - name: Log in to Docker Hub
+        uses: docker/login-action@v3
+        if: github.event_name == 'release'
+        with:
+          registry: docker.io
+          username: ${{ secrets.DOCKER_USERNAME }}
+          password: ${{ secrets.DOCKER_PASSWORD }}
+      - name: Push docker images
+        if: (github.event_name == 'push' && github.ref == 'refs/heads/main') 
|| github.event_name == 'release'
+        run: make docker-push
diff --git a/.gitignore b/.gitignore
index 4f34813..36d6006 100644
--- a/.gitignore
+++ b/.gitignore
@@ -42,3 +42,4 @@ inspector-config.json
 *.log
 .vscode/
 .claude/
+build/
diff --git a/CHANGES.md b/CHANGES.md
new file mode 100644
index 0000000..1d8c6e7
--- /dev/null
+++ b/CHANGES.md
@@ -0,0 +1,17 @@
+# Changes by Version
+
+Release Notes.
+
+## 0.1.0
+
+### Features
+
+* Initial release of the `swmcp` binary (SkyWalking MCP server).
+* Support for three MCP transport modes: `stdio`, `sse`, and `streamable`.
+* Integration with Apache SkyWalking OAP via GraphQL, including:
+  * Traces, logs, metrics, topology, alarms, and events query tools.
+  * MQE (Metrics Query Extension) tools using the OAP `/graphql` endpoint.
+* Prompt support for trace and log analysis and utility workflows.
+* Embedded documentation and dynamic metrics resources for MQE.
+* Makefile targets for build, lint, license checks, and Docker image creation.
+
diff --git a/Makefile b/Makefile
index c33b19f..1e5263d 100644
--- a/Makefile
+++ b/Makefile
@@ -24,47 +24,47 @@ MKDIR_P = mkdir -p
 GO_LINT = golangci-lint
 LICENSE_EYE = license-eye
 
-HUB ?= docker.io/apache
+HUB ?= ghcr.io/apache
 APP_NAME = skywalking-mcp
 
 .PHONY: all
 all: build ;
 
+.PHONY: help
+help: ## Show this help message.
+       @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = 
":.*?## "}; {printf "  %-25s %s\n", $$1, $$2}'
+
 .PHONY: build
 build: ## Build the binary.
        ${MKDIR_P} bin/
        CGO_ENABLED=0 go build -ldflags "\
-           -X ${VERSION_PATH}.version=${VERSION} \
+         -X ${VERSION_PATH}.version=${VERSION} \
                -X ${VERSION_PATH}.commit=${GIT_COMMIT} \
                -X ${VERSION_PATH}.date=${BUILD_DATE}" \
                -o bin/swmcp cmd/skywalking-mcp/main.go
 
-.PHONY: build-image
-build-image: ## Build the Docker image.
-       docker build -t skywalking-mcp:latest .
-
 $(GO_LINT):
        @$(GO_LINT) version > /dev/null 2>&1 || go install 
github.com/golangci/golangci-lint/cmd/[email protected]
 $(LICENSE_EYE):
        @$(LICENSE_EYE) --version > /dev/null 2>&1 || go install 
github.com/apache/skywalking-eyes/cmd/license-eye@latest
-       
-.PHONY: lint
-lint: $(GO_LINT)
+
+lint: $(GO_LINT) ## Run linter.
        $(GO_LINT) run -v --timeout 5m ./...
-.PHONY: fix-lint
-fix-lint: $(GO_LINT)
+
+fix-lint: $(GO_LINT) ## Auto-fix lint issues.
        $(GO_LINT) run -v --fix ./...
 
 .PHONY: license-header
-license-header: clean $(LICENSE_EYE)
+license-header: $(LICENSE_EYE)
        @$(LICENSE_EYE) header check
 
 .PHONY: fix-license-header
-fix-license-header: clean $(LICENSE_EYE)
+fix-license-header: $(LICENSE_EYE)
        @$(LICENSE_EYE) header fix
 
 .PHONY: dependency-license
-dependency-license: clean $(LICENSE_EYE)
+dependency-license: $(LICENSE_EYE)
+       @rm -rf ./dist/licenses
        @$(LICENSE_EYE) dependency resolve --summary ./dist/LICENSE.tpl 
--output ./dist/licenses || exit 1
        @if [ ! -z "`git diff -U0 ./dist`" ]; then \
                echo "LICENSE file is not updated correctly"; \
@@ -73,7 +73,7 @@ dependency-license: clean $(LICENSE_EYE)
        fi
 
 .PHONY: fix-dependency-license
-fix-dependency-license: clean $(LICENSE_EYE)
+fix-dependency-license: $(LICENSE_EYE)
        @$(LICENSE_EYE) dependency resolve --summary ./dist/LICENSE.tpl 
--output ./dist/licenses
 
 .PHONY: fix-license
@@ -87,20 +87,46 @@ clean:
        -rm -rf bin
        -rm -rf coverage.txt
        -rm -rf *.tgz
-       -rm -rf *.tgz
        -rm -rf *.asc
        -rm -rf *.sha512
-       @go mod tidy &> /dev/null
+
+.PHONY: build-image
+build-image: docker-build ## Build the Docker image.
+
+.PHONY: docker-build
+docker-build: ## Build the Docker image (local only).
+       docker build --build-arg VERSION=$(VERSION) . -t 
$(HUB)/$(APP_NAME):$(VERSION) -t $(HUB)/$(APP_NAME):latest
+
+.PHONY: docker-push
+docker-push: ## Push existing Docker images to the registry.
+       docker push $(HUB)/$(APP_NAME):$(VERSION)
+       docker push $(HUB)/$(APP_NAME):latest
 
 .PHONY: docker
-docker: PUSH_OR_LOAD = --load
-docker: PLATFORMS =
+docker: docker-build
 
 .PHONY: docker.push
-docker.push: PUSH_OR_LOAD = --push
-docker.push: PLATFORMS = --platform linux/386,linux/amd64,linux/arm64
+docker.push: docker-push
+
+## Release
+RELEASE_SCRIPTS := ./scripts/release.sh
+
+release-binary: release-source ## Package binary archive
+       ${RELEASE_SCRIPTS} -b
+
+release-source: ## Package source archive
+       ${RELEASE_SCRIPTS} -s
+
+release-sign: ## Sign artifacts
+       ${RELEASE_SCRIPTS} -k mcp
+
+release-assembly: release-binary release-sign ## Generate release package
+
+PUSH_RELEASE_SCRIPTS := ./scripts/push-release.sh
+release-push-candidate:
+       ${PUSH_RELEASE_SCRIPTS}
 
-docker docker.push:
-       docker buildx create --use --driver docker-container --name 
skywalking_mcp > /dev/null 2>&1 || true
-       docker buildx build $(PUSH_OR_LOAD) $(PLATFORMS) --build-arg 
VERSION=$(VERSION) . -t $(HUB)/$(APP_NAME):$(VERSION) -t 
$(HUB)/$(APP_NAME):latest
-       docker buildx rm skywalking_mcp
\ No newline at end of file
+.PHONY: lint fix-lint
+.PHONY: license-header fix-license-header dependency-license 
fix-dependency-license
+.PHONY: release-binary release-source release-sign release-assembly
+.PHONY: release-push-candidate
diff --git a/scripts/push-release.sh b/scripts/push-release.sh
new file mode 100755
index 0000000..15c9b70
--- /dev/null
+++ b/scripts/push-release.sh
@@ -0,0 +1,94 @@
+#!/usr/bin/env bash
+
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+set -ex
+
+if [ "$VERSION" == "" ]; then
+  echo "VERSION environment variable not found, Please setting the VERSION."
+  echo "For example: export VERSION=1.0.0"
+  exit 1
+fi
+
+VERSION=${VERSION}
+TAG_NAME=v${VERSION}
+PRODUCT_NAME="skywalking-mcp-${VERSION}"
+
+echo "Release version "${VERSION}
+echo "Source tag "${TAG_NAME}
+
+SCRIPTDIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
+ROOTDIR=${SCRIPTDIR}/..
+BUILDDIR=${ROOTDIR}/build
+
+pushd ${BUILDDIR}
+trap 'popd' EXIT
+
+rm -rf skywalking
+
+svn co https://dist.apache.org/repos/dist/dev/skywalking/
+mkdir -p skywalking/mcp/"$VERSION"
+cp ${PRODUCT_NAME}-*.tgz skywalking/mcp/"$VERSION"
+cp ${PRODUCT_NAME}-*.tgz.asc skywalking/mcp/"$VERSION"
+cp ${PRODUCT_NAME}-*.tgz.sha512 skywalking/mcp/"$VERSION"
+
+cd skywalking/mcp && svn add "$VERSION" && svn commit -m "Draft Apache 
SkyWalking MCP release $VERSION"
+cd "$VERSION"
+
+cat << EOF
+=========================================================================
+Subject: [VOTE] Release Apache SkyWalking MCP version $VERSION
+
+Content:
+
+Hi the SkyWalking Community:
+This is a call for vote to release Apache SkyWalking MCP version $VERSION.
+
+Release notes:
+
+ * https://github.com/apache/skywalking-mcp/blob/v$VERSION/CHANGES.md
+
+Release Candidate:
+
+ * https://dist.apache.org/repos/dist/dev/skywalking/mcp/$VERSION
+ * sha512 checksums
+   - $(cat ${PRODUCT_NAME}.tgz.sha512)
+
+Release Tag :
+
+ * (Git Tag) $TAG_NAME
+
+Release Commit Hash :
+
+ * https://github.com/apache/skywalking-mcp/tree/$(git rev-list -n 1 
"$TAG_NAME")
+
+Keys to verify the Release Candidate :
+
+ * https://dist.apache.org/repos/dist/release/skywalking/KEYS
+
+Guide to build the release from source :
+
+ * https://github.com/apache/skywalking-mcp/blob/v$VERSION/README.md
+
+Voting will start now and will remain open for at least 72 hours, all PMC 
members are required to give their votes.
+
+[ ] +1 Release this package.
+[ ] +0 No opinion.
+[ ] -1 Do not release this package because....
+
+Thanks.
+
+[1] 
https://github.com/apache/skywalking/blob/master/docs/en/guides/How-to-release.md#vote-check
+EOF
diff --git a/scripts/release.sh b/scripts/release.sh
new file mode 100755
index 0000000..f26bf2e
--- /dev/null
+++ b/scripts/release.sh
@@ -0,0 +1,181 @@
+#!/usr/bin/env bash
+
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+set -euo pipefail
+set -x
+
+SCRIPTDIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
+ROOTDIR=${SCRIPTDIR}/..
+BUILDDIR=${ROOTDIR}/build
+
+require_cmd() {
+    if ! command -v "$1" >/dev/null 2>&1; then
+        echo "Error: required command '$1' not found in PATH" >&2
+        exit 1
+    fi
+}
+
+resolve_release_version() {
+    # 1) Explicit environment override
+    if [ -n "${RELEASE_VERSION:-}" ]; then
+        echo "${RELEASE_VERSION}"
+        return 0
+    fi
+
+    # 2) Derive from Git tags when available
+    if command -v git >/dev/null 2>&1 && git rev-parse --is-inside-work-tree 
>/dev/null 2>&1; then
+        if latest_tag=$(git describe --tags "$(git rev-list --tags 
--max-count=1)" 2>/dev/null); then
+            echo "${latest_tag#v}"
+            return 0
+        fi
+
+        # 3) Fallback to dev-<short-commit> when no tags are present
+        if short_commit=$(git rev-parse --short HEAD 2>/dev/null); then
+            # Optional guard for CI: require a tag when STRICT_RELEASE_TAG=1
+            if [ "${STRICT_RELEASE_TAG:-0}" = "1" ]; then
+                echo "Error: STRICT_RELEASE_TAG=1 is set but no Git tag could 
be resolved for this commit." >&2
+                exit 1
+            fi
+            echo "dev-${short_commit}"
+            return 0
+        fi
+    fi
+
+    # 4) Last-resort fallback when Git is unavailable
+    if [ "${STRICT_RELEASE_TAG:-0}" = "1" ]; then
+        echo "Error: STRICT_RELEASE_TAG=1 is set but neither RELEASE_VERSION 
nor Git metadata are available." >&2
+        exit 1
+    fi
+
+    echo "dev-unknown"
+}
+
+RELEASE_VERSION=$(resolve_release_version)
+
+SOURCE_FILE_NAME=skywalking-mcp-${RELEASE_VERSION}-src.tgz
+SOURCE_FILE=${BUILDDIR}/${SOURCE_FILE_NAME}
+
+binary(){
+    require_cmd tar
+
+    if [ ! -f "${SOURCE_FILE}" ]; then
+        echo "Source archive ${SOURCE_FILE} does not exist. Run '${0} -s' 
first to assemble the source package." >&2
+        exit 1
+    fi
+
+    (
+        tmpdir=$(mktemp -d)
+        trap 'rm -rf "${tmpdir}"' EXIT
+
+        tar -xvf "${SOURCE_FILE}" -C "${tmpdir}"
+        cd "${tmpdir}"
+        make build
+
+        bindir=./build
+        mkdir -p "${bindir}/bin"
+        # Copy relevant files
+        cp -Rfv ./bin/* "${bindir}/bin"
+        cp -Rfv ./CHANGES.md "${bindir}"
+        cp -Rfv ./README.md "${bindir}"
+        cp -Rfv ./dist/* "${bindir}"
+        tar -czf "${BUILDDIR}/skywalking-mcp-${RELEASE_VERSION}.tgz" -C 
"${bindir}" .
+    )
+}
+
+source(){
+    require_cmd tar
+
+    (
+        tmpdir=$(mktemp -d)
+        trap 'rm -rf "${tmpdir}"' EXIT
+
+        rm -rf "${SOURCE_FILE}"
+        cd "${ROOTDIR}"
+        echo "RELEASE_VERSION=${RELEASE_VERSION}" > .env
+        tar \
+        --exclude=".DS_Store" \
+        --exclude=".github" \
+        --exclude=".gitignore" \
+        --exclude=".asf.yaml" \
+        --exclude=".idea" \
+        --exclude=".vscode" \
+        --exclude="bin" \
+        -czf "${tmpdir}/${SOURCE_FILE_NAME}" \
+        .
+
+        mkdir -p "${BUILDDIR}"
+        mv "${tmpdir}/${SOURCE_FILE_NAME}" "${BUILDDIR}"
+    )
+}
+
+sign(){
+    require_cmd gpg
+    require_cmd shasum
+
+    pushd "${BUILDDIR}" >/dev/null
+    trap 'popd >/dev/null' EXIT
+
+    gpg --batch --yes --armor --detach-sig 
"skywalking-mcp-${RELEASE_VERSION}.tgz"
+    shasum -a 512 "skywalking-mcp-${RELEASE_VERSION}.tgz" > 
"skywalking-mcp-${RELEASE_VERSION}.tgz.sha512"
+}
+
+parseCmdLine(){
+    if [ $# -eq 0 ]; then
+        echo "Exactly one argument required." >&2
+        usage
+    fi
+    while getopts  "bsk:vh" FLAG; do
+        case "${FLAG}" in
+            b) binary ;;
+            s) source ;;
+            k) sign "${OPTARG}" ;;
+            v) echo "Resolved RELEASE_VERSION=${RELEASE_VERSION}" ;;
+            h) usage ;;
+            \?) usage ;;
+        esac
+    done
+    return 0
+}
+
+usage() {
+cat <<EOF
+Usage:
+    ${0} -[bskvh]
+
+Parameters:
+    -b  Build and assemble the binary package
+    -s  Assemble the source package
+    -k  Sign the specified artifact type (currently 'mcp')
+    -v  Print the resolved RELEASE_VERSION and exit
+    -h  Show this help.
+EOF
+    exit 1
+}
+
+#
+# main
+#
+
+require_cmd git
+
+ret=0
+
+parseCmdLine "$@"
+ret=$?
+[ "${ret}" -ne 0 ] && exit "${ret}"
+echo "Done release ${RELEASE_VERSION} (exit ${ret})"

Reply via email to