Skip to content

Commit 93f3ba8

Browse files
authored
Merge pull request #1 from chickenzord/feat/github-workflows
feat: github workflows
2 parents 9de5baa + 3623ff3 commit 93f3ba8

11 files changed

Lines changed: 310 additions & 7 deletions

File tree

.github/dependabot.yml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# To get started with Dependabot version updates, you'll need to specify which
2+
# package ecosystems to update and where the package manifests are located.
3+
# Please see the documentation for all configuration options:
4+
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
5+
6+
version: 2
7+
updates:
8+
- package-ecosystem: "gomod" # See documentation for possible values
9+
directory: "/" # Location of package manifests
10+
schedule:
11+
interval: "weekly"
12+
commit-message:
13+
prefix: build(deps)

.github/workflows/docker.yml

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
name: Docker
2+
3+
on:
4+
push:
5+
branches:
6+
- 'main'
7+
tags:
8+
- 'v*'
9+
pull_request:
10+
branches:
11+
- 'main'
12+
paths:
13+
- 'Dockerfile'
14+
- '.dockerignore'
15+
16+
env:
17+
REGISTRY: ghcr.io
18+
IMAGE_NAME: ${{ github.repository }}
19+
20+
jobs:
21+
docker:
22+
runs-on: ubuntu-latest
23+
steps:
24+
- name: Checkout
25+
uses: actions/checkout@v3
26+
27+
- name: Set up QEMU
28+
uses: docker/setup-qemu-action@v3
29+
30+
- name: Set up Docker Buildx
31+
uses: docker/setup-buildx-action@v3
32+
33+
- name: Docker meta
34+
id: meta
35+
uses: docker/metadata-action@v5
36+
with:
37+
images: |
38+
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
39+
tags: |
40+
type=ref,event=branch
41+
type=ref,event=pr
42+
type=semver,pattern={{version}}
43+
type=semver,pattern={{major}}.{{minor}}
44+
45+
- name: Login to Container Registry
46+
if: github.event_name != 'pull_request'
47+
uses: docker/login-action@v2
48+
with:
49+
registry: ${{ env.REGISTRY }}
50+
username: ${{ github.actor }}
51+
password: ${{ secrets.GITHUB_TOKEN }}
52+
53+
- name: Build and push
54+
uses: docker/build-push-action@v6
55+
with:
56+
context: .
57+
platforms: linux/amd64,linux/arm64
58+
push: ${{ github.event_name != 'pull_request' }}
59+
tags: ${{ steps.meta.outputs.tags }}
60+
labels: ${{ steps.meta.outputs.labels }}

.github/workflows/go.yml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
name: go
2+
3+
on:
4+
push:
5+
tags:
6+
- v*
7+
branches:
8+
- master
9+
- main
10+
pull_request:
11+
12+
permissions:
13+
contents: read
14+
pull-requests: read
15+
16+
jobs:
17+
test:
18+
runs-on: ubuntu-latest
19+
steps:
20+
- uses: actions/checkout@v3
21+
- uses: actions/setup-go@v5
22+
with:
23+
go-version: 1.24
24+
- name: Test
25+
run: go test -v ./...

.github/workflows/lint.yml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
name: lint
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
pull_request:
8+
9+
permissions:
10+
contents: read
11+
12+
jobs:
13+
14+
golangci-lint:
15+
name: golangci-lint
16+
runs-on: ubuntu-latest
17+
steps:
18+
- uses: actions/checkout@v5
19+
- uses: actions/setup-go@v5
20+
with:
21+
go-version: '1.24'
22+
cache: false
23+
- name: golangci-lint
24+
uses: golangci/golangci-lint-action@v8
25+
with:
26+
version: v2.4
27+
28+
conventional-commits:
29+
name: conventional-commits
30+
runs-on: ubuntu-latest
31+
steps:
32+
- uses: actions/checkout@v3
33+
- uses: webiny/action-conventional-commits@v1.3.0

.github/workflows/release.yml

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
name: release
2+
3+
on:
4+
push:
5+
tags:
6+
- 'v*'
7+
8+
permissions:
9+
contents: write
10+
# packages: write
11+
# issues: write
12+
13+
jobs:
14+
release:
15+
runs-on: ubuntu-latest
16+
steps:
17+
- uses: actions/checkout@v3
18+
with:
19+
fetch-depth: 0
20+
- run: git fetch --force --tags
21+
- uses: actions/setup-go@v4
22+
with:
23+
go-version: stable
24+
25+
- uses: goreleaser/goreleaser-action@v4
26+
with:
27+
distribution: goreleaser
28+
version: latest
29+
args: release --clean
30+
env:
31+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

.golangci.yml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
version: '2'
2+
linters:
3+
default: none
4+
enable:
5+
# defaults
6+
- errcheck
7+
- govet
8+
- ineffassign
9+
- staticcheck
10+
- unused
11+
# addons
12+
- gocyclo
13+
- revive
14+
- whitespace
15+
- wsl_v5
16+
settings:
17+
wsl_v5:
18+
allow-first-in-block: true
19+
allow-whole-block: false
20+
branch-max-lines: 2
21+
revive:
22+
rules:
23+
# this is not a library project
24+
- name: exported
25+
disabled: true

