Shell 99.5%
Other 0.5%
1 1 0

Clone this repository

https://tangled.org/gdiazlo.tngl.sh/repo
git@tangled.org:gdiazlo.tngl.sh/repo

For self-hosted knots, clone URLs may differ based on your setup.

README.md

Private OPAM Repository#

A private OPAM repository with tooling for publishing OCaml packages.

Repository Structure#

├── bin/opam-publish     # CLI tool for publishing packages
├── packages/            # Published package metadata
│   └── <pkg>/
│       └── <pkg>.<version>/
│           └── opam
└── repo                 # OPAM repository marker

Architecture#

┌──────────────┐   opam-publish   ┌─────────────┐
│ Your Package │ ────────────────▶│ S3 Storage  │◀── tarballs
└──────────────┘                  └─────────────┘
                                         │
                                         ▼
                                  ┌─────────────┐
                                  │ Cloudflare  │◀── public reads
                                  └─────────────┘
                                         
┌──────────────┐   opam-publish   ┌─────────────┐
│ Your Package │ ────────────────▶│ This Repo   │◀── metadata only
└──────────────┘                  └─────────────┘

Setup#

Requirements#

  • mc (MinIO client, for S3-compatible uploads)
  • git (for pushing to this repo)
  • tar, sha256sum (standard Unix tools)
  • opam (optional, for linting validation)
  • SSH access to this repository

Configuration#

1. Configure mc alias (stores credentials securely in ~/.mc/):

mc alias set mys3 https://your-s3-endpoint ACCESS_KEY SECRET_KEY

2. Create opam-publish config (~/.config/opam-publish/config):

mkdir -p ~/.config/opam-publish
chmod 700 ~/.config/opam-publish

cat > ~/.config/opam-publish/config << 'EOF'
MC_ALIAS=mys3
S3_BUCKET=your-bucket
PUBLIC_URL_BASE=https://packages.yourdomain.com
OPAM_REPO_URL=git@your-git-host:path/to/this/repo
EOF

chmod 600 ~/.config/opam-publish/config

Add to PATH#

export PATH="$PATH:/path/to/this/repo/bin"

Or symlink:

ln -s /path/to/this/repo/bin/opam-publish ~/.local/bin/

Publishing a Package#

Prerequisites#

Your OCaml project must have:

  1. A <package>.opam file (or generate via dune build)
  2. A version field in the .opam file or dune-project

Publish#

From your project root:

opam-publish

If multiple .opam files exist, specify which one:

opam-publish mypackage

What Happens#

  1. Validates .opam file (required fields, runs opam lint if available)
  2. Builds a source tarball (excludes .git, _build, _opam)
  3. Computes SHA256 checksum
  4. Uploads tarball to S3
  5. Clones this repo, adds package metadata with URL + checksum
  6. Pushes commit to this repo

Example Output#

==> Validating mylib.opam...
    ok
==> Building mylib.1.0.0.tbz...
    42K
==> Uploading to S3...
    https://packages.example.com/mylib/mylib.1.0.0.tbz
==> Cloning opam repository...
==> Pushing to opam repository...
==> Published mylib 1.0.0

Done. Users can install with:
    opam install mylib

Using This Repository#

Add to OPAM#

opam repository add private git+ssh://git@your-git-host/path/to/repo.git

Or via HTTPS:

opam repository add private git+https://your-git-host/path/to/repo.git

Install Packages#

opam update
opam install <package>

Remove Repository#

opam repository remove private

Releasing a New Version#

  1. Update version in dune-project:

    (version 1.2.0)
    
  2. Regenerate opam file:

    dune build
    
  3. Commit changes:

    git add -A
    git commit -m "Release 1.2.0"
    git tag v1.2.0
    git push origin main --tags
    
  4. Publish:

    opam-publish
    

Troubleshooting#

"version not found"#

Ensure your .opam file has a version field:

version: "1.0.0"

Or in dune-project:

(version 1.0.0)

"version already published"#

Each version can only be published once. Bump the version number.

S3 upload fails#

Check mc alias and bucket access:

mc alias list
mc ls mys3/your-bucket

Git push fails#

Ensure you have SSH access to this repository:

ssh -T git@your-git-host

"opam lint failed"#

Fix the issues reported by opam lint. Common problems:

opam lint mylib.opam

Missing fields can be added to dune-project:

(generate_opam_files true)
(name mylib)
(synopsis "Short description")
(authors "Your Name")
(maintainers "your@email.com")
(license MIT)

Then regenerate with dune build.