Skip to content

Commit 26c6993

Browse files
committed
Initial Commit
0 parents  commit 26c6993

36 files changed

+2499
-0
lines changed

.github/CODEOWNERS

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# More info about codeowners in https://docs.github.com/es/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners
2+
# Each line is a file pattern followed by one or more owners.
3+
4+
# These owners will be the default owners for everything in
5+
# the repo. Unless a later match takes precedence,
6+
# they will be requested for
7+
# review when someone opens a pull request.
8+
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
name: Compile into binaries
2+
3+
on:
4+
release:
5+
types: [created]
6+
7+
workflow_dispatch:
8+
inputs:
9+
release:
10+
description: 'Release tag where to create the binaries (as SemVer vX.X.X)'
11+
required: true
12+
default: v0.1.0
13+
14+
permissions:
15+
contents: write
16+
packages: write
17+
18+
jobs:
19+
releases-matrix:
20+
name: Release Go Binary
21+
runs-on: ubuntu-latest
22+
strategy:
23+
matrix:
24+
# build and publish in parallel:
25+
# linux/386, linux/amd64, linux/arm64, darwin/amd64, darwin/arm64
26+
goos: [linux, darwin]
27+
goarch: ["386", amd64, arm64]
28+
exclude:
29+
- goos: darwin
30+
goarch: "386"
31+
32+
steps:
33+
- id: read_tag
34+
name: "Read release tag name (mostly vx.x.x)"
35+
run: |
36+
if [ "${{ github.event_name }}" = "release" ]; then
37+
export TAG="${{ github.ref_name }}"
38+
elif [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
39+
export TAG="${{ inputs.release }}"
40+
fi
41+
42+
echo "release_tag=${TAG}" >> "$GITHUB_OUTPUT"
43+
44+
- uses: actions/checkout@v3
45+
with:
46+
ref: ${{ steps.read_tag.outputs.release_tag }}
47+
48+
- name: "Read Go version from go.mod"
49+
id: read_go_version
50+
run: |
51+
go_version_raw=$(grep "^go " go.mod | awk '{print $2}')
52+
echo "go_version=${go_version_raw}" >> "$GITHUB_OUTPUT"
53+
54+
- uses: actions/setup-go@v5
55+
with:
56+
go-version: '${{ steps.read_go_version.outputs.go_version }}'
57+
58+
- name: "Build binary"
59+
id: build_binary
60+
run: |
61+
printf "GOOS: %s, GOARCH: %s\n" "${{ matrix.goos }}" "${{ matrix.goarch }}"
62+
63+
export GOOS=${{ matrix.goos }}
64+
export GOARCH=${{ matrix.goarch }}
65+
export VERSION=${{ steps.read_tag.outputs.release_tag }}
66+
67+
make build
68+
69+
- name: "Craft package and its signature"
70+
id: build_package
71+
run: |
72+
export GOOS=${{ matrix.goos }}
73+
export GOARCH=${{ matrix.goarch }}
74+
export PACKAGE_NAME=mcp-proxy-${{ steps.read_tag.outputs.release_tag }}-${{ matrix.goos }}-${{ matrix.goarch }}.tar.gz
75+
76+
make package
77+
make package-signature
78+
79+
echo "package_name=${PACKAGE_NAME}" >> "$GITHUB_OUTPUT"
80+
81+
- name: "Upload package to release"
82+
uses: svenstaro/upload-release-action@v2
83+
with:
84+
repo_token: ${{ secrets.GITHUB_TOKEN }}
85+
file: dist/${{ steps.build_package.outputs.package_name }}
86+
asset_name: ${{ steps.build_package.outputs.package_name }}
87+
tag: ${{ steps.read_tag.outputs.release_tag }}
88+
overwrite: true
89+
90+
- name: "Upload package signature to release"
91+
uses: svenstaro/upload-release-action@v2
92+
with:
93+
repo_token: ${{ secrets.GITHUB_TOKEN }}
94+
file: dist/${{ steps.build_package.outputs.package_name }}.md5
95+
asset_name: ${{ steps.build_package.outputs.package_name }}.md5
96+
tag: ${{ steps.read_tag.outputs.release_tag }}
97+
overwrite: true
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
name: Build Docker image
2+
3+
on:
4+
release:
5+
types: [created]
6+
7+
workflow_dispatch:
8+
inputs:
9+
release:
10+
description: 'Release tag where to create the binaries (as SemVer vX.X.X)'
11+
required: true
12+
default: v0.1.0
13+
14+
permissions:
15+
contents: write
16+
packages: write
17+
18+
jobs:
19+
build:
20+
runs-on: ubuntu-latest
21+
steps:
22+
- id: read_tag
23+
name: Read release tag name (mostly vx.x.x)
24+
run: |
25+
if [ "${{ github.event_name }}" = "release" ]; then
26+
export TAG="${{ github.ref_name }}"
27+
elif [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
28+
export TAG="${{ inputs.release }}"
29+
fi
30+
31+
echo "release_tag=${TAG}" >> "$GITHUB_OUTPUT"
32+
33+
- name: Checkout
34+
uses: actions/checkout@v4
35+
with:
36+
ref: ${{ steps.read_tag.outputs.release_tag }}
37+
38+
- name: Read Go version from go.mod
39+
id: read_go_version
40+
run: |
41+
go_version_raw=$(grep "^go " go.mod | awk '{print $2}')
42+
echo "go_version=${go_version_raw}" >> "$GITHUB_OUTPUT"
43+
44+
- name: Set up Go
45+
uses: actions/setup-go@v5
46+
with:
47+
go-version: '${{ steps.read_go_version.outputs.go_version }}'
48+
49+
- name: Set up QEMU
50+
id: qemu
51+
uses: docker/setup-qemu-action@v3
52+
with:
53+
image: tonistiigi/binfmt:latest
54+
platforms: all
55+
56+
- name: Set up Docker Buildx
57+
id: buildx
58+
uses: docker/setup-buildx-action@v3
59+
60+
- name: Docker Login
61+
uses: docker/login-action@v3
62+
with:
63+
registry: ghcr.io
64+
username: ${{ github.actor }}
65+
password: ${{ secrets.GITHUB_TOKEN }}
66+
67+
- id: build
68+
name: Build and push Docker images
69+
env:
70+
RELEASE_TAG: ${{ steps.read_tag.outputs.release_tag }}
71+
run: |
72+
export IMG="ghcr.io/$GITHUB_REPOSITORY:$RELEASE_TAG"
73+
74+
if grep -q '^docker-buildx:' Makefile; then
75+
make docker-buildx
76+
else
77+
make docker-build
78+
make docker-push
79+
fi
80+

.gitignore

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
.*
2+
!.gitignore
3+
!.github
4+
bin/*
5+
dist/*
6+
*.test
7+
*.out
8+
zz_generated.*
9+
*~
10+
*.cartero
11+
12+
# It makes no sense to store locally used DB file
13+
*.db
14+
__*
15+
16+
# Autogenerated Helm files
17+
chart/charts/**
18+
Chart.lock

Dockerfile

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Build the manager binary
2+
FROM golang:1.24 AS builder
3+
ARG TARGETOS
4+
ARG TARGETARCH
5+
6+
WORKDIR /workspace
7+
8+
# Copy the Go Modules manifests
9+
COPY ./go.mod go.mod
10+
COPY ./go.sum go.sum
11+
# cache deps before building and copying source so that we don't need to re-download as much
12+
# and so that source changes don't invalidate our downloaded layer
13+
14+
RUN go mod download
15+
16+
# Copy the go source
17+
COPY ./ .
18+
19+
# Build
20+
# the GOARCH has not a default value to allow the binary be built according to the host where the command
21+
# was called. For example, if we call make docker-build in a local env which has the Apple Silicon M1 SO
22+
# the docker BUILDPLATFORM arg will be linux/arm64 when for Apple x86 it will be linux/amd64. Therefore,
23+
# by leaving it empty we can ensure that the container and binary shipped on it will have the same platform.
24+
RUN CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -o mcp-proxy ./cmd
25+
26+
27+
# Use distroless as minimal base image to package the manager binary
28+
# Refer to https://github.com/GoogleContainerTools/distroless for more details
29+
FROM gcr.io/distroless/static:nonroot
30+
31+
WORKDIR /
32+
COPY --from=builder /workspace/mcp-proxy .
33+
USER 65532:65532
34+
35+
ENTRYPOINT ["/mcp-proxy"]

Makefile

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
2+
# Image URL to use all building/pushing image targets
3+
IMG ?= ghcr.io/achetronic/mcp-proxy:placeholder
4+
5+
# Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set)
6+
ifeq (,$(shell go env GOBIN))
7+
GOBIN=$(shell go env GOPATH)/bin
8+
else
9+
GOBIN=$(shell go env GOBIN)
10+
endif
11+
12+
# Get the current Go OS
13+
GO_OS ?= $(or $(GOOS),$(shell go env GOOS))
14+
# Get the current Go ARCH
15+
GO_ARCH ?= $(or $(GOARCH),$(shell go env GOARCH))
16+
17+
OS=$(shell uname | tr '[:upper:]' '[:lower:]')
18+
19+
# CONTAINER_TOOL defines the container tool to be used for building images.
20+
# Be aware that the target commands are only tested with Docker which is
21+
# scaffolded by default. However, you might want to replace it to use other
22+
# tools. (i.e. podman)
23+
CONTAINER_TOOL ?= docker
24+
25+
# Setting SHELL to bash allows bash commands to be executed by recipes.
26+
# Options are set to exit when a recipe line exits non-zero or a piped command fails.
27+
SHELL = /usr/bin/env bash -o pipefail
28+
.SHELLFLAGS = -ec
29+
30+
.PHONY: all
31+
all: build
32+
33+
##@ General
34+
35+
# The help target prints out all targets with their descriptions organized
36+
# beneath their categories. The categories are represented by '##@' and the
37+
# target descriptions by '##'. The awk command is responsible for reading the
38+
# entire set of makefiles included in this invocation, looking for lines of the
39+
# file as xyz: ## something, and then pretty-format the target and help. Then,
40+
# if there's a line with ##@ something, that gets pretty-printed as a category.
41+
# More info on the usage of ANSI control characters for terminal formatting:
42+
# https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_parameters
43+
# More info on the awk command:
44+
# http://linuxcommand.org/lc3_adv_awk.php
45+
46+
.PHONY: help
47+
help: ## Display this help.
48+
@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m<target>\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)
49+
50+
##@ Development
51+
52+
.PHONY: fmt
53+
fmt: ## Run go fmt against code.
54+
go fmt ./...
55+
56+
.PHONY: vet
57+
vet: ## Run go vet against code.
58+
go vet ./...
59+
60+
GOLANGCI_LINT = $(shell pwd)/bin/golangci-lint
61+
GOLANGCI_LINT_VERSION ?= v1.54.2
62+
golangci-lint:
63+
@[ -f $(GOLANGCI_LINT) ] || { \
64+
set -e ;\
65+
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(shell dirname $(GOLANGCI_LINT)) $(GOLANGCI_LINT_VERSION) ;\
66+
}
67+
68+
.PHONY: lint
69+
lint: golangci-lint ## Run golangci-lint linter & yamllint
70+
$(GOLANGCI_LINT) run
71+
72+
.PHONY: lint-fix
73+
lint-fix: golangci-lint ## Run golangci-lint linter and perform fixes
74+
$(GOLANGCI_LINT) run --fix
75+
76+
##@ Build
77+
.PHONY: swagger
78+
swagger: install-swag ## Build Swagger documents.
79+
$(SWAG) init --dir "./cmd/,." --outputTypes "go"
80+
81+
.PHONY: build
82+
build: fmt vet ## Build CLI binary.
83+
go build -o bin/mcp-proxy-$(GO_OS)-$(GO_ARCH) cmd/main.go
84+
85+
.PHONY: run
86+
run: fmt vet ## Run a controller from your host.
87+
go run ./cmd/ --config ./docs/config-http-stdio.yaml
88+
89+
# If you wish to build the manager image targeting other platforms you can use the --platform flag.
90+
# (i.e. docker build --platform linux/arm64). However, you must enable docker buildKit for it.
91+
# More info: https://docs.docker.com/develop/develop-images/build_enhancements/
92+
.PHONY: docker-build
93+
docker-build: ## Build docker image with the manager.
94+
$(CONTAINER_TOOL) build --no-cache -t ${IMG} .
95+
96+
.PHONY: docker-push
97+
docker-push: ## Push docker image with the manager.
98+
$(CONTAINER_TOOL) push ${IMG}
99+
100+
PACKAGE_NAME ?= package.tar.gz
101+
.PHONY: package
102+
package: ## Package binary.
103+
@printf "\nCreating package at dist/$(PACKAGE_NAME) \n"
104+
@mkdir -p dist
105+
106+
@if [ "$(OS)" = "linux" ]; then \
107+
tar --transform="s/mcp-proxy-$(GO_OS)-$(GO_ARCH)/mcp-proxy/" -cvzf dist/$(PACKAGE_NAME) -C bin mcp-proxy-$(GO_OS)-$(GO_ARCH) -C ../ LICENSE README.md; \
108+
elif [ "$(OS)" = "darwin" ]; then \
109+
tar -cvzf dist/$(PACKAGE_NAME) -s '/mcp-proxy-$(GO_OS)-$(GO_ARCH)/mcp-proxy/' -C bin mcp-proxy-$(GO_OS)-$(GO_ARCH) -C ../ LICENSE README.md; \
110+
else \
111+
echo "Unsupported OS: $(GO_OS)"; \
112+
exit 1; \
113+
fi
114+
115+
.PHONY: package-signature
116+
package-signature: ## Create a signature for the package.
117+
@printf "\nCreating package signature at dist/$(PACKAGE_NAME).md5 \n"
118+
md5sum dist/$(PACKAGE_NAME) | awk '{ print $$1 }' > dist/$(PACKAGE_NAME).md5

0 commit comments

Comments
 (0)