This is an automated email from the ASF dual-hosted git repository.
SYaoJun pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-graphar.git
The following commit(s) were added to refs/heads/main by this push:
new 54601c9c chore(go): bootstrap Go SDK module and CI (#937)
54601c9c is described below
commit 54601c9c76f37b13b49e3a4bd413f1f3ae99afcd
Author: Zeki Liu <[email protected]>
AuthorDate: Thu Jul 23 19:42:50 2026 +0800
chore(go): bootstrap Go SDK module and CI (#937)
* chore(go): bootstrap module, CI, tooling and license config
Module skeleton: go.mod (go 1.23.0), Makefile (fmt/vet/lint/test/coverage/ci
+ license header check), golangci config, GitHub Actions (matrix 1.23 +
stable), // Go mapping in licenserc.toml, package doc and README.
* docs(go): describe scaffold-only scope and drop stale golangci note
---
.github/.licenserc.yaml | 1 +
.github/workflows/go.yaml | 129 ++++++++++++++++++++++++++++++++++++++++++++++
go/README.md | 93 +++++++++++++++++++++++++++++++++
go/graphar/.gitignore | 5 ++
go/graphar/.golangci.yml | 76 +++++++++++++++++++++++++++
go/graphar/Makefile | 128 +++++++++++++++++++++++++++++++++++++++++++++
go/graphar/doc.go | 29 +++++++++++
go/graphar/go.mod | 20 +++++++
go/graphar/go.sum | 0
licenserc.toml | 8 +++
10 files changed, 489 insertions(+)
diff --git a/.github/.licenserc.yaml b/.github/.licenserc.yaml
index 8086341f..0576024d 100644
--- a/.github/.licenserc.yaml
+++ b/.github/.licenserc.yaml
@@ -61,5 +61,6 @@ header:
- "**/*.json"
- "**/*.lock"
- "**/*.svg"
+ - "**/go.sum"
- cli/*.yml
- cli/*.toml
diff --git a/.github/workflows/go.yaml b/.github/workflows/go.yaml
new file mode 100644
index 00000000..b87a65aa
--- /dev/null
+++ b/.github/workflows/go.yaml
@@ -0,0 +1,129 @@
+# 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: GraphAr Go CI
+
+on:
+ push:
+ branches:
+ - "main"
+ paths:
+ - "go/**"
+ - ".github/workflows/go.yaml"
+ pull_request:
+ branches:
+ - "main"
+ paths:
+ - "go/**"
+ - ".github/workflows/go.yaml"
+
+concurrency:
+ group: ${{ github.workflow }}-${{ github.ref }}
+ cancel-in-progress: true
+
+env:
+ CI: true
+
+defaults:
+ run:
+ shell: bash
+ working-directory: go/graphar
+
+jobs:
+ build:
+ name: Ubuntu Go ${{ matrix.go }}
+ runs-on: ubuntu-24.04
+ if: ${{ github.event_name != 'pull_request' ||
!contains(github.event.pull_request.title, 'WIP') }}
+ strategy:
+ fail-fast: false
+ matrix:
+ # Lowest supported version (matches the go.mod floor) + latest stable.
+ go: ["1.23", "stable"]
+ env:
+ GAR_TEST_DATA: ${{ github.workspace }}/testing/
+
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ # Pull the testing/ submodule so the cross-language interop test
+ # (info.TestLoadAllFixtures) has real C++/Java/Rust fixtures to load.
+ submodules: true
+
+ - name: Set up Go
+ uses: actions/setup-go@v5
+ with:
+ go-version: ${{ matrix.go }}
+ cache-dependency-path: go/graphar/go.sum
+ check-latest: true
+
+ - name: Print Go version
+ run: go version
+
+ - name: Verify go.mod is tidy
+ run: |
+ go mod tidy
+ if ! git diff --quiet -- go.mod go.sum; then
+ echo "::error::go.mod / go.sum is not tidy. Run 'go mod tidy'
locally and commit the result." >&2
+ git --no-pager diff -- go.mod go.sum
+ exit 1
+ fi
+
+ - name: gofmt
+ run: make fmt-check
+
+ - name: go vet
+ run: make vet
+
+ - name: Build
+ run: go build ./...
+
+ - name: Test (race) + coverage
+ run: |
+ go test -race -covermode=atomic -coverprofile=coverage.out ./...
+ go tool cover -func=coverage.out | tail -n 1
+
+ - name: Coverage floor
+ run: make coverage-check COVER_OUT=coverage.out
+
+ - name: Upload coverage to Codecov
+ if: matrix.go == 'stable'
+ uses: codecov/codecov-action@v5
+ with:
+ token: ${{ secrets.CODECOV_TOKEN }}
+ files: go/graphar/coverage.out
+ flags: go
+ fail_ci_if_error: false
+
+ lint:
+ name: golangci-lint
+ runs-on: ubuntu-24.04
+ if: ${{ github.event_name != 'pull_request' ||
!contains(github.event.pull_request.title, 'WIP') }}
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Set up Go
+ uses: actions/setup-go@v5
+ with:
+ go-version: "stable"
+ cache-dependency-path: go/graphar/go.sum
+
+ - name: golangci-lint
+ uses: golangci/golangci-lint-action@v6
+ with:
+ version: v1.64.8
+ working-directory: go/graphar
+ args: --timeout=5m
diff --git a/go/README.md b/go/README.md
new file mode 100644
index 00000000..dfa73c3d
--- /dev/null
+++ b/go/README.md
@@ -0,0 +1,93 @@
+<!--
+ 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.
+-->
+
+# GraphAr Go SDK
+
+Pure-Go SDK for [Apache GraphAr](https://github.com/apache/incubator-graphar).
+The SDK reads and writes the same on-disk YAML schema as the C++, Java and
+Rust reference implementations, so a graph produced by any of them is
+loadable by any other.
+
+> Status: in development. This module currently ships the build and CI
+> scaffold only; the metadata layer (`types/`, `info/`) and the data layer
+> (`reader/`, `writer/`) are planned.
+
+## Install
+
+```bash
+go get github.com/apache/incubator-graphar/go/graphar
+```
+
+Requires Go 1.23 or newer.
+
+## Quick example
+
+The `info` package lands in the next stacked PR; the snippet below shows the
+intended API once it does.
+
+```go
+import (
+ "io/fs"
+ "os"
+
+ "github.com/apache/incubator-graphar/go/graphar/info"
+)
+
+func main() {
+ fsys := os.DirFS("/path/to/graph")
+ g, err := info.LoadGraphInfo(fsys, "modern_graph.graph.yml")
+ if err != nil {
+ panic(err)
+ }
+ if v, ok := g.Vertex("person"); ok {
+ for _, name := range v.PropertyGroups().Names() {
+ println(name)
+ }
+ }
+}
+```
+
+## Packages
+
+The module is currently a build/CI scaffold; the packages below are planned:
+
+| Package | What will live here |
+|---|---|
+| `graphar/types` | Primitive value types: `DataType`, `FileType`,
`AdjListType`, `Cardinality`, `InfoVersion`. No external dependencies. |
+| `graphar/info` | Graph metadata model — `Property`, `PropertyGroup`,
`VertexInfo`, `EdgeInfo`, `GraphInfo` — plus YAML load/save. Validates against
the cpp reference rules so files round-trip across SDKs. |
+
+## Development
+
+```bash
+cd go/graphar
+make ci # gofmt + vet + lint + race tests + coverage floor
+make coverage # produce coverage.out and print per-package coverage
+```
+
+Once the `info` package lands, a cross-language interop gate
+(`info.TestLoadAllFixtures`) will walk the [`testing/`](../testing) submodule
+for every `*.graph.yml` and verify it loads and round-trips through
+`MarshalGraphInfo`, skipping when the submodule is not initialised.
+
+## Reporting issues / proposing changes
+
+Open an issue at https://github.com/apache/incubator-graphar/issues. For
+larger changes (over 300–500 lines of diff), please start a discussion
+first as described in
+[CONTRIBUTING.md](../CONTRIBUTING.md).
diff --git a/go/graphar/.gitignore b/go/graphar/.gitignore
new file mode 100644
index 00000000..b5ad4031
--- /dev/null
+++ b/go/graphar/.gitignore
@@ -0,0 +1,5 @@
+coverage.out
+coverage.html
+*.test
+*.out
+.DS_Store
diff --git a/go/graphar/.golangci.yml b/go/graphar/.golangci.yml
new file mode 100644
index 00000000..f7fb848f
--- /dev/null
+++ b/go/graphar/.golangci.yml
@@ -0,0 +1,76 @@
+# 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.
+
+# golangci-lint configuration.
+
+run:
+ timeout: 5m
+ tests: true
+
+linters:
+ disable-all: true
+ enable:
+ - errcheck
+ - govet
+ - ineffassign
+ - staticcheck
+ - unused
+ - revive
+ - misspell
+ - gocritic
+ - unconvert
+ - prealloc
+ - gofmt
+ - goimports
+
+linters-settings:
+ goimports:
+ local-prefixes: github.com/apache/incubator-graphar/go/graphar
+
+ revive:
+ severity: warning
+ rules:
+ - name: exported
+ arguments:
+ - disableStutteringCheck
+ - name: package-comments
+ - name: var-naming
+ - name: error-return
+ - name: error-naming
+ - name: error-strings
+ - name: indent-error-flow
+ - name: superfluous-else
+ - name: blank-imports
+ - name: context-as-argument
+ - name: range-val-in-closure
+ - name: receiver-naming
+ - name: time-naming
+ - name: unexported-return
+
+ staticcheck:
+ checks:
+ - all
+
+ gocritic:
+ disabled-checks:
+ - hugeParam
+ - rangeValCopy
+
+issues:
+ max-issues-per-linter: 0
+ max-same-issues: 0
+ exclude-use-default: false
diff --git a/go/graphar/Makefile b/go/graphar/Makefile
new file mode 100644
index 00000000..1466631b
--- /dev/null
+++ b/go/graphar/Makefile
@@ -0,0 +1,128 @@
+# 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.
+
+# Coverage threshold per package (percent). CI fails below this floor.
+COVERAGE_MIN ?= 85
+
+GO ?= go
+GOFMT ?= gofmt
+GOIMPORTS ?= goimports
+COVER_OUT ?= coverage.out
+
+# Local import prefix for goimports grouping (see .golangci.yml).
+LOCAL_PREFIX := github.com/apache/incubator-graphar/go/graphar
+
+# License header check: the same tool the CI job uses (skywalking-eyes),
+# scoped to our Go files. REPO_ROOT is needed because the tool enumerates from
+# the git root.
+LICENSE_EYE ?= ghcr.io/apache/skywalking-eyes/license-eye:latest
+REPO_ROOT := $(shell git rev-parse --show-toplevel 2>/dev/null || echo
$(abspath $(CURDIR)/../..))
+
+.PHONY: help all fmt fmt-check vet lint test test-race coverage coverage-check
tidy clean ci license-check
+
+help:
+ @echo "Targets:"
+ @echo " fmt - run gofmt -w and goimports on all .go files"
+ @echo " fmt-check - fail if any file needs gofmt"
+ @echo " vet - run go vet ./..."
+ @echo " lint - run golangci-lint (must be installed)"
+ @echo " test - run go test ./... with race detector off"
+ @echo " test-race - run go test -race ./..."
+ @echo " coverage - produce $(COVER_OUT) with -race and print
per-package coverage"
+ @echo " coverage-check - fail if total coverage < COVERAGE_MIN
($(COVERAGE_MIN)%)"
+ @echo " tidy - go mod tidy"
+ @echo " license-check - check ASF headers on our Go files
(skywalking-eyes, docker)"
+ @echo " ci - fmt-check + vet + lint + coverage +
coverage-check"
+
+all: ci
+
+fmt:
+ $(GOFMT) -w .
+ @if command -v $(GOIMPORTS) >/dev/null 2>&1; then \
+ $(GOIMPORTS) -w -local $(LOCAL_PREFIX) .; \
+ else \
+ echo "$(GOIMPORTS) not installed; skipping import grouping"; \
+ echo " install: go install golang.org/x/tools/cmd/goimports@latest";
\
+ fi
+
+fmt-check:
+ @diff=$$($(GOFMT) -l .); \
+ if [ -n "$$diff" ]; then \
+ echo "gofmt needs to be run on the following files:"; \
+ echo "$$diff"; \
+ exit 1; \
+ fi
+
+vet:
+ $(GO) vet ./...
+
+# golangci-lint is optional locally; CI installs it explicitly.
+# Use --version probe rather than command -v: asdf shims pretend to exist
+# even when no version is selected, so command -v can give a false positive.
+lint:
+ @if golangci-lint --version >/dev/null 2>&1; then \
+ golangci-lint run ./...; \
+ else \
+ echo "golangci-lint not available locally; skipping (CI will run
it)"; \
+ fi
+
+test:
+ $(GO) test ./...
+
+test-race:
+ $(GO) test -race ./...
+
+coverage:
+ $(GO) test -race -coverprofile=$(COVER_OUT) -covermode=atomic ./...
+ @$(GO) tool cover -func=$(COVER_OUT) | tail -n 1
+
+# coverage-check enforces the COVERAGE_MIN floor on an existing profile. It
does
+# not depend on `coverage`: CI (and `make ci`) already produce a -race profile,
+# and regenerating here would both duplicate that run and overwrite the -race
+# profile with a plain one. Only a bare `make coverage-check` with no profile
on
+# disk builds one first.
+# When the profile has no executable statements yet (M0 bootstrap, before any
+# package ships testable code), the floor is skipped, a floor is for guarding
+# against regressions, not for blocking an empty repo. Statement count comes
+# from non-mode/non-summary lines in the profile file itself.
+coverage-check:
+ @test -f $(COVER_OUT) || $(MAKE) coverage
+ @stmts=$$(grep -cv -E '^(mode:|$$)' $(COVER_OUT) || true); \
+ if [ "$$stmts" -eq 0 ]; then \
+ echo "no executable statements yet; skipping coverage floor"; \
+ exit 0; \
+ fi; \
+ total=$$($(GO) tool cover -func=$(COVER_OUT) | tail -n 1 | awk '{print
$$3}' | tr -d '%'); \
+ awk -v t=$$total -v m=$(COVERAGE_MIN) 'BEGIN { if (t+0 < m+0) { printf
"coverage %.1f%% below minimum %s%%\n", t, m; exit 1 } else { printf "coverage
%.1f%% >= minimum %s%%\n", t, m } }'
+
+tidy:
+ $(GO) mod tidy
+
+# license-check runs the CI license tool (skywalking-eyes) over our Go files.
+# The authoritative whole-repo gate is the CI job (config
.github/.licenserc.yaml);
+# this checks the files we own, using the same tool so results agree.
+license-check:
+ @command -v docker >/dev/null 2>&1 || { echo "docker not found; needed
for license-check"; exit 1; }
+ @cfg=$$(mktemp) && trap 'rm -f "$$cfg"' EXIT; \
+ printf 'header:\n license:\n spdx-id: Apache-2.0\n
copyright-owner: Apache Software Foundation\n paths:\n -
"go/graphar/**/*.go"\n' > "$$cfg"; \
+ docker run --rm -v "$(REPO_ROOT):/w" -w /w -v "$$cfg:/lc.yaml" \
+ $(LICENSE_EYE) -c /lc.yaml header check
+
+clean:
+ rm -f $(COVER_OUT)
+
+ci: fmt-check vet lint coverage coverage-check
diff --git a/go/graphar/doc.go b/go/graphar/doc.go
new file mode 100644
index 00000000..85b3309a
--- /dev/null
+++ b/go/graphar/doc.go
@@ -0,0 +1,29 @@
+// 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.
+
+// Package graphar is the Go SDK for Apache GraphAr.
+//
+// This umbrella package only carries documentation. The module is currently
+// a build and CI scaffold; the functional sub-packages are planned:
+//
+// - types: primitive value types (DataType, FileType, AdjListType,
+// Cardinality, InfoVersion).
+// - info: graph metadata model (Property, PropertyGroup, VertexInfo,
+// EdgeInfo, GraphInfo) with YAML load/save and validation.
+// - reader/writer: chunked data access on top of Arrow, over an fs
+// filesystem abstraction.
+package graphar
diff --git a/go/graphar/go.mod b/go/graphar/go.mod
new file mode 100644
index 00000000..bcfbbba1
--- /dev/null
+++ b/go/graphar/go.mod
@@ -0,0 +1,20 @@
+// 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.
+
+module github.com/apache/incubator-graphar/go/graphar
+
+go 1.23.0
diff --git a/go/graphar/go.sum b/go/graphar/go.sum
new file mode 100644
index 00000000..e69de29b
diff --git a/licenserc.toml b/licenserc.toml
index 1e7fc418..0a7fbf0c 100644
--- a/licenserc.toml
+++ b/licenserc.toml
@@ -62,6 +62,14 @@ excludes = [
"**/*.json",
"**/*.lock",
"**/*.svg",
+ "**/go.sum",
"cli/*.yml",
"cli/*.toml",
]
+
+# Go uses // line comments for license headers by convention (matching
+# Apache Arrow Go, Apache Beam Go SDK, Kubernetes etc.). Without this
+# override hawkeye defaults *.go to JAVADOC_STYLE (/* ... */) and would
+# reject the canonical Go header form.
+[mapping.DOUBLESLASH_STYLE]
+extensions = ["go"]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]