Publish ⚡️
The Publish command is restricted and requires setting the --power option to be used.
You can pass it explicitly or set it globally by running:
scala-cli config power true
The publish sub-command is an experimental feature.
Please bear in mind that non-ideal user experience should be expected. If you encounter any bugs or have feedback to share, make sure to reach out to the maintenance team on GitHub.
The publish sub-command allows to publish Scala CLI projects to Maven repositories.
We recommend running the publish setup sub-command once prior to
running publish, in order to set missing using directives for publishing, but this is not
mandatory.
Required settings
scala-cli publish and scala-cli publish local might complain about missing settings.
An organization, a name (or a module name), and (a way to compute) a version are needed, but Scala CLI may
be able to compute sensible defaults for them.
We recommend setting the settings below via using directives rather than on the command-line,
so that commands such as scala publish . or scala publish local . work fine for your
project. Command-line options for those settings take over the using directive values, and are
provided as a convenience.
This table lists settings allowing to specify those. See the sub-sections right after for more details.
using directive | Command-line option | Example values | Notes | |
|---|---|---|---|---|
| Organization | publish.organization | --organization | org.virtuslab.scala-cli | |
| Name | publish.name | --name | scala-cli | |
| Module Name | publish.moduleName | --module-name | scala-cli_3 | Module Name includes the Scala prefix, such as _2.13 or _3. Specifying Name should be favored over Module Name |
| Compute Version | publish.computeVersion | --compute-version | git:tag | |
| Version | publish.version | --project-version | 0.1.0, 0.1.1-SNAPSHOT | As much as possible, Compute Version (describing how to compute the version) should be favored over Version |
Organization
If your Scala CLI project lives in a git repository having a GitHub remote, Scala CLI
will infer an organization from it: if your project lives in GitHub organization foo
(that is, lives somewhere under https://github.com/foo/), Scala CLI will use
io.github.foo as default Maven organization.
To override this default value, set the publish.organization directive, like
//> using publish.organization io.github.foo
Name
Scala CLI will use the project directory name as default Maven name. That is, if your
Scala CLI project lives in a directory named something, it will be published as
something (pure Java project) or something_3 (Scala 3 project) for example.
To override this default value, set the publish.name directive, like
//> using publish.name something
Version
If your Scala CLI project lives in a git repository, Scala CLI will infer a way to compute
versions from it: if the current commit has a tag v1.2.3, version 1.2.3 is assumed.
Else, if it has such a tag earlier in the git history, version 1.2.4-SNAPSHOT is assumed.
To override this default value, set the publish.computeVersion directive, like
//> using publish.computeVersion git:tag
Please note that only tags that follow the semantic versioning are taken into consideration.
Values available for project version configuration are:
git:tagorgit: use the latest stable git tag, if it is older than HEAD then try to increment it and add a suffix-SNAPSHOT, if no tag is available then use0.1.0-SNAPSHOTgit:dynver: use the latest (stable or unstable) git tag, if it is older than HEAD then use the output of-{distance from last tag}-g{shortened version of HEAD commit hash}-SNAPSHOT, if no tag is available then use0.1.0-SNAPSHOT
The difference between stable and unstable tags are, that the latter can contain letters, e.g. v0.1.0-RC1.
It is also possible to specify the path to the repository, e.g. git:tag:../my-repo, git:dynver:../my-repo.
Repository settings
A repository is required for the publish command, and might need other settings to work fine
(to pass credentials for example). See Repositories for more information.
When publishing from you CI, we recommend letting scala-cli publish setup
setting those settings via using directives. When publishing from your local machine to Maven Central,
we recommend setting the repository via a publish.repository directive, and keeping your
Sonatype credentials in the Scala CLI settings, via commands such as
scala-cli config publish.credentials s01.oss.sonatype.org env:SONATYPE_USER env:SONATYPE_PASSWORD
using directive | Command-line option | Example values | Notes | |
|---|---|---|---|---|
| Repository | publish.repository | --publish-repository | central, central-s01, github, https://artifacts.company.com/maven |
Other settings
A number of metadata can be set either by using directives, or from the command-line. These
metadata are optional in the publish local command, but might be mandatory for some repositories
in the publish command, like Maven Central for non-snapshot versions.
We recommend setting the settings below via using directives rather than on the command-line,
so that these don't have to be recalled for each scala-cli publish or scala-cli publish local
invocation. Command-line options for those settings take over the using directive values, and are
provided as a convenience.
using directive | Command-line option | Example values | Notes | |
|---|---|---|---|---|
| License | publish.license | --license | Apache-2.0, MIT, Foo:https://foo.com/license.txt, … | Run scala-cli publish --license list to list pre-defined licenses |
| URL | publish.url | --url | ||
| VCS | publish.vcs | --vcs | github:VirtusLab/scala-cli, https://github.com/VirtusLab/scala-cli.git | scm:git:github.com/VirtusLab/scala-cli.git |
| Developers | publish.developer | --developer | alexme|Alex Me|https://alex.me | Can be specified multiple times, using directives and CLI values add up |
| Docs | publish.doc | --doc | --doc=false, //> using doc false | Use to disable publishing docs jar. |
Signing
Scala CLI can sign the artifacts it publishes with PGP signatures. Signing in Scala CLI can be handled by either
- the Bouncy Castle library (default, recommended)
- the local
gpgbinary on your machine
A signing mechanism will be chosen based on options and directives specified,
it can also be overriden with --signer with one of the values:
bc- Bouncy Castle library will be used for signing, PGP secret key is requiredgpg- a localgpgbinary will be used for signing, GPG key ID is requirednone- NO signing will take place
Bouncy Castle
Bouncy Castle library is the quickest way of signing artifacts with Scala CLI. A benefit of using it is that it has no external dependencies, Scala CLI is able to sign things with Bouncy Castle without further setup on your side. However, it does not provide a complex PGP handling functionality as e.g. GPG does.
When the --signer option is not specified Bouncy Castle library will be used for signing
if one of these conditions occur:
- the
--secret-keyoption has been passed - target repository requires signing (e.g.
central)
To succesfully use PGP signing with Bouncy Castle a PGP key pair is required. Scala CLI can generate and keep PGP keys for you by using:
scala-cli --power config --create-pgp-key --pgp-password MY_CHOSEN_PASSWORD
It's not mandatory, although recomended, to use a password to encrypt your keychains.
To store the private keychain in an unencrypted form use --pgp-password none.
To randomly generate a pasword, use --pgp-password random instead.
The generated values are kept in the config and will be used by default unless specified otherwise:
-
with directives:
//> using publish.secretKey env:PGP_SECRET
//> using publish.secretKeyPassword command:get_my_password -
with options:
scala-cli --power publish \
--secret-key env:PGP_SECRET \
--secret-key-password file:pgp_password.txt \
…
Since these values should be kept secret, the options and directives accept the format documented here.
GPG
Using GPG to sign artifacts requires the gpg binary to be installed on your system.
A benefit of using gpg to sign artifacts over Bouncy Castle is: you can use keys from
your GPG key ring, or from external devices that GPG may support.
To get started, consult the documentation on the library's website and be sure to read about Protecting code integrity with PGP guide from the Linux Foundation.
To enable signing with GPG, pass --gpg-key *key_id* on the command line
or specify it with a using directive: //>using publish.gpgKey key_id.
If needed, you can specify arguments meant to be passed to gpg,
with --gpg-option or //>using publish.gpgOptions --opt1 --opt2, like
--gpg-key 1234567890ABCDEF --gpg-option --foo --gpg-option --bar
Checksums
Scala CLI can generate checksums of the artifacts it publishes.
By default, Scala CLI generates SHA-1 and MD5 checksums. To disable checksums,
pass --checksum none. To generate checksum formats to generate, pass them via
--checksum, separating the checksum values with , or using --checksum multiple
times:
--checksum sha1,md5
--checksum sha1 --checksum md5
To list supported checksum types, pass --checksum list.
CI overrides
Scala CLI allows some publishing-related settings to have different values on your local machine and on CIs. In particular, this can be convenient to handle credentials and signing parameters, as these can be read from different locations on developers' machines and on CIs.
On CIs (when CI is set in the environment, whatever its value), the CI override is
used if it's there. Else the main directive is used.
| Settings | Directive | CI override directive |
|---|---|---|
| Compute Version | publish.computeVersion | publish.ci.computeVersion |
| Repository | publish.repository | publish.ci.repository |
| Repository User | publish.user | publish.ci.user |
| Repository Password | publish.password | publish.ci.password |
| Repository Realm | publish.realm | publish.ci.realm |
| Secret Key | publish.secretKey | publish.ci.secretKey |
| Secret Key Password | publish.secretKeyPassword | publish.ci.secretKeyPassword |
| GPG key | publish.gpgKey | publish.ci.gpgKey |
| GPG options | publish.gpgOptions | publish.ci.gpgOptions |
Repositories
Maven Central
Right now the easiest way to publish to Maven Central Repository is to use
Sonatype repositories - s01.oss.sonatype.org or oss.sonatype.org
Since 25.02.2021 s01 is the default server for new users, if your account is older than that
you probably need to use the legacy oss.sonatype.org. More about this here.
Use central as repository to push artifacts to Maven Central via oss.sonatype.org.
To push to it via s01.oss.sonatype.org, use central-s01.
When using central or central-s01 as repository, artifacts are pushed
either to https://oss.sonatype.org/content/repositories/snapshots (versions
ending in SNAPSHOT) or to https://oss.sonatype.org/staging/deploy/maven2
(in that case, Sonatype API endpoints are called to "close" and "release"
artifacts, which later syncs them to https://repo1.maven.org/maven2).
GitHub Packages
Use github (GitHub organization and name computed from the git remotes)
or github:org/name (replace org and name by the GitHub organization and name
of your repository, like github:VirtusLab/scala-cli)
to push artifacts to GitHub Packages.
Note that, as of writing this, this disables parallel uploading of artifacts, checksums, and signing (all not supported by GitHub Packages as of writing this).
Ivy2 Local
Use ivy2Local to put artifacts in the local Ivy2 repository, just like how
publish local does.
Other pre-defined repositories
All pre-defined repositories accepted by coursier, such as jitpack or sonatype:snapshots, are accepted as repositories for publishing.
Generic Maven repositories
Pass a URL (beginning with http:// or https://) to push to custom
HTTP servers. Pushing to such repositories relies on HTTP PUT requests
(just like for the pre-defined repositories above).
You can also pass a path to a local directory, absolute (recommended) or relative (beware of name clashes with pre-defined repositories above).
Authentication
Specify publish repository authentication either on the command-line or via using directives. See user / password / realm in the settings table and the CI overrides.
Connection parameters configuration
When publishing large packages or when the internet connection is spotty one may use the following options to configure the connection parameters:
--connection-timeout-seconds- the connection timeout in seconds--response-timeout-seconds- the response timeout in seconds--connection-timeout-retries- the number of times to retry the connection on timeout
Publishing to Sonatype uses a staging repository which may sometimes cause problems when transitioning through states.
If a publishing process fails with status 500 and message "Staging repository is already transitioning" you can try to tweak the following parameters taht are Sonatype specific:
--staging-repo-retries- the number of times to retry the staging repository transition--staging-repo-wait-time-milis- the base time to wait between retries in milliseconds
Publishing
Once all the necessary settings are set, publish a Scala CLI project with a command such as this one:
scala-cli --power publish .
(. is for the Scala CLI project in the current directory)
Publishing io.github.scala-cli:hello-scala-cli_3:0.1.0-SNAPSHOT
✔ Computed 8 checksums
🚚 Wrote 12 files
👀 Check results at
https://s01.oss.sonatype.org/content/repositories/snapshots/io/github/scala-cli/hello-scala-cli_3/0.1.0-SNAPSHOT
The publish local sub-command does not currently support publishing of the test scope.
This includes any file that is placed in test directory or with the .test.scala suffix.
Read more about test sources in testing documentation.