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})"