Dagger
Search

tapes

Package main provides reproducible builds and tests locally and in GitHub actions.
It is the main harness for handling nearly all dev operations.

Installation

dagger install github.com/papercomputeco/tapes@8bc0390d275829f3bba8f0eb051f12f3bc9f1c06

Entrypoint

Return Type
Tapes !
Arguments
NameTypeDefault ValueDescription
sourceDirectory -Project source directory.
Example
dagger -m github.com/papercomputeco/tapes@8bc0390d275829f3bba8f0eb051f12f3bc9f1c06 call \
func (m *MyModule) Example() *dagger.Tapes  {
	return dag.
			Tapes()
}
@function
def example() -> dagger.Tapes:
	return (
		dag.tapes()
	)
@func()
example(): Tapes {
	return dag
		.tapes()
}

Types

Tapes 🔗

Tapes is the main module for the Tapes CI/CD pipeline

build() 🔗

Build and return directory of go binaries for all platforms.

Return Type
Directory !
Arguments
NameTypeDefault ValueDescription
ldflagsString "-s -w"

Linker flags for go build

Example
dagger -m github.com/papercomputeco/tapes@8bc0390d275829f3bba8f0eb051f12f3bc9f1c06 call \
 build
func (m *MyModule) Example() *dagger.Directory  {
	return dag.
			Tapes().
			Build()
}
@function
def example() -> dagger.Directory:
	return (
		dag.tapes()
		.build()
	)
@func()
example(): Directory {
	return dag
		.tapes()
		.build()
}

buildExtprocImage() 🔗

BuildExtprocImage builds the local-platform tapes-extproc container image.

A second Dockerfile rather than a second stage in the first one: the two binaries ship on different base images (extproc on distroless nonroot, whose uid is part of its deployed contract) and are released independently.

Return Type
Container !
Arguments
NameTypeDefault ValueDescription
versionString !-

Version string for ldflags

commitString !-

Git commit SHA for ldflags

Example
dagger -m github.com/papercomputeco/tapes@8bc0390d275829f3bba8f0eb051f12f3bc9f1c06 call \
 build-extproc-image --version string --commit string
func (m *MyModule) Example(version string, commit string) *dagger.Container  {
	return dag.
			Tapes().
			Buildextprocimage(version, commit)
}
@function
def example(version: str, commit: str) -> dagger.Container:
	return (
		dag.tapes()
		.buildextprocimage(version, commit)
	)
@func()
example(version: string, commit: string): Container {
	return dag
		.tapes()
		.buildExtprocImage(version, commit)
}

buildPushExtprocImages() 🔗

BuildPushExtprocImages builds a multi-arch tapes-extproc image and publishes it to the provided registry.

Image naming convention: /tapes-extproc:

Return Type
[String ! ] !
Arguments
NameTypeDefault ValueDescription
registryString !-

Container registry address (e.g., “123456789.dkr.ecr.us-east-1.amazonaws.com”)

tags[String ! ] !-

Image tags to apply (e.g., [“v1.0.0”, “latest”])

versionString !-

Version string for ldflags

commitString !-

Git commit SHA for ldflags

Example
dagger -m github.com/papercomputeco/tapes@8bc0390d275829f3bba8f0eb051f12f3bc9f1c06 call \
 build-push-extproc-images --registry string --tags string1 --tags string2 --version string --commit string
func (m *MyModule) Example(ctx context.Context, registry string, tags []string, version string, commit string) []string  {
	return dag.
			Tapes().
			Buildpushextprocimages(ctx, registry, tags, version, commit)
}
@function
async def example(registry: str, tags: List[str], version: str, commit: str) -> List[str]:
	return await (
		dag.tapes()
		.buildpushextprocimages(registry, tags, version, commit)
	)
@func()
async example(registry: string, tags: string[], version: string, commit: string): Promise<string[]> {
	return dag
		.tapes()
		.buildPushExtprocImages(registry, tags, version, commit)
}

buildPushTapesImages() 🔗

BuildPushTapesImage builds a multi-arch image for tapes and publishes to the provided registry.

Image naming convention: /tapes:

Return Type
[String ! ] !
Arguments
NameTypeDefault ValueDescription
registryString !-

Container registry address (e.g., “123456789.dkr.ecr.us-east-1.amazonaws.com”)

tags[String ! ] !-

Image tags to apply (e.g., [“v1.0.0”, “latest”])

