Skip to content

Commit

Permalink
Merge pull request #5765 from DataInMotion/5761
Browse files Browse the repository at this point in the history
Adds support for extra staging repository
  • Loading branch information
juergen-albert authored Sep 7, 2023
2 parents 40e21c3 + 33e9fe8 commit 7d05252
Show file tree
Hide file tree
Showing 9 changed files with 131 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ public interface Configuration {
*/
String releaseUrl();

/**
* The url of the staging release repository.
*/
String stagingUrl();

/**
* The urls to the remote snapshot repository.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -646,6 +646,13 @@ synchronized boolean init() {
List<MavenBackingRepository> snapshot = MavenBackingRepository.create(configuration.snapshotUrl(), reporter,
localRepo, client);

MavenBackingRepository staging = null;

if (configuration.stagingUrl() != null) {
staging = MavenBackingRepository.getBackingRepository(configuration.stagingUrl(),
reporter, localRepo, client);
}

for (MavenBackingRepository mbr : release) {
if (mbr.isRemote()) {
remote = true;
Expand All @@ -660,7 +667,8 @@ synchronized boolean init() {
}
}

storage = new MavenRepository(localRepo, name, release, snapshot, client.promiseFactory()
storage = new MavenRepository(localRepo, name, release, staging, snapshot,
client.promiseFactory()
.executor(), reporter);

File indexFile = getIndexFile();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ public class MavenRepository implements IMavenRepo, Closeable {
private final File base;
private final String id;
private final List<MavenBackingRepository> release = new ArrayList<>();
private final MavenBackingRepository stagingRepository;
private final List<MavenBackingRepository> snapshot = new ArrayList<>();
private final PromiseFactory promiseFactory;
private final boolean localOnly;
Expand All @@ -48,8 +49,15 @@ public class MavenRepository implements IMavenRepo, Closeable {

public MavenRepository(File base, String id, List<MavenBackingRepository> release,
List<MavenBackingRepository> snapshot, Executor executor, Reporter reporter) throws Exception {
this(base, id, release, null, snapshot, executor, reporter);
}

public MavenRepository(File base, String id, List<MavenBackingRepository> release,
MavenBackingRepository stagingRepository, List<MavenBackingRepository> snapshot, Executor executor,
Reporter reporter) throws Exception {
this.base = base;
this.id = id;
this.stagingRepository = stagingRepository;
if (release != null)
this.release.addAll(release);
if (snapshot != null)
Expand Down Expand Up @@ -114,7 +122,13 @@ public Release release(final Revision revision, final Properties context) throws
if (revision.isSnapshot()) {
return new SnapshotReleaser(this, revision, snapshot.isEmpty() ? null : snapshot.get(0), context);
}
return new Releaser(this, revision, release.isEmpty() ? null : release.get(0), context);

MavenBackingRepository releaseRepo = stagingRepository;
if (releaseRepo == null) {
releaseRepo = release.isEmpty() ? null : release.get(0);
}

return new Releaser(this, revision, releaseRepo, context);
}

@Override
Expand Down
2 changes: 1 addition & 1 deletion biz.aQute.repository/src/aQute/maven/provider/packageinfo
Original file line number Diff line number Diff line change
@@ -1 +1 @@
version 2.5
version 2.6
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
Expand Down Expand Up @@ -73,6 +74,7 @@ public class MavenBndRepoTest {
File tmp;
File local;
File remote;
File staging;
File index;

private MavenBndRepository repo;
Expand All @@ -83,9 +85,11 @@ public class MavenBndRepoTest {
public void setUp() throws Exception {
local = IO.getFile(tmp, "local");
remote = IO.getFile(tmp, "remote");
staging = IO.getFile(tmp, "staging");
index = IO.getFile(tmp, "index");
remote.mkdirs();
local.mkdirs();
staging.mkdirs();

IO.copy(IO.getFile("testresources/mavenrepo"), remote);
IO.copy(IO.getFile("testresources/mavenrepo/index.maven"), index);
Expand Down Expand Up @@ -1239,4 +1243,45 @@ public void testPutBundledWithMetaInfMaven() throws Exception {
assertNotNull(file);
}

@Test
public void testPutReleaseWithStaging() throws Exception {
Workspace ws = new Workspace(IO.getFile("testdata/releasews"));
Project p1 = ws.getProject("p1");
Project indexProject = ws.getProject("index");

Map<String, String> map = new HashMap<>();
map.put("releaseUrl", remote.toURI()
.toString());
map.put("stagingUrl", staging.toURI()
.toString());
p1.set("-pom", "true");
config(ws, map);

repo.begin(indexProject);
File jar = IO.getFile("testresources/mavenrepo/org/osgi/org.osgi.dto/1.0.0/org.osgi.dto-1.0.0.jar");
PutOptions po = new PutOptions();
po.context = p1;
PutResult put = repo.put(new FileInputStream(jar), po);
assertTrue(put.alreadyReleased);

File demoJar = IO.getFile("testresources/demo.jar");
PutOptions indexPo = new PutOptions();
indexPo.context = indexProject;
put = repo.put(new FileInputStream(demoJar), indexPo);
assertFalse(put.alreadyReleased);

repo.end(indexProject);

assertTrue(indexProject.check());
assertFalse(IO.getFile(remote, "biz/aQute/bnd/demo/1.0.0/demo-1.0.0-index.xml")
.isFile());
assertTrue(IO.getFile(staging, "biz/aQute/bnd/demo/1.0.0/demo-1.0.0-index.xml")
.isFile());

assertTrue(IO.getFile(remote, "org/osgi/org.osgi.dto/1.0.0/org.osgi.dto-1.0.0.jar")
.isFile());
assertFalse(IO.getFile(staging, "org/osgi/org.osgi.dto/1.0.0/org.osgi.dto-1.0.0.jar")
.isFile());
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.osgi</groupId>
<artifactId>org.osgi.dto</artifactId>
<version>1.0.0</version>
<description>OSGi Companion Code for org.osgi.dto Version 1.0.0.</description>
<name>org.osgi:org.osgi.dto</name>
<url>http://www.osgi.org/</url>
<organization>
<name>OSGi Alliance</name>
<url>http://www.osgi.org/</url>
</organization>
<licenses>
<license>
<name>Apache License, Version 2.0</name>
<url>http://opensource.org/licenses/apache2.0.php</url>
<distribution>repo</distribution>
</license>
</licenses>
<scm>
<url>https://osgi.org/git/build.git</url>
<connection>scm:git:https://osgi.org/git/build.git</connection>
<developerConnection>scm:git:https://osgi.org/git/build.git</developerConnection>
</scm>
<developers>
<developer>
<id>osgi</id>
<email>[email protected]</email>
<name>OSGi Alliance</name>
<organization>OSGi Alliance</organization>
</developer>
</developers>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
a1638f7dbb775f2dd9389a6e14a60b5ca90e932c
10 changes: 2 additions & 8 deletions docs/_instructions/maven-release.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,7 @@ If `sources` or `javadoc` has the attribute `force=true`, either one will be rel

The `aQute.maven.bnd.MavenBndRepository` is a bnd plugin that represent the local and a remote Maven repository. The locations of both repositories can be configured. The local repository is always used as a cache for the remote repository.

The repository has the following parameters:

* `url` – The remote repository URL. Credentials and proxy can be set with the [Http Client options]. The url should be the base url of a Maven repository. If no URL is configured, there is no remote repository.
* `local` – (`~/.m2/repository`) The location of the local repository. By default this is `~/.m2/repository`. It is not possible to not have a local repository because it acts as the cache.
* `generate` – (`JAVADOC,SOURCES`) A combination of `JAVADOC` and/or `SOURCES`. If no `-maven-release` instruction is found and the released artifact contains source code, then the given classifiers are used to generate them.
* `readOnly` – (`false`) Indicates if this is a read only repository
* `name` – The name of the repository
For a detailed configuration of the [Maven Bnd Repository Plugin][1], please look at the documentation page.

If the Maven Bnd Repository is asked to put a file, it will look up the `-maven-release` instruction using merged properties. The property is looked up from the bnd file that built the artifact. However, it should in general be possible to define this header in the workspace using macros like `${project}` to specify relative paths.

Expand All @@ -58,7 +52,7 @@ For example:
archive;\
path=files/feature.json;
classifier=feature

# Signing

If the instruction contains the sign attribute and release build is detected the repository tries to apply [gnupg](https://gnupg.org/) via a command process to create `.asc` files for all deployed artifacts. This requires a Version of [gnupg](https://gnupg.org/) installed on your build system. By default it uses the `gpg` command. If the `passphrase` is configured, it will hand it over to the command as standard input. The command will be constructed as follows: `gpg --batch --passphrase-fd 0 --output <filetosign>.asc --detach-sign --armor <filetosign>`. Some newer gnupg versions will ignore the passphrase via standard input for the first try and ask again with password screen. This will crash the process. Have a look [here](https://stackoverflow.com/questions/19895122/how-to-use-gnupgs-passphrase-fd-argument) to teach gnupg otherwise. The command can be exchanged or amended with additional options by defining a property named `gpg` in your workspace (e.g. `build.bnd` or somewhere in the ext directory).
Expand Down
20 changes: 19 additions & 1 deletion docs/_plugins/maven.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,23 @@ To access Maven Central use the following configuration:

You can add `Group:Artifact:Version` coordinates in the `central.maven` file. The file can contain comments, empty lines, and can use macros per line. That is, you cannot create a macro with a load of GAV's.

#### Release to Maven Central

Releasing to maven Central requires usually a couple of steps. For one you usually go through a staging repositroy like the staging nexus of sonartype. They perform a couple of checks and you manually have to clear the release via their web frontend.

In case you version your bundles individually, e.g. sonartype will not complain if a Version of one Artifact in your staging repo already exists. The release will simply not work. Thus you can define a staging repository. The Release process will check against the releaseUrl if something already exists, but will upload to the staging URL.

A configuration can look like this:

-plugin.release = \
aQute.bnd.repository.maven.provider.MavenBndRepository; \
releaseUrl=https://repo.maven.apache.org/maven2/; \
stagingUrl=https://oss.sonatype.org/service/local/staging/deploy/maven2/; \
index=${.}/release.maven; \
name="Release"



### Use of .m2 Local Repository

To use your local Maven repository (`~/.m2/repository`) you can define the following plugin:
Expand Down Expand Up @@ -63,6 +80,7 @@ The class name of the plugin is `aQute.bnd.repository.maven.provider.MavenBndRep
|------------------|-------|---------|-------------|
| `releaseUrl` | `URI` | | Comma separated list of URLs to the repositories of released artifacts.|
| `snapshotUrl` | `URI` | | Comma separated list of URLs to the repositories of snapshot artifacts.|
| `stagingUrl` | `URI` | | A single URL to the repositories staging repository. THis is required, e.g. for a release to maven central, which usually goes through a staging repository.|
| `local` | `PATH`| `~/.m2/repository` | The file path to the local Maven repository. |
| | | | If specified, it should use forward slashes. If the directory does not exist, the plugin will attempt to create it.|
| | | | The default can be overridden with the `maven.repo.local` System property.|
Expand All @@ -76,7 +94,7 @@ The class name of the plugin is `aQute.bnd.repository.maven.provider.MavenBndRep

If no `releaseUrl` nor a `snapshotUrl` are specified then the repository is _local only_.

For finding archives, both URLs are used, first `releaseUrl`.
For finding archives, both URLs are used. For releasing, only the first or the `stagingUrl` is used.

The `index` file specifies a view on the remote repository, it _scopes_ it. Since we use the bnd repositories to resolve against, it is impossible to resolve against the world. The index file falls under source control, it is stored in the source control management system. This guarantees that at any time the project is checked out it has the same views on its repository. This is paramount to prevent build breackages due to changes in repositories.

Expand Down

0 comments on commit 7d05252

Please sign in to comment.