Push to Registry
Build and publish your resolver to a container registry
Push to Registry
Publish your resolver to a container registry so others can use it.
Prerequisites
- Docker installed and logged in
- Access to a container registry (Docker Hub, GitHub GHCR, etc.)
- Resolver code ready to publish
- Dockerfile includes
LABEL cyanprint.dev=true(see Resolver Dockerfile)
Build and Push
Tag Your Image
Choose a naming convention for your resolver:
# Docker Hubdocker tag my-resolver:dev username/my-resolver:latest# GitHub Container Registrydocker tag my-resolver:dev ghcr.io/orgname/my-resolver:latest# Private registrydocker tag my-resolver:dev registry.company.com/resolvers/my-resolver:latest
Push to Registry
# Login to Docker Hubdocker login# Pushdocker push username/my-resolver:latest# Also push a versioned tagdocker push username/my-resolver:1.0.0
# Login to GitHub Container Registryecho $GITHUB_TOKEN | docker login ghcr.io -u USERNAME --password-stdin# Pushdocker push ghcr.io/orgname/my-resolver:latestdocker push ghcr.io/orgname/my-resolver:1.0.0
# Login to private registrydocker login registry.company.com# Pushdocker push registry.company.com/resolvers/my-resolver:latest
Verify the Push
# Pull the image to verifydocker pull username/my-resolver:latest# Run a testdocker run --rm username/my-resolver:latest
Pushing to a container registry is only part of the process. You must also register your resolver with the CyanPrint registry for the system to discover and use it.
Naming Convention
Use the username/resolver-name or org/resolver-name format for your Docker images:
| Pattern | Example | Description |
|---|---|---|
org/resolver-name | atomi/json-merger | Organization namespace |
username/resolver-name | johndoe/gitignore-merger | User namespace |
registry/org/resolver-name | ghcr.io/atomi/resolvers/json-merger | Full registry path |
The system uses the username/name[:version] format to reference resolvers in templates. Container names are auto-generated internally by the system.
Versioning
Semantic Versioning
Use semantic versioning for releases:
# Major version (breaking changes)docker tag my-resolver:dev org/my-resolver:2.0.0# Minor version (new features)docker tag my-resolver:dev org/my-resolver:1.1.0# Patch version (bug fixes)docker tag my-resolver:dev org/my-resolver:1.0.1# Latest tag (current stable)docker tag my-resolver:dev org/my-resolver:latest
Using in Templates
Templates can pin to specific versions:
# cyan.yamlresolvers:- resolver: org/my-resolver:1.0.0 # Pinned versionconfig: {}files:- config.json- resolver: org/my-resolver:latest # Always latestconfig: {}files:- "*.json"
Version references are exact matches or latest. The system does not perform semantic version range matching.
Automation
GitHub Actions
Create .github/workflows/publish.yml:
name: Publish Resolveron:release:types: [published]jobs:publish:runs-on: ubuntu-lateststeps:- uses: actions/checkout@v4- name: Set up Docker Buildxuses: docker/setup-buildx-action@v3- name: Login to GHCRuses: docker/login-action@v3with:registry: ghcr.iousername: ${{ github.actor }}password: ${{ secrets.GITHUB_TOKEN }}- name: Extract versionid: versionrun: echo "VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT- name: Build and pushuses: docker/build-push-action@v5with:context: .push: truetags: |ghcr.io/${{ github.repository_owner }}/my-resolver:latestghcr.io/${{ github.repository_owner }}/my-resolver:${{ steps.version.outputs.VERSION }}
Documentation
Include usage documentation with your resolver:
README.md
# My ResolverA CyanPrint resolver that merges JSON files from layered templates.## Configuration| Option | Type | Default | Description ||--------|------|---------|-------------|| `arrayStrategy` | `string` | `replace` | How to merge arrays: `concat`, `replace`, `distinct` |## UsageAdd to your template's `cyan.yaml`:\`\`\`yamlresolvers:- resolver: org/my-resolver:1.0.0config:arrayStrategy: concatfiles:- config.json- package.json\`\`\`