versionString !-

Version string for ldflags

commitString !-

Git commit SHA for ldflags

postHogPublicKeyString -

PostHog telemetry public API key (write-only). Empty disables telemetry.

Example
dagger -m github.com/papercomputeco/tapes@8bc0390d275829f3bba8f0eb051f12f3bc9f1c06 call \
 build-push-tapes-images --registry string --tags string1 --tags string2 --version string --commit string
func (m *MyModule) Example(ctx context.Context, registry string, tags []string, version string, commit string) []string  {
	return dag.
			Tapes().
			Buildpushtapesimages(ctx, registry, tags, version, commit)
}
@function
async def example(registry: str, tags: List[str], version: str, commit: str) -> List[str]:
	return await (
		dag.tapes()
		.buildpushtapesimages(registry, tags, version, commit)
	)
@func()
async example(registry: string, tags: string[], version: string, commit: string): Promise<string[]> {
	return dag
		.tapes()
		.buildPushTapesImages(registry, tags, version, commit)
}

buildRelease() 🔗

BuildRelease compiles versioned release binaries with embedded version info

Return Type
Directory !
Arguments
NameTypeDefault ValueDescription
versionString !-

Version string of build

commitString !-

Git commit SHA of build

postHogPublicKeyString -

PostHog telemetry public API key (write-only). Empty disables telemetry.

postHogEndpointString -

PostHog ingestion endpoint

Example
dagger -m github.com/papercomputeco/tapes@8bc0390d275829f3bba8f0eb051f12f3bc9f1c06 call \
 build-release --version string --commit string
func (m *MyModule) Example(version string, commit string) *dagger.Directory  {
	return dag.
			Tapes().
			Buildrelease(version, commit)
}
@function
def example(version: str, commit: str) -> dagger.Directory:
	return (
		dag.tapes()
		.buildrelease(version, commit)
	)
@func()
example(version: string, commit: string): Directory {
	return dag
		.tapes()
		.buildRelease(version, commit)
}

buildTapesImage() 🔗

BuildTapesImage builds the local-platform tapes container image from the repository Dockerfile.

Return Type
Container !
Arguments
NameTypeDefault ValueDescription
versionString !-

Version string for ldflags

commitString !-

Git commit SHA for ldflags

postHogPublicKeyString -

PostHog telemetry public API key (write-only). Empty disables telemetry.

Example
dagger -m github.com/papercomputeco/tapes@8bc0390d275829f3bba8f0eb051f12f3bc9f1c06 call \
 build-tapes-image --version string --commit string
func (m *MyModule) Example(version string, commit string) *dagger.Container  {
	return dag.
			Tapes().
			Buildtapesimage(version, commit)
}
@function
def example(version: str, commit: str) -> dagger.Container:
	return (
		dag.tapes()
		.buildtapesimage(version, commit)
	)
@func()
example(version: string, commit: string): Container {
	return dag
		.tapes()
		.buildTapesImage(version, commit)
}

checkExtproc() 🔗

CheckExtproc runs the ext_proc adapter’s test suite.

It is separate from Test, and bound to no database, because none of these tests need one — extproc talks to ingest over HTTP and is tested against fixtures. That is what makes it affordable on every PR, which matters: Test binds Postgres and for that reason does not run on the PR path, so folding extproc’s tests into it would have quietly retired the gate that used to run on every extproc change. This keeps that gate, including the wire-capture fidelity tests, which read the committed recordings and therefore always run rather than skipping.

Return Type
String !
Example
dagger -m github.com/papercomputeco/tapes@8bc0390d275829f3bba8f0eb051f12f3bc9f1c06 call \
 check-extproc
func (m *MyModule) Example(ctx context.Context) string  {
	return dag.
			Tapes().
			Checkextproc(ctx)
}
@function
async def example() -> str:
	return await (
		dag.tapes()
		.checkextproc()
	)
@func()
async example(): Promise<string> {
	return dag
		.tapes()
		.checkExtproc()
}

checkGenerate() 🔗

CheckGenerate verifies that sqlc-generated code is up to date by regenerating it from sqlc.yaml and diffing the result against the committed files.

Return Type
String !
Example
dagger -m github.com/papercomputeco/tapes@8bc0390d275829f3bba8f0eb051f12f3bc9f1c06 call \
 check-generate
