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 | --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:tag
orgit
: 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-SNAPSHOT
git: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
gpg
binary 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 localgpg
binary 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-key
option 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