- Project structure
- Code generation
- Debugging
- Testing and adding new SCIP semantics
- Release a new version
- bindings/: Contains a mix of generated and hand-written
bindings for different languages.
- The TypeScript, Rust, Haskell, JVM and .NET bindings are auto-generated.
- The Go bindings include protoc-generated code as well as extra functionality. This is used by the CLI below as well as the Sourcegraph CLI.
- cmd/scip: CLI for SCIP.
- cmd/scip/tests/: Test data and packages for SCIP.
- reprolang/: A verbose, small language which consists of declarations, references, imports and other minor bits of functionality, which is used to test the SCIP CLI. The language is defined using a tree-sitter grammar. This functionality is not meant for use outside of this repository.
- docs/: Auto-generated documentation.
-
Regenerating definitions after changing the schema in scip.proto.
nix run .#proto-generateThe only dependency you need is Nix.
-
Regenerating snapshots after making changes to the CLI.
go test ./cmd/scip -update-snapshots -
Regenerating parser for Repro after editing its grammar.
cd reprolang ./generate-tree-sitter-parser.sh
Protobuf output can be inspected using scip print:
scip print /path/to/index.scip
This may be a bit verbose. The default Protobuf output is more compact,
and can be inspected using protoc:
protoc --decode=scip.Index -I /path/to/scip scip.proto < index.scip
There is also a lint subcommand which performs various well-formedness
checks on a SCIP index. It is meant primarily for people working on a SCIP indexer,
and is not recommended for use in other settings.
scip lint /path/to/index.scip
It is helpful to use reprolang to check the existing code navigation behavior or to design new code navigation behavior.
To do this, add a test file (and implement any new functionality) first. Then, regenerate the snapshots.
go test ./cmd/scip -update-snapshotsUpdate the version in cmd/scip/version.txt and all package manifests and
lockfiles under bindings/, as well as reprolang/package.json and
docs/CLI.md, then land a commit with those changes. CI validates that the
package versions match cmd/scip/version.txt.
When the commit reaches main, the change to cmd/scip/version.txt
automatically triggers the release workflow.
The workflow validates the version, creates and pushes tags, creates a draft
GitHub release (with auto-generated notes), publishes all language bindings,
builds and uploads CLI binaries, and finally marks the release as non-draft.
Manual dispatch re-runs the version currently on main; it does not accept a
version input.
The Java and Kotlin bindings are published to Maven Central under the
org.scip-code namespace via the
Sonatype Central Portal, driven by the
release profile in bindings/{java,kotlin}/pom.xml and the
publish-jvm-bindings job in the release workflow.
Required GitHub Actions secrets:
| Secret | Source |
|---|---|
MAVEN_USERNAME |
Token name from the Central Portal account page |
MAVEN_PASSWORD |
Token secret from the same page |
MAVEN_GPG_PRIVATE_KEY |
gpg --armor --export-secret-keys $KEYID of a passphrase-less primary signing key |
scip-kotlin-bindings depends on scip-java-bindings, so the Java
deploy uses <waitUntil>published</waitUntil> (~10–30 min) before the
Kotlin deploy runs. Publications are irreversible — bad releases are
fixed by bumping cmd/scip/version.txt.
The .NET bindings are published to nuget.org as the
Scip package by the publish-dotnet-bindings job in the release workflow,
which packs the project through nix develop so the SDK matches the
dotnet-bindings check.
The job authenticates with
trusted publishing
rather than a stored API key: it asks GitHub for an OIDC token
(permissions: id-token: write) and NuGet/login exchanges that token for an
API key that expires after an hour. Nothing long-lived has to be rotated, which
matters because nuget.org now caps manually created keys at 30 days.
On nuget.org, under your username → Trusted Publishing, add a policy:
| Field | Value |
|---|---|
| Policy owner | the user or organization that owns the Scip package |
| Repository owner | scip-code |
| Repository | scip |
| Workflow file | release.yaml (file name only, no .github/workflows/ path) |
| Environment | leave empty; the job uses no environment |
A policy covers every package its owner owns, so it works for the first
publication, which creates the Scip package id. Policies on private
repositories start out temporarily active for 7 days and become permanent on
the first successful publish, which is when nuget.org learns the GitHub
repository and owner IDs.
Required GitHub Actions secret:
| Secret | Source |
|---|---|
NUGET_USER |
The nuget.org username (profile name, not email) that owns the trust policy |
NuGet publications are irreversible (versions can be unlisted, not deleted), so
bad releases are fixed by bumping cmd/scip/version.txt.