func (m *MyModule) Example(ctx context.Context) string  {
	return dag.
			Tapes().
			Checkgenerate(ctx)
}
@function
async def example() -> str:
	return await (
		dag.tapes()
		.checkgenerate()
	)
@func()
async example(): Promise<string> {
	return dag
		.tapes()
		.checkGenerate()
}

checkGoModTidy() 🔗

CheckGoModTidy runs “go mod tidy” and fails if it produces any changes to go.mod or go.sum, indicating that the caller forgot to tidy before committing.

Return Type
String !
Example
dagger -m github.com/papercomputeco/tapes@8bc0390d275829f3bba8f0eb051f12f3bc9f1c06 call \
 check-go-mod-tidy
func (m *MyModule) Example(ctx context.Context) string  {
	return dag.
			Tapes().
			Checkgomodtidy(ctx)
}
@function
async def example() -> str:
	return await (
		dag.tapes()
		.checkgomodtidy()
	)
@func()
async example(): Promise<string> {
	return dag
		.tapes()
		.checkGoModTidy()
}

checkLint() 🔗

CheckLint runs golangci-lint against the tapes source code without applying fixes.

Return Type
String !
Example
dagger -m github.com/papercomputeco/tapes@8bc0390d275829f3bba8f0eb051f12f3bc9f1c06 call \
 check-lint
func (m *MyModule) Example(ctx context.Context) string  {
	return dag.
			Tapes().
			Checklint(ctx)
}
@function
async def example() -> str:
	return await (
		dag.tapes()
		.checklint()
	)
@func()
async example(): Promise<string> {
	return dag
		.tapes()
		.checkLint()
}

checkParity() 🔗

CheckParity runs the contract-fixture gates: the envelope corpus parity gate (seal, schema, coverage), the parser oracle that holds this repo’s reader to that corpus, and the envelope validation rules the corpus’s error cases declare.

It exists as a check of its own rather than as part of Test for two reasons.

The first is that it needs nothing. No Postgres, no Ollama, no services at all — it is fixtures and pure functions. Test binds a database because most of the suite needs one, and that cost is why Test is not on the PR path today; CI runs TestE2E, Build and Smoke. That left the envelope contract — which is the agreement between capture paths in different repositories — gated by nothing on a pull request, even though a corpus edit is exactly the kind of change whose blast radius reaches other repos. A check with no service dependencies can run on every PR in seconds.

The second is what a failure here means. A red CheckParity says the shared contract moved, and the fix usually involves another repository: re-sync a vendored copy, or land a parser change beside the fixture change. Keeping it separate makes that legible from the check name alone, instead of arriving as one failed assertion inside a full unit-test run.

Return Type
String !
Example
dagger -m github.com/papercomputeco/tapes@8bc0390d275829f3bba8f0eb051f12f3bc9f1c06 call \
 check-parity
func (m *MyModule) Example(ctx context.Context) string  {
	return dag.
			Tapes().
			Checkparity(ctx)
}
@function
async def example() -> str:
	return await (
		dag.tapes()
		.checkparity()
	)
@func()
async example(): Promise<string> {
	return dag
		.tapes()
		.checkParity()
}

fixLint() 🔗

FixLint runs golangci-lint against the tapes source code with –fix, applying automatic fixes where possible, and returns the modified source directory.

Return Type
Directory !
Example
dagger -m github.com/papercomputeco/tapes@8bc0390d275829f3bba8f0eb051f12f3bc9f1c06 call \
 fix-lint
func (m *MyModule) Example() *dagger.Directory  {
	return dag.
			Tapes().
			Fixlint()
}
@function
def example() -> dagger.Directory:
	return (
		dag.tapes()
		.fixlint()
	)
@func()
example(): Directory {
	return dag
		.tapes()
		.fixLint()
}

nightly() 🔗

Nightly builds and uploads nightly artifacts

Return Type
Directory !
Arguments
NameTypeDefault ValueDescription
commitString !-

Git commit SHA

postHogPublicKeyString -

PostHog telemetry public API key (write-only)

endpointSecret !-

Bucket endpoint URL

bucketSecret !-

Bucket name

accessKeyIdSecret !-

Bucket access key ID

secretAccessKeySecret !-

Bucket secret access key

Example
dagger -m github.com/papercomputeco/tapes@8bc0390d275829f3bba8f0eb051f12f3bc9f1c06 call \
 nightly --commit string --endpoint env:MYSECRET --bucket env:MYSECRET --access-key-id env:MYSECRET --secret-access-key env:MYSECRET
