Build and release tool for SPT client plugins
Project description
sptbuild
Build and release tool for SPT (Single Player Tarkov) client plugins. This tool provides a unified CLI for packaging, uploading, and releasing BepInEx plugins for SPT.
Features
- Package: Create zip packages for SPT plugins in the correct BepInEx structure
- File Bundling: Bundle additional files and directories with your plugin using
plugin.toml - Upload: Upload release packages to GitLab project uploads
- Release: Create GitLab releases with package registry integration (CI mode)
- Setup CI: Setup and manage NuGet reference packages for CI builds
Installation
From source (development)
git clone https://gitlab.com/flir063-spt/sptbuild.git
cd sptbuild
pip install -e .
From PyPI (when published)
pip install sptbuild
Configuration
sptbuild uses environment variables for configuration. Set these in your environment or in a .envrc file:
Required Variables
# Package information
export UPLOAD_PACKAGE_NAME="your.package.name"
export VERSION_SOURCE_FILE="Plugin.cs"
# GitLab configuration
export GITLAB_PROJECT_ID="your_project_id"
export GITLAB_USERNAME="your_username"
export GITLAB_PROJECT_NAME="your_project_name"
Authentication (Non-CI)
# Personal access token with 'api' scope
export GITLAB_SECRET_TOKEN="glpat-xxxxxxxxxxxxx"
CI Mode (Auto-configured in GitLab CI)
export CI_JOB_TOKEN="<auto-provided>"
export CI_API_V4_URL="<auto-provided>"
Usage
Package Command
Create a zip package for your SPT plugin:
sptbuild package
This will:
- Copy the compiled DLL from
bin/Release/net472/ - Bundle additional files/directories if
plugin.tomlexists (see File Bundling) - Create the correct BepInEx directory structure
- Generate a zip file in
bin/upload/
Prerequisites: Run dotnet build --configuration Release <your-project>.csproj first
File Bundling
You can bundle additional files and directories alongside your plugin DLL using a plugin.toml configuration file.
Creating plugin.toml
Generate an example configuration file:
# Create plugin.toml in current directory
sptbuild init-config
plugin.toml Format
The plugin.toml file tells sptbuild which additional files and directories to include in your plugin package:
[bundle]
# Individual files to include (relative to project root)
# These maintain their directory structure in the plugin folder
files = [
"README.md",
"LICENSE.txt",
"config/settings.json",
]
# Directories to include recursively
# All files within these directories will be copied
directories = [
"assets",
"localization",
]
# Optional: Custom file mappings for renaming or restructuring
[[bundle.custom]]
source = "docs/UserGuide.md"
destination = "GUIDE.md" # Renamed in the zip
[[bundle.custom]]
source = "configs/default.json"
destination = "config/default.json" # Placed in config subfolder instead of configs
Note: All paths are relative to your project root. All bundled files are placed in BepInEx/plugins/{YourPackageName}/ alongside your DLL.
Example Zip Structure
With the above configuration, your final zip will look like:
BepInEx/
plugins/
YourPlugin/
YourPlugin.dll # Your compiled plugin
README.md # From files list
LICENSE.txt # From files list
config/
settings.json # From files list
default.json # From custom mapping
assets/ # From directories list
icon.png
banner.png
localization/ # From directories list
en.json
fr.json
GUIDE.md # From custom mapping (renamed)
Important Notes
plugin.tomlis optional - if it doesn't exist, only the DLL is bundled- Build will fail if any specified file or directory doesn't exist
- Files not listed in
plugin.tomlare not included in the package
Upload Command
Upload your package to GitLab project uploads:
# Upload only
sptbuild upload
# Upload and create a release
sptbuild upload --release
# or
sptbuild upload -r
The release notes are automatically extracted from CHANGELOG.md based on the current version.
Release Command (CI Mode)
Create a GitLab release with package registry integration. This is designed for CI environments:
sptbuild release
This will:
- Upload the package to GitLab Package Registry
- Create a GitLab release with the package link
- Extract release notes from
CHANGELOG.md
Setup CI Command
Setup and manage NuGet reference packages for CI builds:
# Build package only
sptbuild setup-ci myproject.csproj
# Build and upload to GitLab
sptbuild setup-ci myproject.csproj --upload
# or
sptbuild setup-ci myproject.csproj -u
# Build, upload, and update csproj with new version
sptbuild setup-ci myproject.csproj -u -m
This command:
- Parses your
.csprojfor reference assemblies - Copies DLLs to a
refs/directory - Creates a NuGet package with all references
- Optionally uploads to GitLab Package Registry
- Optionally updates your
.csprojwith the new version
Example Workflow
Local Development
# 1. (Optional) Create plugin.toml to bundle additional files
sptbuild init-config
# Edit plugin.toml to specify which files to bundle
# 2. Build your plugin (specify the main project .csproj)
dotnet build --configuration Release yourproject.csproj
# 3. Package it
sptbuild package
# 4. Upload to GitLab and create a release
sptbuild upload --release
CI/CD Pipeline
Example .gitlab-ci.yml:
stages:
- build
- package
- release
build:
stage: build
script:
- dotnet restore yourproject.csproj
- dotnet build --configuration Release yourproject.csproj
package:
stage: package
script:
- sptbuild package
artifacts:
paths:
- bin/upload/*.zip
release:
stage: release
script:
- sptbuild release
only:
- tags
Note: When you have multiple .csproj files in your directory (e.g., yourproject.csproj and ReferencePackage.csproj), you must specify which one to build in the dotnet build command.
Setting Up CI References
# 1. Create reference package
sptbuild setup-ci myproject.csproj -u
# 2. Update your .csproj to use it
# Add to your .csproj:
<PackageReference Include="YourProject.SPT.References" Version="1.0.0" />
# 3. Configure nuget.config for CI
# Create nuget.config with:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<add key="gitlab" value="https://gitlab.com/api/v4/projects/%CI_PROJECT_ID%/packages/nuget/index.json" />
</packageSources>
</configuration>
Version Detection
sptbuild automatically detects the version from your source file (specified by VERSION_SOURCE_FILE). It looks for:
public const string Version = "1.0.0";
Changelog Integration
Release notes are automatically extracted from CHANGELOG.md. The expected format is:
## [1.0.0] - 2024-01-15
### Features
- New feature description
### Bug Fixes
- Bug fix description
We recommend using towncrier to manage changelogs.
Environment Setup Example
Create a .envrc file in your project root:
# Git configuration
export GIT_SSH_COMMAND='ssh -i ~/.ssh/id_ed25519 -o IdentitiesOnly=yes'
export GIT_COMMITTER_NAME="Your Name"
export GIT_COMMITTER_EMAIL="your.email@example.com"
# GitLab configuration
export GITLAB_SECRET_TOKEN="glpat-xxxxxxxxxxxxx"
export GITLAB_PROJECT_ID="12345678"
export GITLAB_USERNAME="your-username"
export GITLAB_PROJECT_NAME="your-project"
# Package configuration
export UPLOAD_PACKAGE_NAME="your.package.name"
export VERSION_SOURCE_FILE="Plugin.cs"
Then use direnv to automatically load these variables:
direnv allow
Requirements
- Python >= 3.8
- requests >= 2.31.0
- semver >= 3.0.0
- tomli >= 2.0.0 (for Python < 3.11)
Optional Dependencies
For development and changelog management:
pip install sptbuild[dev]
This includes:
- towncrier >= 23.11.0
- pytest >= 7.0.0
License
MIT
Development
This project uses Task for common development tasks.
Available Tasks
# Build the package
task build
# Run tests
task test
# Run tests with coverage
task test:coverage
# Clean build artifacts
task clean
# Clean all artifacts (build + test)
task clean:all
# Install in development mode
task install:dev
# Lint code
task lint
# Release to PyPI (requires build first)
task release
Quick Start for Contributors
# 1. Clone the repository
git clone <repository-url>
cd sptbuild
# 2. Install in development mode
task install:dev
# 3. Make your changes
# 4. Run tests
task test
# 5. Build the package
task build
Continuous Integration
This project uses GitLab CI/CD for automated testing and deployment.
CI Pipeline Stages
-
Test Stage
- Runs tests on Python 3.8, 3.9, 3.10, 3.11, and 3.12
- Generates coverage reports (text, XML, HTML)
- Coverage metrics are tracked over time in GitLab
- Lints code for syntax errors
-
Build Stage
- Creates distribution packages (source + wheel)
- Validates packages with twine
- Artifacts stored for 90 days
-
Deploy Stage
- Automatic deployment to PyPI (on tags)
Coverage Reporting
The CI pipeline generates coverage reports in multiple formats:
- Terminal output: Displayed in job logs
- XML (Cobertura): Used by GitLab for coverage tracking
- HTML: Viewable as job artifacts for detailed analysis
Coverage trends are tracked in GitLab's Analytics > Repository > Code Coverage.
Running CI Locally
You can simulate CI jobs locally using Task:
# Run the same tests as CI
task test:coverage
# Lint like CI
task lint
# Build packages like CI
task build
Setting Up Trusted Publishing for PyPI
This project uses PyPI's Trusted Publishers feature for secure, passwordless deployment.
Prerequisites:
- Project must exist on PyPI (create initial release manually first)
- GitLab project must be hosted on gitlab.com
Setup Steps:
-
On PyPI (https://pypi.org/manage/project/sptbuild/settings/publishing/):
- Go to your project settings → Publishing
- Click "Add a new publisher"
- Select "GitLab CI/CD"
- Fill in:
- Owner: Your GitLab username or organization
- Repository name:
sptbuild - Environment name:
production/pypi - Workflow filename: Leave empty (uses default)
- Save the publisher
-
Verify GitLab Settings:
- Go to Settings → CI/CD → Variables
- Ensure "ID tokens" feature is enabled (automatic in modern GitLab)
- No manual tokens/passwords needed!
How It Works:
- GitLab generates OIDC tokens during deployment jobs
- PyPI verifies the token matches the configured publisher
- No secrets to manage or rotate
- More secure than API tokens
For more information, see:
Contributing
Contributions are welcome! Please feel free to submit issues or pull requests.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file sptbuild-0.1.3.tar.gz.
File metadata
- Download URL: sptbuild-0.1.3.tar.gz
- Upload date:
- Size: 30.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
65f9b372fafc64a590a7593d63f906ec6ff6ad264c304f3df31e12fe87554088
|
|
| MD5 |
d6696aa9a27cc37f575567dd8195d39f
|
|
| BLAKE2b-256 |
bf8196395781f8fbcb87eaaf08950d358df85a4a40b1f67ab76bec18898c844b
|
File details
Details for the file sptbuild-0.1.3-py3-none-any.whl.
File metadata
- Download URL: sptbuild-0.1.3-py3-none-any.whl
- Upload date:
- Size: 27.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
07578ae1c9921a737a8988459bd05d2ef6d7b3bcfbf31c17e1028bc1d4efc4b2
|
|
| MD5 |
43b26ba7e0e0dd62fea15efb7349ac24
|
|
| BLAKE2b-256 |
f497bc2ba8c459ed6426737d2db514471abfc33b07e9bb96861e91ae486a0f29
|