Timoni modules are distributed as Open Container Initiative
(OCI) artifacts. When publishing a module version to a container registry,
the version number is used as the OCI artifact tag.
Artifact format
The OCI artifacts produced with timoni mod push have the following media types:
Image media type application/vnd.oci.image.manifest.v1+json
Config media type application/vnd.timoni.config.v1+json
Layer media type application/vnd.timoni.content.v1.tar+gzip
The container images declared in the module’s images.cue file are recorded
in the sh.timoni.images annotation as a comma-separated list of image
references, sorted alphabetically. Each reference is composed from the image
default values in the repository[:tag][@digest] format, where the tag and
digest are included only when set to non-empty values.
Modules without an images.cue file carry no sh.timoni.images annotation,
and the annotation can be overridden with --annotation sh.timoni.images=<LIST>.For reproducible builds, Timoni preserves explicit creation, source and
revision annotations, then uses SOURCE_DATE_EPOCH or the Git commit time for
the creation date. Git source and revision metadata are added when available.
Version format
The version format used by Timoni follows the SemVer 2
standard, with the following restrictions:
The version number must take the form X.Y.Z where X, Y, and Z are non-negative integers, and must not contain leading zeroes.
Prefixing the version number with v is not supported.
Suffixing the version number with build metadata by appending a plus sign is not supported, because the + sign can’t be used in OCI tags.
The supported formats are:
0.Y.Z - denotes initial development e.g. 0.1.2
X.Y.Z - denotes a stable release when X >= 1 e.g. 1.0.0 or 1.23.45
X.Y.Z-alpha.N - denotes an alpha pre-release e.g. 2.0.0-alpha.1
X.Y.Z-beta.N - denotes a beta pre-release e.g. 2.0.0-beta.1
X.Y.Z-rc.N - denotes a releases candidate e.g. 2.0.0-rc.1
Building modules without a registry
timoni mod build writes the same ordered
vendor and module layers as timoni mod push, without registry or network
access:
The version is required and becomes the manifest version annotation and local
reference name. Use --format=oci-layout for directory output.
Local outputs are unsigned; existing output paths are rejected.The archive produced by mod build can be pushed to a registry with
timoni mod push without re-packaging the source module. The version is read
from the archive manifest, so it must not be passed again:
timoni mod build ./modules/my-app -v 1.0.0 -o ./my-app-1.0.0.oci.tartimoni mod push ./my-app-1.0.0.oci.tar oci://ghcr.io/org/modules/app
Annotations and symlink resolution are fixed at build time, so
--annotation and --resolve-symlinks are not supported when pushing a
pre-built archive.
Publishing module versions
Timoni offers a command for publishing a module version
by packaging a local module as an OCI artifact and pushing
the artifact to a container registry.When publishing a module with timoni mod push,
the version number must be specified using the --version flag.
Stable versions
Example of publishing version 1.0.0 as the latest stable release:
timoni mod push ./modules/my-app oci://ghcr.io/my-org/modules/my-app \ --latest=true \ --version=1.0.0
To add custom metadata to a version, such as licenses and documentation links
please the timoni mod push docs.
Pre-release versions
Example of publishing a pre-release version:
timoni mod push ./modules/my-app oci://ghcr.io/my-org/modules/my-app \ --latest=false \ --version=2.0.0-rc.1
Latest version
The --latest flag is used to mark a stable release as the latest version.
When --latest is set to true, Timoni will push the version tag,
then it will tag the version as latest in the container registry.
ImmutabilityNote that a Timoni module version should be immutable.
The only tag that is suppose to be mutable, is the latest one.
Overriding an existing version tag in the container registry should be avoided,
some registries allow enforcing immutability for semver tags but this is not guranteed by default.
Timoni modules can contain files that are not meant to be published.
To exclude files from the module artifact, you can add a timoni.ignore file
in the module root directory.The timoni.ignore file must contain rules in the
.gitignore pattern format.It is recommended to exclude Git, Go and CUE tools related files, for example:
When packaging a module, Timoni skips symbolic links by default.
To include the link targets in the artifact as regular files and
directories, run timoni mod push or timoni mod build with the
--resolve-symlinks flag:
timoni mod push ./path/to/module oci://docker.io/org/app-module \ --version=1.0.0 \ --resolve-symlinks
The same flag applies when building the module artifact locally:
timoni mod build ./path/to/module -v 1.0.0 -o ./app-module-1.0.0.oci.tar \ --resolve-symlinks
This allows sharing files between modules in a monorepo, for example
by symlinking the vendored CUE schemas under cue.mod/gen.The timoni.ignore rules apply to the resolved content at its
in-module path, the same as for regular files and directories.The timoni artifact push and timoni artifact build commands take the
same flag for packaging the symlink targets found in the given directory.
Local modulesWhen building a module from a local path, timoni build, timoni apply
and timoni mod vet read the module files in place from the source
directory, following symbolic links the same way as the operating system.
Note that a module which relies on symlinked files builds locally but
is published incomplete unless pushed or built with --resolve-symlinks.
Listing module versions
Timoni offers a command for listing all the versions available in a
container registry for a particular module.The timoni mod list oci://<module-url> prints a table with the versions order
by semver and the OCI digest corresponding to each version. The newest 100 versions
are listed by default, use --limit 0 to list all of them or --limit <n> to
change the number of versions shown. Pass --with-digest=false to skip the
digest lookups when only the version list is needed.Example:
$ timoni mod list oci://ghcr.io/stefanprodan/modules/podinfoVERSION DIGEST latest sha256:ddf8be195f69ad767b40d5c3fec3a8a85482bf6bf469d949a462cb4fd27df580 6.14.1 sha256:ddf8be195f69ad767b40d5c3fec3a8a85482bf6bf469d949a462cb4fd27df580 6.14.0 sha256:32082e8ac0bba9ee2a3f95534f52c94f5a41dc642bb396c73b04fa18aff147d7 6.13.0 sha256:37312e975dc9bc6c1f4ebccc90f55caf2d35ce15f1b0f59794348924fa0193e9 6.12.0 sha256:99bdcbc42933bd0d14c0c5496541059063f0c111393f5b773cd0e2bbf6bed435 6.11.2 sha256:12b1fa57fdf554110a1ec3519d02f69a6896515967d652029bc953a7e988ff29
Was this page helpful?
{"docsConfig":{"theme":"aspen","$schema":"https://mintlify.com/docs.json","name":"Timoni","description":"Timoni is a package manager for Kubernetes powered by CUE lang.","colors":{"primary":"#7e56c2","light":"#a98be0","dark":"#6500b0"},"logo":{"light":"https://mintcdn.com/timoni/8xOqj2ulwazG1u2D/images/logo_text_black.svg?fit=max\u0026auto=format\u0026n=8xOqj2ulwazG1u2D\u0026q=85\u0026s=85ffbf62ec541a621a19255513199222","dark":"https://mintcdn.com/timoni/8xOqj2ulwazG1u2D/images/logo_text_white.svg?fit=max\u0026auto=format\u0026n=8xOqj2ulwazG1u2D\u0026q=85\u0026s=89788f7e520a7c81896a693804eb502d","href":"/"},"favicon":"https://mintcdn.com/timoni/8xOqj2ulwazG1u2D/images/favicon.png?fit=max\u0026auto=format\u0026n=8xOqj2ulwazG1u2D\u0026q=85\u0026s=214f9ea61f808abf055c6211a83d221c","appearance":{"default":"system"},"background":{"decoration":"gradient"},"navbar":{"links":[{"icon":"download","href":"/install","label":"Install"},{"icon":"github-alt","href":"https://github.com/stefanprodan/timoni","label":"GitHub"}]},"footer":{"socials":{"github":"https://github.com/stefanprodan/timoni","slack":"https://cloud-native.slack.com/team/ULPRMFH38","x":"https://x.com/stefanprodan","linkedin":"https://linkedin.com/in/stefanprodan"}},"seo":{"metatags":{"twitter:site":"@stefanprodan","twitter:creator":"@stefanprodan","twitter:card":"summary_large_image"},"indexing":"navigable"},"styling":{"eyebrows":"breadcrumbs","codeblocks":"system","latex":false},"errors":{"404":{"redirect":false,"title":"Page not found","description":"The page you are looking for does not exist or has moved.\n\n\u003cCardGroup cols={2}>\n \u003cCard title=\"Quickstart\" icon=\"rocket\" href=\"/quickstart\">Deploy your first module in minutes.\u003c/Card>\n \u003cCard title=\"Installation\" icon=\"download\" href=\"/install\">Get the Timoni CLI for your OS.\u003c/Card>\n \u003cCard title=\"CUE Reference\" icon=\"code\" href=\"/cue/module/initialization\">Author Timoni modules with CUE.\u003c/Card>\n \u003cCard title=\"CLI Reference\" icon=\"terminal\" href=\"/cmd/timoni\">Every timoni command and flag.\u003c/Card>\n\u003c/CardGroup>\n\nFollowed a broken link? [Open an issue](https://github.com/stefanprodan/timoni/issues) so we can fix it."}},"contextual":{"options":["copy","mcp","view","cursor","vscode"],"display":"header"},"navigation":{"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"timoni","hasAudioNarration":false,"actualSubdomain":"timoni","customDomains":["timoni.sh"],"gitSource":{"type":"github","owner":"stefanprodan","repo":"timoni","deployBranch":"website","contentDirectory":"","isPrivate":true,"mountPath":"","label":""},"feedback":{"thumbs":true},"entitlements":{"AI_CHAT":{"status":"ENABLED"},"WEB_MCP":{"status":"ENABLED"},"NARRATION":{"status":"ENABLED"}},"buildId":"6ae489bca3eed560d7e508f5","clientVersion":"0.0.4143","searchFilterCounts":[{"language":"default","tag":"CLI Reference","count":49},{"language":"default","tag":"Documentation","count":16},{"language":"default","tag":"CUE Reference","count":14},{"language":"default","tag":"Module","count":13},{"language":"default","tag":"Instance","count":9},{"language":"default","tag":"Module Development","count":9},{"language":"default","tag":"Artifact","count":7},{"language":"default","tag":"Bundle","count":7},{"language":"default","tag":"App Delivery","count":6},{"language":"default","tag":"Integrations","count":5}]},"assistantConfig":{"enableAskAiButton":false,"enableStarterQuestions":false,"enableContextualStarterQuestions":false,"enableAskAiSearchBar":true,"deflection":{"enabled":true,"email":"[email protected]"}},"basePath":"","hasChatPermissions":false,"hasWebMcpPermissions":true,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-rbac-roles","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"rbac-expansion","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"full-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-sso-scim","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-signup","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-dual-write","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-enabled","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"approve-review-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-metadata","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"sso-setup-deadline-banner","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-serve","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"live-agents","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"googleFontsInlined":false},"customCss":[{"filePath":"style.css","content":"body:has(#timoni-home) #navbar div:has(>.nav-tabs){display:none}#body-content,#navbar>div.mx-auto{max-width:100rem!important}@media (min-width: 1024px){#content-container{max-width:none!important;padding-left:3rem!important}}#header>.text-lg.prose{display:none}body:has(#timoni-home) #body-content{max-width:none!important}.tm-gradient{background:linear-gradient(135deg, #7e56c2 0%, #6500b0 60%, #2b1a4a 100%)}.tm-on-gradient{color:rgba(255, 255, 255, 0.8)}.tm-outline-light{color:#fff;border:1px solid rgba(255, 255, 255, 0.5)}.tm-outline-light:hover{border-color:#fff;background:rgba(255, 255, 255, 0.1)}.tm-band{background:#faf8fd;border-top:1px solid #ebe6f4;border-bottom:1px solid #ebe6f4}html.dark .tm-band{background:rgba(255, 255, 255, 0.025);border-color:rgba(255, 255, 255, 0.07)}.tm-check{display:inline-flex;flex:none;align-items:center;justify-content:center;width:1.25rem;height:1.25rem;margin-top:0.1rem;border-radius:9999px;background:rgba(126, 86, 194, 0.12);color:#7e56c2}.tm-check svg{width:0.65rem!important;height:0.65rem!important}html.dark .tm-check{background:rgba(169, 139, 224, 0.18);color:#a98be0}.tm-diagram-frame{padding:1.25rem;border:1px solid #ebe6f4;border-radius:1rem;background:#fff}html.dark .tm-diagram-frame{border-color:rgba(255, 255, 255, 0.08);background:rgba(255, 255, 255, 0.02)}.tm-footer{border-top:1px solid #ebe6f4}html.dark .tm-footer{border-color:rgba(255, 255, 255, 0.07)}.tm-footer ul a{color:#4b5563}html.dark .tm-footer ul a{color:#9ca3af}.tm-footer ul a:hover{color:#7e56c2}html.dark .tm-footer ul a:hover{color:#a98be0}.tm-footer-bottom{border-top:1px solid #ebe6f4}html.dark .tm-footer-bottom{border-color:rgba(255, 255, 255, 0.07)}.tm-footer-socials{display:inline-flex;gap:1rem}.tm-footer-socials a{color:#6b7280}.tm-footer-socials a:hover{color:#7e56c2}.tm-footer-socials svg{width:1.1rem!important;height:1.1rem!important}#navbar .navbar-link>a{width:30px;height:30px;padding:0;justify-content:center;border-radius:9999px;background:rgba(31, 41, 55, 0.04)}html.dark #navbar .navbar-link>a{background:rgba(255, 255, 255, 0.1)}#navbar .navbar-link>a>span{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0, 0, 0, 0);white-space:nowrap}#navbar .navbar-link>a>svg{width:1rem;height:1rem;background-color:#4b5563}#navbar .navbar-link>a:hover>svg{background-color:#1f2937}html.dark #navbar .navbar-link>a>svg{background-color:#d1d5db}html.dark #navbar .navbar-link>a:hover>svg{background-color:#f3f4f6}.not-found-container{max-width:44rem!important;padding-top:8rem!important}.not-found-description .card-group{width:100%;text-align:left}.not-found-description .card-group .card{text-align:left}#navbar img.nav-logo{height:30px}[data-component-part=\"card-icon\"] img[src*=\"/images/icons/\"]{object-fit:none;object-position:-9999px -9999px;background-color:rgb(var(--primary));mask-repeat:no-repeat;mask-position:center;mask-size:contain}html.dark [data-component-part=\"card-icon\"] img[src*=\"/images/icons/\"]{background-color:rgb(var(--primary-light))}[data-component-part=\"card-icon\"] img[src*=\"/images/icons/kubernetes.svg\"]{mask-image:url(\"/images/icons/kubernetes.svg\")}[data-component-part=\"card-icon\"] img[src*=\"/images/icons/helm.svg\"]{mask-image:url(\"/images/icons/helm.svg\")}[data-component-part=\"card-icon\"] img[src*=\"/images/icons/cue.svg\"]{mask-image:url(\"/images/icons/cue.svg\")}[data-component-part=\"card-icon\"] img[src*=\"/images/icons/flux.svg\"]{mask-image:url(\"/images/icons/flux.svg\")}img.tm-hero-logo{object-fit:none;object-position:-9999px -9999px;background-color:#111827;mask-image:url(\"/images/logo_icons.svg\");mask-repeat:no-repeat;mask-position:center;mask-size:contain}html.dark img.tm-hero-logo{background-color:#fff}"}],"page":{"pagePath":"cue/module/publishing","slug":"/cue/module/publishing","pageMetadata":{"title":"Module Publishing","sidebarTitle":"Publishing module versions","description":"Version and publish modules as OCI artifacts.","href":"/cue/module/publishing"},"description":{"compiledSource":"\"use strict\";\nconst {jsx: _jsx} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n p: \"p\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsx(_components.p, {\n children: \"Version and publish modules as OCI artifacts.\"\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx,jsxs:_jsxs}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){const _components={a:`a`,code:`code`,li:`li`,p:`p`,pre:`pre`,span:`span`,strong:`strong`,ul:`ul`,..._provideComponents(),...props.components},{CodeBlock,Heading,Tip}=_components;if(!CodeBlock)_missingMdxReference(`CodeBlock`,true);if(!Heading)_missingMdxReference(`Heading`,true);if(!Tip)_missingMdxReference(`Tip`,true);return _jsxs(_Fragment,{children:[_jsxs(_components.p,{children:[`Timoni modules are distributed as `,_jsx(_components.a,{href:`https://opencontainers.org/`,children:`Open Container Initiative`}),`\n(OCI) artifacts. When publishing a module version to a container registry,\nthe version number is used as the OCI artifact tag.`]}),`\n`,_jsx(Heading,{level:`2`,id:`artifact-format`,children:`Artifact format`}),`\n`,_jsxs(_components.p,{children:[`The OCI artifacts produced with `,_jsx(_components.code,{children:`timoni mod push`}),` have the following media types:`]}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[`Image media type `,_jsx(_components.code,{children:`application/vnd.oci.image.manifest.v1+json`})]}),`\n`,_jsxs(_components.li,{children:[`Config media type `,_jsx(_components.code,{children:`application/vnd.timoni.config.v1+json`})]}),`\n`,_jsxs(_components.li,{children:[`Layer media type `,_jsx(_components.code,{children:`application/vnd.timoni.content.v1.tar+gzip`})]}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`The artifacts are annotated with OCI\n`,_jsx(_components.a,{href:`https://specs.opencontainers.org/image-spec/annotations/?v=v1.0.1#pre-defined-annotation-keys`,children:`standard annotations`}),`:`]}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsx(_components.li,{children:_jsx(_components.code,{children:`org.opencontainers.image.version: \u003cMODULE VERSION>`})}),`\n`,_jsx(_components.li,{children:_jsx(_components.code,{children:`org.opencontainers.image.created: \u003cMODULE LAST MODIFIED DATE>`})}),`\n`,_jsx(_components.li,{children:_jsx(_components.code,{children:`org.opencontainers.image.source: \u003cMODULE GIT URL>`})}),`\n`,_jsx(_components.li,{children:_jsx(_components.code,{children:`org.opencontainers.image.revision: \u003cMODULE GIT SHA>`})}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`The container images declared in the module’s `,_jsx(_components.code,{children:`images.cue`}),` file are recorded\nin the `,_jsx(_components.code,{children:`sh.timoni.images`}),` annotation as a comma-separated list of image\nreferences, sorted alphabetically. Each reference is composed from the image\ndefault values in the `,_jsx(_components.code,{children:`repository[:tag][@digest]`}),` format, where the tag and\ndigest are included only when set to non-empty values.\nModules without an `,_jsx(_components.code,{children:`images.cue`}),` file carry no `,_jsx(_components.code,{children:`sh.timoni.images`}),` annotation,\nand the annotation can be overridden with `,_jsx(_components.code,{children:`--annotation sh.timoni.images=\u003cLIST>`}),`.`]}),`\n`,_jsxs(_components.p,{children:[`For reproducible builds, Timoni preserves explicit creation, source and\nrevision annotations, then uses `,_jsx(_components.code,{children:`SOURCE_DATE_EPOCH`}),` or the Git commit time for\nthe creation date. Git source and revision metadata are added when available.`]}),`\n`,_jsx(Heading,{level:`2`,id:`version-format`,children:`Version format`}),`\n`,_jsxs(_components.p,{children:[`The version format used by Timoni follows the `,_jsx(_components.a,{href:`https://semver.org/spec/v2.0.0.html`,children:`SemVer 2`}),`\nstandard, with the following restrictions:`]}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[`The version number must take the form `,_jsx(_components.code,{children:`X.Y.Z`}),` where X, Y, and Z are non-negative integers, and must not contain leading zeroes.`]}),`\n`,_jsxs(_components.li,{children:[`Prefixing the version number with `,_jsx(_components.code,{children:`v`}),` is not supported.`]}),`\n`,_jsxs(_components.li,{children:[`Suffixing the version number with build metadata by appending a plus sign is not supported, because the `,_jsx(_components.code,{children:`+`}),` sign can’t be used in OCI tags.`]}),`\n`]}),`\n`,_jsx(_components.p,{children:`The supported formats are:`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`0.Y.Z`}),` - denotes initial development e.g. `,_jsx(_components.code,{children:`0.1.2`})]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`X.Y.Z`}),` - denotes a stable release when `,_jsx(_components.code,{children:`X >= 1`}),` e.g. `,_jsx(_components.code,{children:`1.0.0`}),` or `,_jsx(_components.code,{children:`1.23.45`})]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`X.Y.Z-alpha.N`}),` - denotes an alpha pre-release e.g. `,_jsx(_components.code,{children:`2.0.0-alpha.1`})]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`X.Y.Z-beta.N`}),` - denotes a beta pre-release e.g. `,_jsx(_components.code,{children:`2.0.0-beta.1`})]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`X.Y.Z-rc.N`}),` - denotes a releases candidate e.g. `,_jsx(_components.code,{children:`2.0.0-rc.1`})]}),`\n`]}),`\n`,_jsx(Heading,{level:`2`,id:`building-modules-without-a-registry`,children:`Building modules without a registry`}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.a,{href:`/cmd/timoni_mod_build`,children:`timoni mod build`}),` writes the same ordered\nvendor and module layers as `,_jsx(_components.code,{children:`timoni mod push`}),`, without registry or network\naccess:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`2`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`2`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`timoni`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` mod`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` build`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` ./modules/my-app`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -v`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:` 1.0.0`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -o`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` ./my-app-1.0.0.oci.tar`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`skopeo`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` copy`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` oci-archive:./my-app-1.0.0.oci.tar`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` docker://ghcr.io/org/modules/app:1.0.0`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`The version is required and becomes the manifest version annotation and local\nreference name. Use `,_jsx(_components.code,{children:`--format=oci-layout`}),` for directory output.\nLocal outputs are unsigned; existing output paths are rejected.`]}),`\n`,_jsxs(_components.p,{children:[`The archive produced by `,_jsx(_components.code,{children:`mod build`}),` can be pushed to a registry with\n`,_jsx(_components.code,{children:`timoni mod push`}),` without re-packaging the source module. The version is read\nfrom the archive manifest, so it must not be passed again:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`2`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`2`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`timoni`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` mod`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` build`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` ./modules/my-app`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -v`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:` 1.0.0`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -o`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` ./my-app-1.0.0.oci.tar`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`timoni`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` mod`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` push`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` ./my-app-1.0.0.oci.tar`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` oci://ghcr.io/org/modules/app`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`Annotations and symlink resolution are fixed at build time, so\n`,_jsx(_components.code,{children:`--annotation`}),` and `,_jsx(_components.code,{children:`--resolve-symlinks`}),` are not supported when pushing a\npre-built archive.`]}),`\n`,_jsx(Heading,{level:`2`,id:`publishing-module-versions`,children:`Publishing module versions`}),`\n`,_jsx(_components.p,{children:`Timoni offers a command for publishing a module version\nby packaging a local module as an OCI artifact and pushing\nthe artifact to a container registry.`}),`\n`,_jsxs(_components.p,{children:[`When publishing a module with `,_jsx(_components.a,{href:`/cmd/timoni_mod_push`,children:`timoni mod push`}),`,\nthe version number must be specified using the `,_jsx(_components.code,{children:`--version`}),` flag.`]}),`\n`,_jsx(Heading,{level:`3`,id:`stable-versions`,children:`Stable versions`}),`\n`,_jsxs(_components.p,{children:[`Example of publishing version `,_jsx(_components.code,{children:`1.0.0`}),` as the latest stable release:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`3`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`3`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`timoni`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` mod`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` push`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` ./modules/my-app`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` oci://ghcr.io/my-org/modules/my-app`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D7BA7D`},children:` \\\\`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --latest=true`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D7BA7D`},children:` \\\\`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --version=1.0.0`})}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`To add custom metadata to a version, such as licenses and documentation links\nplease the `,_jsx(_components.a,{href:`/cmd/timoni_mod_push`,children:`timoni mod push docs`}),`.`]}),`\n`,_jsx(Heading,{level:`3`,id:`pre-release-versions`,children:`Pre-release versions`}),`\n`,_jsx(_components.p,{children:`Example of publishing a pre-release version:`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`3`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`3`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`timoni`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` mod`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` push`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` ./modules/my-app`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` oci://ghcr.io/my-org/modules/my-app`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D7BA7D`},children:` \\\\`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --latest=false`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D7BA7D`},children:` \\\\`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --version=2.0.0-rc.1`})}),`\n`]})})}),`\n`,_jsx(Heading,{level:`3`,id:`latest-version`,children:`Latest version`}),`\n`,_jsxs(_components.p,{children:[`The `,_jsx(_components.code,{children:`--latest`}),` flag is used to mark a stable release as the latest version.\nWhen `,_jsx(_components.code,{children:`--latest`}),` is set to `,_jsx(_components.code,{children:`true`}),`, Timoni will push the version tag,\nthen it will tag the version as `,_jsx(_components.code,{children:`latest`}),` in the container registry.`]}),`\n`,_jsxs(Tip,{children:[_jsx(_components.p,{children:_jsx(_components.strong,{children:`Immutability`})}),_jsxs(_components.p,{children:[`Note that a Timoni module version should be immutable.\nThe only tag that is suppose to be mutable, is the `,_jsx(_components.code,{children:`latest`}),` one.\nOverriding an existing version tag in the container registry should be avoided,\nsome registries allow enforcing immutability for semver tags but this is not guranteed by default.`]})]}),`\n`,_jsxs(_components.p,{children:[`To automate the publishing of module versions, please see the `,_jsx(_components.a,{href:`/cue/module/github-actions`,children:`Timoni GitHub Actions doc`}),`.`]}),`\n`,_jsx(Heading,{level:`3`,id:`ignoring-files`,children:`Ignoring files`}),`\n`,_jsxs(_components.p,{children:[`Timoni modules can contain files that are not meant to be published.\nTo exclude files from the module artifact, you can add a `,_jsx(_components.code,{children:`timoni.ignore`}),` file\nin the module root directory.`]}),`\n`,_jsxs(_components.p,{children:[`The `,_jsx(_components.code,{children:`timoni.ignore`}),` file must contain rules in the\n`,_jsx(_components.a,{href:`https://git-scm.com/docs/gitignore#_pattern_format`,children:`.gitignore pattern format`}),`.`]}),`\n`,_jsx(_components.p,{children:`It is recommended to exclude Git, Go and CUE tools related files, for example:`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`15`,language:`text`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`text`,children:_jsxs(_components.code,{language:`text`,numberOfLines:`15`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`# VCS`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`.git/`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`.gitignore`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`.gitmodules`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`.gitattributes`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`# Go`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`vendor/`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`go.mod`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`go.sum`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`# CUE`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`*_tool.cue`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`debug_values.cue`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})})]})})}),`\n`,_jsx(Heading,{level:`3`,id:`symbolic-links`,children:`Symbolic links`}),`\n`,_jsxs(_components.p,{children:[`When packaging a module, Timoni skips symbolic links by default.\nTo include the link targets in the artifact as regular files and\ndirectories, run `,_jsx(_components.code,{children:`timoni mod push`}),` or `,_jsx(_components.code,{children:`timoni mod build`}),` with the\n`,_jsx(_components.code,{children:`--resolve-symlinks`}),` flag:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`3`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`3`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`timoni`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` mod`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` push`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` ./path/to/module`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` oci://docker.io/org/app-module`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D7BA7D`},children:` \\\\`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --version=1.0.0`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D7BA7D`},children:` \\\\`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --resolve-symlinks`})}),`\n`]})})}),`\n`,_jsx(_components.p,{children:`The same flag applies when building the module artifact locally:`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`2`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`2`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`timoni`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` mod`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` build`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` ./path/to/module`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -v`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:` 1.0.0`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -o`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` ./app-module-1.0.0.oci.tar`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D7BA7D`},children:` \\\\`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --resolve-symlinks`})}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`This allows sharing files between modules in a monorepo, for example\nby symlinking the vendored CUE schemas under `,_jsx(_components.code,{children:`cue.mod/gen`}),`.`]}),`\n`,_jsxs(_components.p,{children:[`The `,_jsx(_components.code,{children:`timoni.ignore`}),` rules apply to the resolved content at its\nin-module path, the same as for regular files and directories.`]}),`\n`,_jsxs(_components.p,{children:[`The `,_jsx(_components.code,{children:`timoni artifact push`}),` and `,_jsx(_components.code,{children:`timoni artifact build`}),` commands take the\nsame flag for packaging the symlink targets found in the given directory.`]}),`\n`,_jsxs(Tip,{children:[_jsx(_components.p,{children:_jsx(_components.strong,{children:`Local modules`})}),_jsxs(_components.p,{children:[`When building a module from a local path, `,_jsx(_components.code,{children:`timoni build`}),`, `,_jsx(_components.code,{children:`timoni apply`}),`\nand `,_jsx(_components.code,{children:`timoni mod vet`}),` read the module files in place from the source\ndirectory, following symbolic links the same way as the operating system.\nNote that a module which relies on symlinked files builds locally but\nis published incomplete unless pushed or built with `,_jsx(_components.code,{children:`--resolve-symlinks`}),`.`]})]}),`\n`,_jsx(Heading,{level:`2`,id:`listing-module-versions`,children:`Listing module versions`}),`\n`,_jsx(_components.p,{children:`Timoni offers a command for listing all the versions available in a\ncontainer registry for a particular module.`}),`\n`,_jsxs(_components.p,{children:[`The `,_jsx(_components.code,{children:`timoni mod list oci://\u003cmodule-url>`}),` prints a table with the versions order\nby semver and the OCI digest corresponding to each version. The newest 100 versions\nare listed by default, use `,_jsx(_components.code,{children:`--limit 0`}),` to list all of them or `,_jsx(_components.code,{children:`--limit \u003cn>`}),` to\nchange the number of versions shown. Pass `,_jsx(_components.code,{children:`--with-digest=false`}),` to skip the\ndigest lookups when only the version list is needed.`]}),`\n`,_jsx(_components.p,{children:`Example:`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`8`,language:`shellsession`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellsession`,children:_jsxs(_components.code,{language:`shellsession`,numberOfLines:`8`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`$ timoni mod list oci://ghcr.io/stefanprodan/modules/podinfo`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`VERSION DIGEST `})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`latest sha256:ddf8be195f69ad767b40d5c3fec3a8a85482bf6bf469d949a462cb4fd27df580 `})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`6.14.1 sha256:ddf8be195f69ad767b40d5c3fec3a8a85482bf6bf469d949a462cb4fd27df580 `})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`6.14.0 sha256:32082e8ac0bba9ee2a3f95534f52c94f5a41dc642bb396c73b04fa18aff147d7 `})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`6.13.0 sha256:37312e975dc9bc6c1f4ebccc90f55caf2d35ce15f1b0f59794348924fa0193e9 `})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`6.12.0 sha256:99bdcbc42933bd0d14c0c5496541059063f0c111393f5b773cd0e2bbf6bed435 `})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`6.11.2 sha256:12b1fa57fdf554110a1ec3519d02f69a6896515967d652029bc953a7e988ff29 `})}),`\n`]})})})]})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent};function _missingMdxReference(id,component){throw new Error(`Expected `+(component?`component`:`object`)+\" `\"+id+\"` to be defined: you likely forgot to import, pass, or provide it.\")}","frontmatter":{},"scope":{"codeStyling":"system","config":{},"pageMetadata":{"title":"Module Publishing","sidebarTitle":"Publishing module versions","description":"Version and publish modules as OCI artifacts.","href":"/cue/module/publishing"}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[{"title":"Artifact format","slug":"artifact-format","depth":2,"children":[]},{"title":"Version format","slug":"version-format","depth":2,"children":[]},{"title":"Building modules without a registry","slug":"building-modules-without-a-registry","depth":2,"children":[]},{"title":"Publishing module versions","slug":"publishing-module-versions","depth":2,"children":[{"title":"Stable versions","slug":"stable-versions","depth":3,"children":[]},{"title":"Pre-release versions","slug":"pre-release-versions","depth":3,"children":[]},{"title":"Latest version","slug":"latest-version","depth":3,"children":[]},{"title":"Ignoring files","slug":"ignoring-files","depth":3,"children":[]},{"title":"Symbolic links","slug":"symbolic-links","depth":3,"children":[]}]},{"title":"Listing module versions","slug":"listing-module-versions","depth":2,"children":[]}],"codeExamples":{}},"jsLinks":[],"subdomain":"timoni","siteName":"Timoni","title":"Module Publishing - Timoni","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-10-21T17:16:20.271Z","originalFileLocation":"cue/module/publishing.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"system\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"Version and publish modules as OCI artifacts.\">\u003cmeta data-mint-head name=\"application-name\" content=\"Timoni\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/timoni/wBHd5XBsu-JLPEJB/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/mintlify-assets/_mintlify/favicons/timoni/wBHd5XBsu-JLPEJB/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/timoni/wBHd5XBsu-JLPEJB/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/timoni/wBHd5XBsu-JLPEJB/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/timoni/wBHd5XBsu-JLPEJB/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/timoni/wBHd5XBsu-JLPEJB/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/timoni/wBHd5XBsu-JLPEJB/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/timoni/wBHd5XBsu-JLPEJB/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/timoni/wBHd5XBsu-JLPEJB/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"Module Publishing - Timoni\">\u003cmeta data-mint-head property=\"og:description\" content=\"Version and publish modules as OCI artifacts.\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"Timoni\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://timoni.sh/cue/module/publishing\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://timoni.mintlify.site/_mintlify/api/og/v2?division=Module+Distribution\u0026amp;title=Module+Publishing\u0026amp;description=Version+and+publish+modules+as+OCI+artifacts.\u0026amp;theme=75f94fd67070bb6be2c4d855\u0026amp;signature=71657401d0044b2cbe31ed9562b68036306c338d6b2549dd26d9635bfd55c4f2\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"Module Publishing - Timoni\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Version and publish modules as OCI artifacts.\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://timoni.mintlify.site/_mintlify/api/og/v2?division=Module+Distribution\u0026amp;title=Module+Publishing\u0026amp;description=Version+and+publish+modules+as+OCI+artifacts.\u0026amp;theme=75f94fd67070bb6be2c4d855\u0026amp;signature=71657401d0044b2cbe31ed9562b68036306c338d6b2549dd26d9635bfd55c4f2\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/mintlify-assets/_mintlify/favicons/timoni/wBHd5XBsu-JLPEJB/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"Timoni\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#7e56c2\">\u003cmeta data-mint-head name=\"twitter:creator\" content=\"@stefanprodan\">\u003clink data-mint-head rel=\"canonical\" href=\"https://timoni.sh/cue/module/publishing\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/cue/module/publishing.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://timoni.sh/#organization\",\"name\":\"Timoni\",\"url\":\"https://timoni.sh\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/timoni/8xOqj2ulwazG1u2D/images/logo_text_black.svg?fit=max\u0026auto=format\u0026n=8xOqj2ulwazG1u2D\u0026q=85\u0026s=85ffbf62ec541a621a19255513199222\"}},{\"@type\":\"WebSite\",\"@id\":\"https://timoni.sh#website\",\"name\":\"Timoni\",\"url\":\"https://timoni.sh\",\"publisher\":{\"@id\":\"https://timoni.sh/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://timoni.sh/cue/module/publishing#webpage\",\"url\":\"https://timoni.sh/cue/module/publishing\",\"name\":\"Module Publishing\",\"description\":\"Version and publish modules as OCI artifacts.\",\"dateModified\":\"2026-10-21T17:16:20.271Z\",\"isPartOf\":{\"@id\":\"https://timoni.sh#website\"},\"breadcrumb\":{\"@id\":\"https://timoni.sh/cue/module/publishing#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://timoni.sh/cue/module/publishing#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Timoni\",\"item\":\"https://timoni.sh\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Module Publishing\",\"item\":\"https://timoni.sh/cue/module/publishing\"}]},{\"@type\":[\"Article\",\"TechArticle\"],\"@id\":\"https://timoni.sh/cue/module/publishing#article\",\"headline\":\"Module Publishing\",\"name\":\"Module Publishing\",\"description\":\"Version and publish modules as OCI artifacts.\",\"url\":\"https://timoni.sh/cue/module/publishing\",\"mainEntityOfPage\":{\"@id\":\"https://timoni.sh/cue/module/publishing#webpage\"},\"dateModified\":\"2026-10-21T17:16:20.271Z\",\"publisher\":{\"@id\":\"https://timoni.sh/#organization\"},\"isPartOf\":{\"@id\":\"https://timoni.sh#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"Timoni\",\"publisher\":{\"@type\":\"Organization\",\"name\":\"Timoni\"},\"provider\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","agentPointerHref":"/cue/module/publishing.md","siteName":"Timoni","nav":{"global":null,"tabs":[{"tab":"Documentation","icon":"book-open","pages":[{"title":"Documentation","href":"/quickstart"}]},{"tab":"CUE Reference","icon":"code","groups":[{"group":"CUE Language","pages":[{"title":"CUE Language","sidebarTitle":"Introduction","href":"/cue/introduction"},{"title":"CUE Features Walkthrough","sidebarTitle":"CUE Walkthrough","href":"/cue/walkthrough"}]},{"group":"Module Development","pages":[{"title":"Get Started with Timoni Modules","sidebarTitle":"Get started with modules","href":"/cue/module/initialization"},{"title":"Immutable ConfigMaps and Secrets","href":"/cue/module/immutable-config"},{"title":"Embedding files","href":"/cue/module/embedding-files"},{"title":"Kubernetes Custom Resources","sidebarTitle":"Add custom resources","href":"/cue/module/custom-resources"},{"title":"Kubernetes Version Constraints","sidebarTitle":"Cluster version constraints","href":"/cue/module/semver-constraints"},{"title":"Control the Apply Behavior","sidebarTitle":"Control the apply behavior","href":"/cue/module/apply-behavior"},{"title":"Custom Health Checks","sidebarTitle":"Custom health checks","href":"/cue/module/health-checks"},{"title":"Run tests with Kubernetes Jobs","href":"/cue/module/test-jobs"},{"title":"Import Kubernetes Resources from YAML","sidebarTitle":"Import resources from YAML","description":"Convert existing Kubernetes YAML manifests to CUE templates.","href":"/cue/module/import-resources"}]},{"group":"Module Distribution","pages":[{"title":"Module Publishing","sidebarTitle":"Publishing module versions","href":"/cue/module/publishing"},{"title":"Module Signing and Verification","sidebarTitle":"Signing and Verification","description":"Sign module artifacts with Cosign or Notation and verify them at apply time.","href":"/cue/module/signing"},{"title":"Module Distribution with GitHub Actions","sidebarTitle":"GitHub Actions","href":"/cue/module/github-actions"}]}]},{"tab":"CLI Reference","icon":"terminal","pages":[{"title":"CLI Reference","href":"/cmd/timoni"}]}]},"basePath":"","title":"Module Publishing - Timoni","buildId":"dpl_Fyv1NbzwP68g2bEH2Roy98uY1zmE","deploymentId":"dpl_Fyv1NbzwP68g2bEH2Roy98uY1zmE","dynamics":[],"chunks":[]}