func (m *MyModule) Example(commit string, endpoint *dagger.Secret, bucket *dagger.Secret, accessKeyId *dagger.Secret, secretAccessKey *dagger.Secret) *dagger.Directory  {
	return dag.
			Tapes().
			Nightly(commit, endpoint, bucket, accessKeyId, secretAccessKey)
}
@function
def example(commit: str, endpoint: dagger.Secret, bucket: dagger.Secret, accesskeyid: dagger.Secret, secretaccesskey: dagger.Secret) -> dagger.Directory:
	return (
		dag.tapes()
		.nightly(commit, endpoint, bucket, accesskeyid, secretaccesskey)
	)
@func()
example(commit: string, endpoint: Secret, bucket: Secret, accessKeyId: Secret, secretAccessKey: Secret): Directory {
	return dag
		.tapes()
		.nightly(commit, endpoint, bucket, accessKeyId, secretAccessKey)
}

ollamaPullModel() 🔗

ollamaPullModel pulls a given Ollama model in a sidecare container.

Return Type
String !
Arguments
NameTypeDefault ValueDescription
modelString !-No description provided
ollamaSvcService !-No description provided
Example
dagger -m github.com/papercomputeco/tapes@8bc0390d275829f3bba8f0eb051f12f3bc9f1c06 call \
 ollama-pull-model --model string --ollama-svc PROTOCOL://HOST:PORT
func (m *MyModule) Example(ctx context.Context, model string, ollamaSvc *dagger.Service) string  {
	return dag.
			Tapes().
			Ollamapullmodel(ctx, model, ollamaSvc)
}
@function
async def example(model: str, ollamasvc: dagger.Service) -> str:
	return await (
		dag.tapes()
		.ollamapullmodel(model, ollamasvc)
	)
@func()
async example(model: string, ollamaSvc: Service): Promise<string> {
	return dag
		.tapes()
		.ollamaPullModel(model, ollamaSvc)
}

ollamaService() 🔗

OllamaService provides an Ollama ready to run service. This service uses a cache volume so models are only pulled once across runs. Pre-create the models/manifests directory tree so Ollama’s serve command doesn’t crash on a fresh (empty) cache volume.

Return Type
Service !
Example
dagger -m github.com/papercomputeco/tapes@8bc0390d275829f3bba8f0eb051f12f3bc9f1c06 call \
 ollama-service
func (m *MyModule) Example() *dagger.Service  {
	return dag.
			Tapes().
			Ollamaservice()
}
@function
def example() -> dagger.Service:
	return (
		dag.tapes()
		.ollamaservice()
	)
@func()
example(): Service {
	return dag
		.tapes()
		.ollamaService()
}

ollamaStack() 🔗

Return Type
Service !
Example
dagger -m github.com/papercomputeco/tapes@8bc0390d275829f3bba8f0eb051f12f3bc9f1c06 call \
 ollama-stack
func (m *MyModule) Example() *dagger.Service  {
	return dag.
			Tapes().
			Ollamastack()
}
@function
def example() -> dagger.Service:
	return (
		dag.tapes()
		.ollamastack()
	)
@func()
example(): Service {
	return dag
		.tapes()
		.ollamaStack()
}

postgresService() 🔗

PostgresService provides a ready to run postgres service with “tapes” user, password, and db

Return Type
Service !
Example
dagger -m github.com/papercomputeco/tapes@8bc0390d275829f3bba8f0eb051f12f3bc9f1c06 call \
 postgres-service
func (m *MyModule) Example() *dagger.Service  {
	return dag.
			Tapes().
			Postgresservice()
}
@function
def example() -> dagger.Service:
	return (
		dag.tapes()
		.postgresservice()
	)
@func()
example(): Service {
	return dag
		.tapes()
		.postgresService()
}

releaseLatest() 🔗

Release builds release binaries and uploads to bucket

Return Type
Directory !
Arguments
NameTypeDefault ValueDescription
versionString !-

Version string (e.g., “v1.0.0”)

commitString !-

Git commit SHA

postHogPublicKeyString -

PostHog telemetry public API key (write-only)

endpointSecret !-

Bucket endpoint URL

bucketSecret !-

Bucket name

accessKeyIdSecret !-

Bucket access key ID

secretAccessKeySecret !-

Bucket secret access key

