Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
fdc097c
Exclude tests from CI for now.
haroonc Oct 20, 2025
6192303
Add tag for nightly release
haroonc Oct 20, 2025
47b513d
Add tag for nightly release
haroonc Oct 20, 2025
d8c1e92
Merge branch 'gemini-cli-extensions:main' into main
haroonc Oct 20, 2025
07a7bc2
fix conflict
haroonc Oct 20, 2025
b8efd7e
Update nightly-release.yml
haroonc Oct 20, 2025
9877b53
Update nightly-release.yml
haroonc Oct 20, 2025
1b0df59
need a reusable tag step
haroonc Oct 21, 2025
f078147
need a reusable tag step
haroonc Oct 21, 2025
e146539
need a reusable tag step
haroonc Oct 21, 2025
562995f
need a reusable tag step
haroonc Oct 21, 2025
6596975
need a reusable tag step
haroonc Oct 21, 2025
d38d765
need a reusable tag step
haroonc Oct 21, 2025
af1f0f3
updated call to prep
haroonc Oct 21, 2025
b187637
updated call to prep
haroonc Oct 21, 2025
ce92016
updated call to prep
haroonc Oct 21, 2025
b839dc7
updated call to prep
haroonc Oct 21, 2025
129a874
updated call to prep
haroonc Oct 21, 2025
09f7be9
updated call to prep
haroonc Oct 21, 2025
f066a18
updated call to prep
haroonc Oct 21, 2025
f9600a1
updated call to prep
haroonc Oct 22, 2025
e28a547
updated call to prep
haroonc Oct 22, 2025
10e28a3
updated call to prep
haroonc Oct 22, 2025
894ef58
Delete duplicate contributing
haroonc Oct 22, 2025
ad957e2
fix: wrapped results of tools that are arrays in an object
haroonc Oct 22, 2025
59e368e
fix: Added rag queries and tests
haroonc Oct 23, 2025
8e1f1e5
Merge branch 'main' into development
haroonc Oct 23, 2025
4bae301
Merge pull request #1 from haroonc/development
haroonc Oct 23, 2025
f5c0030
Merge pull request #2 from haroonc/main
haroonc Oct 23, 2025
ec29fe3
Added GitHub release, RAG generation and MCP tools
haroonc Oct 23, 2025
ff3684d
fix: resolved merge conflicts and test failures
haroonc Oct 23, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
139 changes: 85 additions & 54 deletions .github/workflows/nightly-release.yml
Original file line number Diff line number Diff line change
@@ -1,67 +1,98 @@
name: Nightly Release

on:
schedule:
- cron: '0 0 * * *' # Runs daily at midnight UTC
workflow_dispatch: # Allows manual triggering of the workflow
schedule:
- cron: "0 0 * * *" # Runs daily at midnight UTC
workflow_dispatch: # Allows manual triggering of the workflow

env:
RELEASE: nightly

jobs:
release:
runs-on: ubuntu-latest
defaults:
run:
working-directory: devops-mcp-server
strategy:
matrix:
goos: [linux, windows, darwin]
goarch: [amd64, arm64]
exclude:
- goos: windows
goarch: arm64
- goos: darwin
goarch: amd64

steps:
- uses: actions/checkout@v3

- name: prep-release
run: |
mkdir -p release
cp ../gemini-extension.json release/
cp ../README.md release/
cp ../local-rag/devops-rag.db release/

- name: Set up Go
uses: actions/setup-go@v3
prep-release:
uses: ./.github/workflows/prep-release.yaml
with:
go-version: '1.24'

- name: Run Go Vet
run: go vet ./...
release: nightly

- name: Run Go Fmt
run: go fmt ./...
release:
needs: prep-release
runs-on: ubuntu-latest
defaults:
run:
working-directory: devops-mcp-server
strategy:
matrix:
goos: [linux, windows, darwin]
goarch: [amd64, arm64]
exclude:
- goos: windows
goarch: arm64
- goos: darwin
goarch: amd64

