- 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, bindings/rust/Cargo.toml,
bindings/rust/Cargo.lock, bindings/java/pom.xml, bindings/kotlin/pom.xml,
bindings/dotnet/Scip.csproj, and docs/CLI.md, then land a commit with those
changes. The jvm-bindings workflow
fails the PR if the two pom.xml versions don't match cmd/scip/version.txt,
and the dotnet-bindings workflow
does the same for Scip.csproj.
After the commit is on main, trigger the
release workflow from the
Actions tab on GitHub, providing the version number (e.g. 0.7.0).
The workflow will validate version.txt, create and push tags, create a draft
GitHub release (with auto-generated notes), publish the Rust crate, publish the
Java/Kotlin bindings to Maven Central, publish the .NET bindings to NuGet,
build and upload CLI binaries, and finally mark the release as non-draft.
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.