Example
dagger -m github.com/papercomputeco/tapes@8bc0390d275829f3bba8f0eb051f12f3bc9f1c06 call \
 release-latest --version string --commit string --endpoint env:MYSECRET --bucket env:MYSECRET --access-key-id env:MYSECRET --secret-access-key env:MYSECRET
func (m *MyModule) Example(version string, commit string, endpoint *dagger.Secret, bucket *dagger.Secret, accessKeyId *dagger.Secret, secretAccessKey *dagger.Secret) *dagger.Directory  {
	return dag.
			Tapes().
			Releaselatest(version, commit, endpoint, bucket, accessKeyId, secretAccessKey)
}
@function
def example(version: str, commit: str, endpoint: dagger.Secret, bucket: dagger.Secret, accesskeyid: dagger.Secret, secretaccesskey: dagger.Secret) -> dagger.Directory:
	return (
		dag.tapes()
		.releaselatest(version, commit, endpoint, bucket, accesskeyid, secretaccesskey)
	)
@func()
example(version: string, commit: string, endpoint: Secret, bucket: Secret, accessKeyId: Secret, secretAccessKey: Secret): Directory {
	return dag
		.tapes()
		.releaseLatest(version, commit, endpoint, bucket, accessKeyId, secretAccessKey)
}

test() 🔗

Test runs the tapes unit tests via “go test” and provides a just-in-time Postgres service that can be used by the tests via the “TEST_POSTGRES_DSN” env var.

Return Type
String !
Arguments
NameTypeDefault ValueDescription
runIdString -

Inert identifier that callers can vary to bypass Dagger’s exec cache.

Example
dagger -m github.com/papercomputeco/tapes@8bc0390d275829f3bba8f0eb051f12f3bc9f1c06 call \
 test
func (m *MyModule) Example(ctx context.Context) string  {
	return dag.
			Tapes().
			Test(ctx)
}
@function
async def example() -> str:
	return await (
		dag.tapes()
		.test()
	)
@func()
async example(): Promise<string> {
	return dag
		.tapes()
		.test()
}

testE2E() 🔗

TestE2E runs end-to-end tests against Postgres and Ollama services.

It stands up a PostgreSQL database and an Ollama LLM service, builds the tapes binary, runs the proxy and API as Dagger services backed by Postgres, and uses hurl to verify the full pipeline.

Return Type
String !
Example
dagger -m github.com/papercomputeco/tapes@8bc0390d275829f3bba8f0eb051f12f3bc9f1c06 call \
 test-e-2-e
func (m *MyModule) Example(ctx context.Context) string  {
	return dag.
			Tapes().
			Teste2e(ctx)
}
@function
async def example() -> str:
	return await (
		dag.tapes()
		.teste2e()
	)
@func()
async example(): Promise<string> {
	return dag
		.tapes()
		.testE2E()
}

uploadInstallSh() 🔗

UploadInstallSh uploads the install.sh script to the artifacts bucket

Return Type
Void !
Arguments
NameTypeDefault ValueDescription
endpointSecret !-

Bucket endpoint URL

bucketSecret !-

Bucket name

accessKeyIdSecret !-

Bucket access key ID

secretAccessKeySecret !-

Bucket secret access key

Example
dagger -m github.com/papercomputeco/tapes@8bc0390d275829f3bba8f0eb051f12f3bc9f1c06 call \
 upload-install-sh --endpoint env:MYSECRET --bucket env:MYSECRET --access-key-id env:MYSECRET --secret-access-key env:MYSECRET
func (m *MyModule) Example(ctx context.Context, endpoint *dagger.Secret, bucket *dagger.Secret, accessKeyId *dagger.Secret, secretAccessKey *dagger.Secret)   {
	return dag.
			Tapes().
			Uploadinstallsh(ctx, endpoint, bucket, accessKeyId, secretAccessKey)
}
@function
async def example(endpoint: dagger.Secret, bucket: dagger.Secret, accesskeyid: dagger.Secret, secretaccesskey: dagger.Secret) -> None:
	return await (
		dag.tapes()
		.uploadinstallsh(endpoint, bucket, accesskeyid, secretaccesskey)
	)
@func()
async example(endpoint: Secret, bucket: Secret, accessKeyId: Secret, secretAccessKey: Secret): Promise<void> {
	return dag
		.tapes()
		.uploadInstallSh(endpoint, bucket, accessKeyId, secretAccessKey)
}