- name: Run Go Tests
run: go test ./...
steps:
- uses: actions/checkout@v3

# - name: Install golangci-lint
# run: go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
- name: prep-release
run: |
mkdir -p release dist
cp ../gemini-extension.json release/
cp ../README.md release/
cp ../local-rag/devops-rag.db release/

# - name: Run golangci-lint
# run: golangci-lint run
- name: Set up Go
uses: actions/setup-go@v3
with:
go-version: "1.24"

- name: Build
run: |
export GOOS=${{ matrix.goos }}
export GOARCH=${{ matrix.goarch }}
go build -o "release/devops-mcp-server-${GOOS}-${GOARCH}"
- name: Run Go Vet
run: go vet ./...

- name: Create release assets
run: |
tar -czvf "release/devops-mcp-server-${{ matrix.goos }}-${{ matrix.goarch }}.tar.gz" -C release "devops-mcp-server-${{ matrix.goos }}-${{ matrix.goarch }}"
- name: Run Go Fmt
run: go fmt ./...

- name: Create GitHub Release
uses: softprops/action-gh-release@v1
with:
files: release/*.tar.gz
# - name: Run Go Tests
# run: go test ./...

# - name: Install golangci-lint
# run: go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest

# - name: Run golangci-lint
# run: golangci-lint run

- name: Build
run: |
export GOOS=${{ matrix.goos }}
export GOARCH=${{ matrix.goarch }}
go build -o "release/devops-mcp-server-${GOOS}-${GOARCH}"

- name: Create release assets
id: archive
run: |
archive="dist/devops-mcp-server-${{ matrix.goos }}-${{ matrix.goarch }}"
if [[ "matrix.goos" == "windows" ]];then
archive="${archive}.zip"
zip -J "${archive}" -C release .
else
archive="${archive}.tar.gz"
tar -czvf "${archive}" -C release .
fi
echo "Created ${archive}"
echo "ARCHIVE_NAME=${archive}" >> "$GITHUB_OUTPUT"

- name: Create release assets
id: test
run: |
pwd
ls dist/*
ls ${{ steps.archive.ARCHIVE_NAME }}

- name: UpUpload archive to GitHub Release
uses: softprops/action-gh-release@v1
with:
files: dist/*
overwrite_files: true
tag_name: ${{ env.RELEASE }}
fail_on_unmatched_files: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
54 changes: 54 additions & 0 deletions .github/workflows/prep-release.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
name: Prepare Release

on:
workflow_call:
inputs:
release:
required: true
type: string
default: dev
workflow_dispatch: # Allows manual triggering of the workflow

env:
RELEASE: dev
GH_TOKEN: ${{ github.token }}

jobs:
prep-release:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3

- name: Prepare for a new release
id: prep
run: |
export RELEASE="${{ env.RELEASE }}"
if [[ "${{ inputs.release }}" != "" ]]; then
echo "Updating to RELEASE to ${{ inputs.release }}"
RELEASE="${{ inputs.release }}"
fi
echo "RELEASE=${RELEASE}" >> "$GITHUB_OUTPUT"

echo "Preparing for \"${RELEASE}\" release"
git config --local user.email "[email protected]"
git config --local user.name "GitHub Action"
git tag -fa -m "${RELEASE} release" "${RELEASE}"
git push --force origin "${RELEASE}"

# check of a release already exists
if [[ $(gh release view "${RELEASE}" >/dev/null ) ]]; then
echo "CREATE_RELEASE=true" >> "$GITHUB_OUTPUT"
else
echo "CREATE_RELEASE=false" >> "$GITHUB_OUTPUT"
fi

- name: Create a GitHub Release
uses: softprops/action-gh-release@v1
if: ${{ steps.prep.CREATE_RELEASE }}
with:
name: ${{ steps.prep.RELEASE }}
tag: ${{ steps.prep.RELEASE }}

env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.venv/
dist/
.gemini
**/__pycache__/
**/*.pyc
Expand Down
65 changes: 65 additions & 0 deletions devops-mcp-server/auth/auth.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// Copyright 2024 Google LLC
//
// Licensed 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
//
// https://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.
package auth

import (
"context"
"fmt"

"cloud.google.com/go/auth"
"cloud.google.com/go/auth/credentials"
)

type Creds struct {
Token string
ProjectId string
}

func GetAuthToken(ctx context.Context) (Creds, error) {
// Use Application Default Credentials to get a TokenSource
scopes := []string{"https://www.googleapis.com/auth/cloud-platform"}
creds, err := credentials.DetectDefault(&credentials.DetectOptions{
Scopes: scopes,
})
if err != nil {
return Creds{}, fmt.Errorf("Failed to find default credentials: %w", err)
}

projectID, err := creds.ProjectID(ctx)
if err != nil {
return Creds{}, fmt.Errorf("Failed to get project ID: %w", err)
}
if projectID == "" {
//Try quota project
projectID, err = creds.QuotaProjectID(ctx)
if err != nil {
return Creds{}, fmt.Errorf("Failed to get project ID: %w", err)
}
if projectID == "" {
return Creds{}, fmt.Errorf(`
No Project ID found in Application Default Credentials.
This can happen if credentials are user-based or the project hasn't been explicitly set
e.g., via gcloud auth application-default set-quota-project.
Error:%v`, err)
}
}
// We need an access token
var token *auth.Token
token, err = creds.TokenProvider.Token(ctx)
if err != nil {
return Creds{}, fmt.Errorf("Failed to retrieve access token: %v", err)
}

return Creds{Token: token.Value, ProjectId: projectID}, nil
}
8 changes: 5 additions & 3 deletions devops-mcp-server/cloudbuild/cloudbuild.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ type ProjectsLocationsTriggersServiceWrapper struct {
*cloudbuild.ProjectsLocationsTriggersService
}

type ListResult[T any] struct {
Items []T `json:"items"`
}
type triggersCreateCallWrapper struct {
*cloudbuild.ProjectsLocationsTriggersCreateCall
}
Expand Down Expand Up @@ -90,7 +93,6 @@ func (w *ProjectsLocationsTriggersServiceWrapper) List(parent string) cloudbuild
return &triggersListCallWrapper{w.ProjectsLocationsTriggersService.List(parent)}
}


// ProjectsLocationsBuildsServiceWrapper wraps cloudbuild.ProjectsLocationsBuildsService
type ProjectsLocationsBuildsServiceWrapper struct {
*cloudbuild.ProjectsLocationsBuildsService
Expand Down Expand Up @@ -219,13 +221,13 @@ func (c *Client) RunTrigger(ctx context.Context, projectID, location, triggerID
}

// ListTriggers lists all Cloud Build triggers in a given location.
func (c *Client) ListTriggers(ctx context.Context, projectID, location string) ([]*cloudbuild.BuildTrigger, error) {
func (c *Client) ListTriggers(ctx context.Context, projectID, location string) (*ListResult[*cloudbuild.BuildTrigger], error) {
parent := fmt.Sprintf("projects/%s/locations/%s", projectID, location)
resp, err := c.triggersService.List(parent).Context(ctx).Do()
if err != nil {
return nil, fmt.Errorf("failed to list triggers: %v", err)
}
return resp.Triggers, nil
return &ListResult[*cloudbuild.BuildTrigger]{Items: resp.Triggers}, nil
}

// BuildContainer builds a container image using Cloud Build.
Expand Down
4 changes: 2 additions & 2 deletions devops-mcp-server/cloudbuild/cloudbuild_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -205,8 +205,8 @@ func TestListTriggers(t *testing.T) {
if err != nil {
t.Fatalf("ListTriggers() error = %v, want nil", err)
}
if len(triggers) != 2 {
t.Errorf("ListTriggers() got %d triggers, want 2", len(triggers))
if len(triggers.Items) != 2 {
t.Errorf("ListTriggers() got %d triggers, want 2", len(triggers.Items))
}
})

Expand Down
Loading
Loading