Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
fail-fast: false
matrix:
runner-os: [windows-latest, ubuntu-latest, macos-latest]
language: [ csharp, actions ]
language: [csharp, actions]

runs-on: ${{ matrix.runner-os }}

Expand Down
101 changes: 101 additions & 0 deletions .github/workflows/go-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
name: Go CI

on:
push:
branches: [main]
pull_request:
branches:
- main
- o1/golang-port/*
workflow_dispatch:

permissions:
contents: read

jobs:
go-build-and-test:
name: Go Build and Test
strategy:
fail-fast: false
matrix:
runner-os: [windows-latest, ubuntu-latest, macos-latest]

runs-on: ${{ matrix.runner-os }}

steps:
- uses: actions/checkout@v6
with:
persist-credentials: false

- name: Setup Go
uses: actions/setup-go@v6
with:
go-version-file: go.mod
cache: true

- name: Setup Just
uses: extractions/setup-just@e33e0265a09d6d736e2ee1e0eb685ef1de4669ff # v3

- name: Check Go formatting
if: matrix.runner-os == 'ubuntu-latest'
run: |
if [ -n "$(gofmt -l .)" ]; then
echo "Go files need formatting:"
gofmt -l .
exit 1
fi

- name: Go Vet
run: go vet ./...

- name: Build Go binaries
run: just go-build

- name: Run Go tests
run: go test -v -race ./...
if: matrix.runner-os != 'ubuntu-latest'

- name: Run Go tests with coverage
run: go test -v -race -coverprofile=coverage.out ./...
if: matrix.runner-os == 'ubuntu-latest'

- name: Generate coverage report
if: matrix.runner-os == 'ubuntu-latest'
run: |
go tool cover -html=coverage.out -o coverage.html
go tool cover -func=coverage.out

- name: Upload coverage artifact
if: matrix.runner-os == 'ubuntu-latest'
uses: actions/upload-artifact@v6
with:
name: go-coverage-report
path: coverage.html

- name: Test binaries
run: |
./dist/gei --version
./dist/ado2gh --version
./dist/bbs2gh --version
Comment on lines +77 to +79
Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On Windows runners, the go build -o dist/gei ./cmd/gei output is typically dist/gei.exe, so invoking ./dist/gei --version will fail. Consider making this step OS-aware (use .exe on Windows) or derive the executable suffix from go env GOEXE.

Suggested change
./dist/gei --version
./dist/ado2gh --version
./dist/bbs2gh --version
goexe="$(go env GOEXE)"
./dist/gei${goexe} --version
./dist/ado2gh${goexe} --version
./dist/bbs2gh${goexe} --version

Copilot uses AI. Check for mistakes.
shell: bash

go-lint:
name: Go Lint
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v6
with:
persist-credentials: false

- name: Setup Go
uses: actions/setup-go@v6
with:
go-version-file: go.mod
cache: true

- name: golangci-lint
uses: golangci/golangci-lint-action@1e7e51e771db61008b38414a730f564565cf7c20 # v9.2.0
with:
version: latest
args: --timeout=5m
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -359,3 +359,9 @@ MigrationBackup/
/src/gei/Properties/launchSettings.json
/src/OctoshiftCLI.IntegrationTests/Properties/launchSettings.json
/src/ado2gh/Properties/launchSettings.json

# Go coverage reports
coverage/
*.out
coverage.html
/coverage.out
104 changes: 104 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# golangci-lint configuration for gh-gei Go port
# See https://golangci-lint.run/usage/configuration/
version: "2"

run:
timeout: 5m
tests: true
modules-download-mode: readonly

formatters:
enable:
- gofmt
- goimports
- gofumpt

linters:
enable:
- govet # Reports suspicious constructs
- errcheck # Checks for unchecked errors
- staticcheck # Static analysis (includes gosimple, stylecheck)
- unused # Checks for unused code
- ineffassign # Detects ineffectual assignments
- bodyclose # Checks for HTTP response body close
- noctx # Finds HTTP requests without context
- misspell # Finds commonly misspelled English words
- unconvert # Removes unnecessary type conversions
- goconst # Finds repeated strings that could be constants
- gocyclo # Computes cyclomatic complexities
- revive # Fast, configurable, extensible linter
- gosec # Security-focused linter
- errname # Checks error naming
- errorlint # Finds misuses of errors
- whitespace # Detects leading/trailing whitespace

settings:
gocyclo:
min-complexity: 15
goconst:
min-len: 3
min-occurrences: 3
misspell:
locale: US
revive:
rules:
- name: exported
severity: warning
disabled: false
- name: package-comments
severity: warning
disabled: false
gosec:
excludes:
- G104 # Audit errors not checked (too noisy)

exclusions:
presets:
- comments
- common-false-positives
- legacy
- std-error-handling
rules:
# Exclude some linters from running on tests files
- path: _test\.go
linters:
- gocyclo
- errcheck
- gosec
- revive
# Exclude error checks in main.go files (handled by cobra)
- path: cmd/.*/main\.go
text: "Error return value"
linters:
- errcheck
# Unused functions in skeleton main.go files will be wired up in future PRs
- path: cmd/.*/main\.go
linters:
- unused
# SA1029: context key type - will be replaced with proper type in later phases
- path: cmd/.*/main\.go
text: "SA1029"
linters:
- staticcheck
# G101 false positives on template constant names containing "Password", "Secret", etc.
- path: pkg/scriptgen/templates\.go
text: "G101"
linters:
- gosec
# Cyclomatic complexity for generate-script command will be addressed when refactoring
- path: cmd/gei/generate_script\.go
linters:
- gocyclo
# TLS InsecureSkipVerify is user-configurable for GHES with self-signed certs
- path: pkg/http/client\.go
text: "G402"
linters:
- gosec

output:
formats:
text:
path: stdout
colors: true
print-issued-lines: true
print-linter-name: true
Loading
Loading