Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions .github/workflows/docker-push.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.

name: Push Sling Committer CLI Docker image

on:
Comment thread
rombert marked this conversation as resolved.
workflow_dispatch:
push:
branches:
- master

permissions:
contents: read

concurrency:
group: docker-push
cancel-in-progress: false

jobs:
sling-committer-cli-push-image:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v7
- name: Set up JDK 21
uses: actions/setup-java@v5
with:
distribution: 'temurin'
java-version: '21'
cache: 'maven'
- name: Login to Docker Hub
id: login-docker-hub
uses: docker/login-action@af1e73f918a031802d376d3c8bbc3fe56130a9b0
with:
username: ${{ secrets.DOCKERHUB_USER }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Set up QEMU # https://github.com/docker/buildx/issues/499
uses: docker/setup-qemu-action@ce360397dd3f832beb865e1373c09c0e9f86d70a
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd
- name: Push Docker image
run: mvn --batch-mode install docker:push -Ddocker.platforms=linux/amd64,linux/arm64
30 changes: 15 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,27 +89,27 @@ password in `~/.m2/settings-security.xml`:

## Building

The Docker image (`apache/sling-cli:latest`) is produced by the `docker:build` goal of the
The Docker image (`apache/sling-committer-cli:latest`) is produced by the `docker:build` goal of the
[fabric8 docker-maven-plugin](https://dmp.fabric8.io/). The image bundles the project jar via the
generated `*-app.slingfeature` descriptor; the `slingfeature-maven-plugin` resolves the project's
own bundle from the reactor, so the image always contains the jar built in the same invocation.

A single command builds (and tests) the project and the image:

mvn clean package docker:build
mvn clean install

No prior `mvn install` is needed. The `docker:build` execution is also bound to the `package`
phase, so the CI build (`mvn package`) builds the image too.
The `docker:build` execution is bound to the `package` phase, so `mvn package` and later phases
build the image too. Image pushes are never part of the lifecycle; invoke `docker:push` explicitly.

To confirm the image contains the expected commands:

docker run --env-file=./docker-env apache/sling-cli release help
docker run --env-file=./docker-env apache/sling-committer-cli release help

## Launching

After building, run the image with:

docker run --env-file=./docker-env apache/sling-cli
docker run --env-file=./docker-env apache/sling-committer-cli

This invocation produces a list of available commands.

Expand All @@ -124,7 +124,7 @@ The commands can be executed in 3 different modes:

To select a non-default execution mode provide the mode as an argument to the command:

docker run -it --env-file=./docker-env apache/sling-cli release prepare-email --repository=$STAGING_REPOSITORY
docker run -it --env-file=./docker-env apache/sling-committer-cli release prepare-email --repository=$STAGING_REPOSITORY
--execution-mode=INTERACTIVE

Note that for running commands in the `INTERACTIVE` mode you need to run the Docker container in interactive mode with a pseudo-tty
Expand Down Expand Up @@ -168,46 +168,46 @@ After `release:perform` has staged the artifacts, drive the rest with the CLI:
0. **Find the staging repository id** if you did not capture it. `release list` shows every staging
repo with its `[open]`/`[closed]` state and description; a freshly staged one is `[open]`:

docker run --env-file=./docker-env apache/sling-cli release list
docker run --env-file=./docker-env apache/sling-committer-cli release list

1. **Close** the staging repository. The description is derived automatically from the staged POM's
`<name>` + `<version>` (e.g. _Apache Sling Feature Model Launcher 1.3.6_) by browsing the
repository content, so it works even though an open repository is not yet in the Lucene index:

docker run --env-file=./docker-env apache/sling-cli release close-staging --repository=$STAGING_REPOSITORY_ID --execution-mode=AUTO
docker run --env-file=./docker-env apache/sling-committer-cli release close-staging --repository=$STAGING_REPOSITORY_ID --execution-mode=AUTO

2. **Verify** the artifacts' signatures, hashes and CI status:

docker run --env-file=./docker-env apache/sling-cli release verify --repository=$STAGING_REPOSITORY_ID
docker run --env-file=./docker-env apache/sling-committer-cli release verify --repository=$STAGING_REPOSITORY_ID

3. **Generate the vote email**:

docker run --env-file=./docker-env apache/sling-cli release prepare-email --repository=$STAGING_REPOSITORY_ID --execution-mode=AUTO
docker run --env-file=./docker-env apache/sling-committer-cli release prepare-email --repository=$STAGING_REPOSITORY_ID --execution-mode=AUTO

4. After the 72h vote, **tally the votes** and generate the result email. PMC membership is detected
automatically from your ASF id: if you are a PMC member the email says you will copy the release to
the dist directory yourself; otherwise it asks a PMC member to perform the dist upload:

docker run --env-file=./docker-env apache/sling-cli release tally-votes --repository=$STAGING_REPOSITORY_ID --execution-mode=AUTO
docker run --env-file=./docker-env apache/sling-committer-cli release tally-votes --repository=$STAGING_REPOSITORY_ID --execution-mode=AUTO

5. **Finalize** the release (post successful vote). This runs, in order: promote to Maven Central,
create the next Jira version, release the current Jira version, and update the Apache Reporter:

docker run --env-file=./docker-env apache/sling-cli release finalize --repository=$STAGING_REPOSITORY_ID --execution-mode=AUTO
docker run --env-file=./docker-env apache/sling-committer-cli release finalize --repository=$STAGING_REPOSITORY_ID --execution-mode=AUTO

When the current user is detected as a PMC member, `finalize` additionally publishes to
`dist.apache.org` (requires `subversion`, which is bundled in the image). The previous version to
remove from `dist/release` is deduced automatically from the directory contents, so no extra flag
is needed:

docker run --env-file=./docker-env apache/sling-cli release finalize --repository=$STAGING_REPOSITORY_ID --execution-mode=AUTO
docker run --env-file=./docker-env apache/sling-committer-cli release finalize --repository=$STAGING_REPOSITORY_ID --execution-mode=AUTO

PMC membership is determined from your ASF id (via Whimsy). A non-PMC committer's `finalize` skips
the dist upload and the `tally-votes` result email asks a PMC member to perform it.

If the vote does not pass, **drop** the staging repository:

docker run --env-file=./docker-env apache/sling-cli release drop --repository=$STAGING_REPOSITORY_ID --execution-mode=AUTO
docker run --env-file=./docker-env apache/sling-committer-cli release drop --repository=$STAGING_REPOSITORY_ID --execution-mode=AUTO

### Command reference

Expand Down
14 changes: 12 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@
<project.build.outputTimestamp>2026-01-01T00:00:01Z</project.build.outputTimestamp>
<sling.java.version>21</sling.java.version>
<bouncycastle.version>1.85</bouncycastle.version>
<docker.image.name>apache/sling-committer-cli</docker.image.name>
<docker.image.tag>latest</docker.image.tag>
<!-- pass a list of platforms to enable multi-arch builds: linux/amd64,linux/arm64 -->
<docker.platforms />
</properties>

<dependencies>
Expand Down Expand Up @@ -318,22 +322,28 @@
<configuration>
<images>
<image>
<name>apache/sling-cli</name>
<name>${docker.image.name}:${docker.image.tag}</name>
<build>
<contextDir>${project.basedir}</contextDir>
<args>
<FEATURE_FILE>target/artifacts/org/apache/sling/${project.artifactId}/${project.version}/${project.artifactId}-${project.version}-app.slingfeature</FEATURE_FILE>
</args>
<buildx>
<platforms>
<platform>${docker.platforms}</platform>
Comment thread
rombert marked this conversation as resolved.
</platforms>
</buildx>
</build>
</image>
</images>
</configuration>
<executions>
<execution>
<id>default</id>
<id>build-image</id>
<goals>
<goal>build</goal>
</goals>
<phase>package</phase>
</execution>
</executions>
</plugin>
Expand Down