.goreleaser.yaml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
before:
2+
hooks:
3+
- go mod tidy
4+
- go generate ./...
5+
builds:
6+
- env:
7+
- CGO_ENABLED=0
8+
goos:
9+
- linux
10+
- windows
11+
- darwin
12+
flags:
13+
- -trimpath
14+
15+
archives:
16+
- format: tar.gz
17+
# this name template makes the OS and Arch compatible with the results of uname.
18+
name_template: >-
19+
{{ .ProjectName }}_
20+
{{- title .Os }}_
21+
{{- if eq .Arch "amd64" }}x86_64
22+
{{- else if eq .Arch "386" }}i386
23+
{{- else }}{{ .Arch }}{{ end }}
24+
{{- if .Arm }}v{{ .Arm }}{{ end }}
25+
# use zip for windows archives
26+
format_overrides:
27+
- goos: windows
28+
format: zip
29+
30+
checksum:
31+
name_template: 'checksums.txt'
32+
snapshot:
33+
name_template: "{{ incpatch .Version }}-next"
34+
changelog:
35+
sort: asc
36+
filters:
37+
exclude:
38+
- '^docs:'
39+
- '^test:'
40+
- '^ci:'
41+
- '^nit:'
42+
43+
# yaml-language-server: $schema=https://goreleaser.com/static/schema.json
44+
# vim: set ts=2 sw=2 tw=0 fo=cnqoj

cmd/linkding-mcp/main.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ func main() {
3131
switch mode {
3232
case "http":
3333
fmt.Printf("Starting Linkding-MCP HTTP server on %s\n", bindAddr)
34+
3435
if err := mcpServer.RunHTTP(ctx, bindAddr); err != nil {
3536
fmt.Fprintf(os.Stderr, "Error running MCP server: %v\n", err)
3637
os.Exit(1)

internal/server/mcp.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,15 @@ func (s *MCPServer) handleSearchBookmarks(ctx context.Context, req *mcpsdk.CallT
4949
result := fmt.Sprintf("Found %d bookmarks:\n\n", len(bookmarks.Results))
5050
for _, bookmark := range bookmarks.Results {
5151
result += fmt.Sprintf("• **%s**\n URL: %s\n", bookmark.Title, bookmark.URL)
52+
5253
if bookmark.Description != "" {
5354
result += fmt.Sprintf(" Description: %s\n", bookmark.Description)
5455
}
56+
5557
if len(bookmark.TagNames) > 0 {
5658
result += fmt.Sprintf(" Tags: %v\n", bookmark.TagNames)
5759
}
60+
5861
result += "\n"
5962
}
6063

@@ -100,9 +103,11 @@ func (s *MCPServer) handleCreateBookmark(ctx context.Context, req *mcpsdk.CallTo
100103

101104
result := fmt.Sprintf("✅ Bookmark created successfully!\n\n• **%s**\n URL: %s\n ID: %d",
102105
bookmark.Title, bookmark.URL, bookmark.ID)
106+
103107
if bookmark.Description != "" {
104108
result += fmt.Sprintf("\n Description: %s", bookmark.Description)
105109
}
110+
106111
if len(bookmark.TagNames) > 0 {
107112
result += fmt.Sprintf("\n Tags: %v", bookmark.TagNames)
108113
}
@@ -200,5 +205,6 @@ func NewMCP(linkdingURL, apiToken string) *MCPServer {
200205
}, s.handleGetTags)
201206

202207
s.mcpServer = mcpServer
208+
203209
return s
204210
}

internal/server/types.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package server
2+
3+
// GetTagsArgs defines the input structure for get_tags tool
4+
type GetTagsArgs struct {
5+
Limit int `json:"limit,omitempty" jsonschema:"description:Maximum number of tags to return,default:50"`
6+
}
7+
8+
// CreateBookmarkArgs defines the input structure for create_bookmark tool
9+
type CreateBookmarkArgs struct {
10+
URL string `json:"url" jsonschema:"description:URL to bookmark"`
11+
Title string `json:"title,omitempty" jsonschema:"description:Bookmark title"`
12+
Description string `json:"description,omitempty" jsonschema:"description:Bookmark description"`
13+
Tags []string `json:"tags,omitempty" jsonschema:"description:List of tags"`
14+
}
15+
16+
// SearchBookmarksArgs defines the input structure for search_bookmarks tool
17+
type SearchBookmarksArgs struct {
18+
Query string `json:"query,omitempty" jsonschema:"description:Search query"`
19+
Limit int `json:"limit,omitempty" jsonschema:"description:Maximum number of results,default:20"`
20+
}
21+
22+
// BookmarkResult defines the output structure for bookmark operations
23+
type BookmarkResult struct {
24+
ID int `json:"id"`
25+
URL string `json:"url"`
26+
Title string `json:"title"`
27+
Description string `json:"description,omitempty"`
28+
Tags []string `json:"tags,omitempty"`
29+
Success bool `json:"success"`
30+
Message string `json:"message,omitempty"`
31+
}
32+
33+
// TagResult defines the output structure for tag operations
34+
type TagResult struct {
35+
ID int `json:"id"`
36+
Name string `json:"name"`
37+
}

0 commit comments

Comments
 (0)