Add option to create snapshot manifest from a branch point
Currently the snapshot manifests are stored like this:
refs/heads/m/master/some/manifest/default.xml
a---b---c---d---e
and if you tag commit 'a', you can use git-describe to reference all
subsequent commits.
This plugin also let you branch a set of repositories described by a
manifest and create a new manifest to point to the same set of
repositories at a new branch. So for example, you can tell the plugin
to branch at the snapshot manifest stored in commit 'c' and create a new
manifest back in the subscribing repository (master branch with path
release/1.0.xml, for example.) When any of the projects in the
subscribed repositories change, a snapshot manifest will be created.
In previous implementation, the new snapshot manifest branch is created
from head of the master branch (assuming pointing to 'a'),
refs/heads/m/master/some/manifest/default.xml
a---b---c---d---e
\
f
refs/heads/m/master/release/1.0.xml
With this commit, the user will have the option of pre-creating the
snapshot manifest of the newly created manifest at the point branching
was requested.
refs/heads/m/master/some/manifest/default.xml
a---b---c---d---e
\
f
refs/heads/m/master/release/1.0.xml
This will allow a system-level versioning using git-describe. For
example:
a---b---c---d---e
^ \ ^
v1.0 \ v1.2
\
f---g
^
v1.0-4-gc0ffee1
Change-Id: Ifba982d35c6f6af55200474d5ec090ba9758de36
diff --git a/src/main/java/com/amd/gerrit/plugins/manifestsubscription/BranchManifestCommand.java b/src/main/java/com/amd/gerrit/plugins/manifestsubscription/BranchManifestCommand.java
index 0f3ce1f..fd367a6 100644
--- a/src/main/java/com/amd/gerrit/plugins/manifestsubscription/BranchManifestCommand.java
+++ b/src/main/java/com/amd/gerrit/plugins/manifestsubscription/BranchManifestCommand.java
@@ -14,6 +14,7 @@
package com.amd.gerrit.plugins.manifestsubscription;
+import com.google.gerrit.common.ChangeHooks;
import com.google.gerrit.common.data.GlobalCapability;
import com.google.gerrit.extensions.annotations.RequiresCapability;
import com.google.gerrit.server.git.GitRepositoryManager;
@@ -34,6 +35,9 @@
@Inject
private MetaDataUpdate.Server metaDataUpdateFactory;
+ @Inject
+ private ChangeHooks changeHooks;
+
@Option(name = "-r", aliases = {"--manifest-repo"},
usage = "", required = true)
private String manifestRepo;
@@ -69,6 +73,11 @@
usage = "", required = false)
private String newManifestPath;
+ @Option(name = "-cs", aliases = {"--create-snapshot-branch"},
+ depends = {"-nb", "-nr", "-np"},
+ usage = "", required = false)
+ private boolean createSnapShotBranch;
+
@Override
protected void run() {
stdout.println("Branching manifest:");
@@ -79,10 +88,13 @@
stdout.println(newManifestRepo);
stdout.println(newManifestBranch);
stdout.println(newManifestPath);
+ stdout.println("Create snapshot branch: " + createSnapShotBranch);
- Utilities.branchManifest(gitRepoManager, metaDataUpdateFactory,
- manifestRepo, manifestCommitish, manifestPath, newBranch,
+ Utilities.branchManifest(gitRepoManager, metaDataUpdateFactory, changeHooks,
+ manifestRepo, manifestCommitish, manifestPath,
+ newBranch,
newManifestRepo, newManifestBranch, newManifestPath,
+ createSnapShotBranch,
stdout, stderr,
outputType==Utilities.OutputType.JSON);
diff --git a/src/main/java/com/amd/gerrit/plugins/manifestsubscription/BranchManifestServlet.java b/src/main/java/com/amd/gerrit/plugins/manifestsubscription/BranchManifestServlet.java
index 68a198a..aeb97f2 100644
--- a/src/main/java/com/amd/gerrit/plugins/manifestsubscription/BranchManifestServlet.java
+++ b/src/main/java/com/amd/gerrit/plugins/manifestsubscription/BranchManifestServlet.java
@@ -14,6 +14,7 @@
package com.amd.gerrit.plugins.manifestsubscription;
+import com.google.gerrit.common.ChangeHooks;
import com.google.gerrit.extensions.annotations.Export;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.git.MetaDataUpdate;
@@ -37,6 +38,9 @@
@Inject
private MetaDataUpdate.Server metaDataUpdateFactory;
+ @Inject
+ private ChangeHooks changeHooks;
+
protected void doPost(HttpServletRequest req, HttpServletResponse res)
throws IOException {
@@ -49,6 +53,7 @@
String newManifestRepo = null;
String newManifestBranch= null;
String newManifestPath = null;
+ boolean createSnapShotBranch = false;
if (input.containsKey("new-manifest-repo")) {
newManifestRepo = input.get("new-manifest-repo")[0];
@@ -56,16 +61,21 @@
newManifestPath = input.get("new-manifest-path")[0];
}
- Utilities.branchManifest(gitRepoManager,
- metaDataUpdateFactory,
- input.get("manifest-repo")[0],
- input.get("manifest-commit-ish")[0],
- input.get("manifest-path")[0],
- input.get("new-branch")[0],
- newManifestRepo,
- newManifestBranch,
- newManifestPath,
- res.getWriter(), null, true);
+ if (input.containsKey("create-snapshot-branch")) {
+ createSnapShotBranch =
+ Boolean.parseBoolean(input.get("create-snapshot-branch")[0]);
+ }
+
+ Utilities.branchManifest(
+ gitRepoManager, metaDataUpdateFactory, changeHooks,
+ input.get("manifest-repo")[0],
+ input.get("manifest-commit-ish")[0],
+ input.get("manifest-path")[0],
+ input.get("new-branch")[0],
+ newManifestRepo,
+ newManifestBranch,
+ newManifestPath,
+ createSnapShotBranch, res.getWriter(), null, true);
} else {
res.setStatus(HttpServletResponse.SC_BAD_REQUEST);
diff --git a/src/main/java/com/amd/gerrit/plugins/manifestsubscription/ManifestSubscription.java b/src/main/java/com/amd/gerrit/plugins/manifestsubscription/ManifestSubscription.java
index 0ecc2d2..4a51773 100644
--- a/src/main/java/com/amd/gerrit/plugins/manifestsubscription/ManifestSubscription.java
+++ b/src/main/java/com/amd/gerrit/plugins/manifestsubscription/ManifestSubscription.java
@@ -20,7 +20,6 @@
import com.google.gerrit.extensions.annotations.PluginName;
import com.google.gerrit.extensions.events.GitReferenceUpdatedListener;
import com.google.gerrit.extensions.events.LifecycleListener;
-import com.google.gerrit.reviewdb.client.Branch;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.git.MetaDataUpdate;
@@ -48,7 +47,7 @@
private static final String KEY_BRANCH = "branch";
private static final String KEY_STORE = "store";
- private static final String STORE_BRANCH_PREFIX = "refs/heads/m/";
+ static final String STORE_BRANCH_PREFIX = "refs/heads/m/";
private final String pluginName;
@@ -182,8 +181,9 @@
}
try {
- updateManifest(store, STORE_BRANCH_PREFIX + storeBranch,
- manifest, manifestSrc, extraCommitMsg.toString());
+ Utilities.updateManifest(gitRepoManager, metaDataUpdateFactory,
+ changeHooks, store, STORE_BRANCH_PREFIX + storeBranch,
+ manifest, manifestSrc, extraCommitMsg.toString(), null);
} catch (JAXBException | IOException e) {
e.printStackTrace();
}
@@ -454,61 +454,8 @@
private void updateManifest(String projectName, String refName,
Manifest manifest, String manifestSrc)
throws JAXBException, IOException {
- updateManifest(projectName, refName, manifest, manifestSrc, "");
- }
-
- private void updateManifest(String projectName, String refName,
- Manifest manifest, String manifestSrc,
- String extraCommitMsg)
- throws JAXBException, IOException {
- Project.NameKey p = new Project.NameKey(projectName);
- Repository repo = gitRepoManager.openRepository(p);
- MetaDataUpdate update = metaDataUpdateFactory.create(p);
- ObjectId commitId = repo.resolve(refName);
- VersionedManifests vManifests = new VersionedManifests(refName);
-
- //TODO find a better way to detect no branch
- boolean refExists = true;
- try {
- vManifests.load(update, commitId);
- } catch (Exception e) {
- refExists = false;
- }
-
-
- RevCommit commit = null;
- if (refExists) {
- Map<String, Manifest> entry = Maps.newHashMapWithExpectedSize(1);
- entry.put("default.xml", manifest);
- vManifests.setManifests(entry);
- vManifests.setSrcManifestRepo(manifestSrc);
- vManifests.setExtraCommitMsg(extraCommitMsg);
- commit = vManifests.commit(update);
- } else {
- vManifests = new VersionedManifests("master");
- try {
- vManifests.load(update);
- } catch (ConfigInvalidException e) {
- e.printStackTrace();
- }
- Map<String, Manifest> entry = Maps.newHashMapWithExpectedSize(1);
- entry.put("default.xml", manifest);
- vManifests.setManifests(entry);
- commit = vManifests.commitToNewRef(update, refName);
- }
-
- // TODO this may be bug in the MetaDataUpdate or VersionedMetaData
- // May be related:
- // https://code.google.com/p/gerrit/issues/detail?id=2564
- // https://gerrit-review.googlesource.com/55540
- if (commit != null) {
- changeHooks.doRefUpdatedHook(new Branch.NameKey(p, refName),
- commit.getParent(0).getId(),
- commit.getId(), null);
- } else {
- log.warn("Failing to commit manifest subscription update");
- }
-
+ Utilities.updateManifest(gitRepoManager, metaDataUpdateFactory, changeHooks,
+ projectName, refName, manifest, manifestSrc, "", null);
}
}
diff --git a/src/main/java/com/amd/gerrit/plugins/manifestsubscription/Utilities.java b/src/main/java/com/amd/gerrit/plugins/manifestsubscription/Utilities.java
index 5c5ce00..08e9807 100644
--- a/src/main/java/com/amd/gerrit/plugins/manifestsubscription/Utilities.java
+++ b/src/main/java/com/amd/gerrit/plugins/manifestsubscription/Utilities.java
@@ -14,8 +14,11 @@
package com.amd.gerrit.plugins.manifestsubscription;
+import com.google.common.base.Strings;
import com.google.common.base.Throwables;
import com.google.common.collect.Maps;
+import com.google.gerrit.common.ChangeHooks;
+import com.google.gerrit.reviewdb.client.Branch;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.git.MetaDataUpdate;
@@ -26,11 +29,13 @@
import com.amd.gerrit.plugins.manifestsubscription.manifest.Default;
import com.amd.gerrit.plugins.manifestsubscription.manifest.Manifest;
+import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevWalk;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -74,6 +79,67 @@
return false;
}
+ static ObjectId updateManifest(GitRepositoryManager gitRepoManager,
+ MetaDataUpdate.Server metaDataUpdateFactory,
+ ChangeHooks changeHooks,
+ String projectName, String refName,
+ Manifest manifest, String manifestSrc,
+ String extraCommitMsg,
+ String defaultBranchBase)
+ throws JAXBException, IOException {
+ Project.NameKey p = new Project.NameKey(projectName);
+ Repository repo = gitRepoManager.openRepository(p);
+ MetaDataUpdate update = metaDataUpdateFactory.create(p);
+ ObjectId commitId = repo.resolve(refName);
+ VersionedManifests vManifests = new VersionedManifests(refName);
+
+ //TODO find a better way to detect no branch
+ boolean refExists = true;
+ try {
+ vManifests.load(update, commitId);
+ } catch (Exception e) {
+ refExists = false;
+ }
+
+ RevCommit commit = null;
+ if (refExists) {
+ Map<String, Manifest> entry = Maps.newHashMapWithExpectedSize(1);
+ entry.put("default.xml", manifest);
+ vManifests.setManifests(entry);
+ vManifests.setSrcManifestRepo(manifestSrc);
+ vManifests.setExtraCommitMsg(extraCommitMsg);
+ commit = vManifests.commit(update);
+ } else {
+ if (defaultBranchBase == null) defaultBranchBase = "refs/heads/master";
+ vManifests = new VersionedManifests(defaultBranchBase);
+ ObjectId cid = repo.resolve(defaultBranchBase);
+ try {
+ vManifests.load(update, cid);
+ } catch (ConfigInvalidException e) {
+ e.printStackTrace();
+ }
+ Map<String, Manifest> entry = Maps.newHashMapWithExpectedSize(1);
+ entry.put("default.xml", manifest);
+ vManifests.setManifests(entry);
+ commit = vManifests.commitToNewRef(update, refName);
+ }
+
+ // TODO this may be bug in the MetaDataUpdate or VersionedMetaData
+ // May be related:
+ // https://code.google.com/p/gerrit/issues/detail?id=2564
+ // https://gerrit-review.googlesource.com/55540
+ if (commit != null) {
+ changeHooks.doRefUpdatedHook(new Branch.NameKey(p, refName),
+ commit.getParent(0).getId(),
+ commit.getId(), null);
+ return commit.getId();
+ } else {
+ log.warn("Failing to commit manifest subscription update");
+ }
+
+ return null;
+ }
+
public enum OutputType {
TEXT,
JSON
@@ -95,14 +161,15 @@
return manifests.getCanonicalManifest(manifestPath);
}
- static Manifest createNewManifestFromBase
- (GitRepositoryManager gitRepoManager,
- MetaDataUpdate.Server metaDataUpdateFactory,
- String manifestRepo,
- String manifestBranch,
- String manifestPath,
- String newRef,
- Manifest base)
+ static Manifest createNewManifestFromBase(
+ GitRepositoryManager gitRepoManager,
+ MetaDataUpdate.Server metaDataUpdateFactory,
+ ChangeHooks changeHooks,
+ String srcManifestRepo, String srcManifestCommitish,
+ String manifestRepo, String manifestBranch, String manifestPath,
+ String newRef,
+ boolean createSnapShotBranch,
+ Manifest base)
throws JAXBException, IOException, ConfigInvalidException, GitAPIException {
// Replace default ref with newly created branch or tag
@@ -141,6 +208,29 @@
manifest.getDefault().setRevision(newRef);
+ if (createSnapShotBranch) {
+ // Create the snapshot branch and tag it
+ // branch name is by convention for the new manifest to be created below
+
+ // current jgit Repository.resolve doesn't seem to resolve short-name
+ // properly. FIXME
+ String shortBranch = manifestBranch.replaceFirst("^refs/heads/(.*)", "$1");
+
+ ObjectId oid = Utilities.updateManifest(
+ gitRepoManager, metaDataUpdateFactory, changeHooks,
+ srcManifestRepo,
+ ManifestSubscription.STORE_BRANCH_PREFIX + shortBranch + "/" + manifestPath,
+ manifest, manifestRepo, "Manifest branched", srcManifestCommitish);
+
+// try (Repository db = gitRepoManager.openRepository(new Project.NameKey(srcManifestRepo));
+// Git git = new Git(db);
+// RevWalk walk = new RevWalk(db)) {
+// RevCommit commit = walk.parseCommit(oid);
+// git.tag().setName(createSnapShotBranch)
+// .setObjectId(commit).setAnnotated(true).call();
+// }
+ }
+
Project.NameKey p = new Project.NameKey(manifestRepo);
Repository repo = gitRepoManager.openRepository(p);
ObjectId commitId = repo.resolve(manifestBranch);
@@ -218,11 +308,13 @@
static void branchManifest(GitRepositoryManager gitRepoManager,
MetaDataUpdate.Server metaDataUpdateFactory,
+ ChangeHooks changeHooks,
String manifestRepo, String manifestCommitish,
String manifestPath, String newBranch,
String newManifestRepo,
String newManifestBranch,
String newManifestPath,
+ boolean createSnapShotBranch,
Writer output, PrintWriter error, boolean inJSON) {
Manifest manifest;
@@ -234,9 +326,11 @@
if (newManifestBranch != null &&
newManifestPath != null &&
newManifestRepo != null) {
- createNewManifestFromBase(gitRepoManager, metaDataUpdateFactory,
+ createNewManifestFromBase(
+ gitRepoManager, metaDataUpdateFactory, changeHooks,
+ manifestRepo, manifestCommitish,
newManifestRepo, newManifestBranch, newManifestPath,
- newBranch, manifest);
+ newBranch, createSnapShotBranch, manifest);
}
} catch (IOException | ConfigInvalidException | ManifestReadException |
diff --git a/src/main/resources/Documentation/cmd-branch.md b/src/main/resources/Documentation/cmd-branch.md
index a9ab868..d5c7899 100644
--- a/src/main/resources/Documentation/cmd-branch.md
+++ b/src/main/resources/Documentation/cmd-branch.md
@@ -16,8 +16,9 @@
{-b/--new-branch <new branch name>}
[-o/--output-type]
[-nr/--new-manifest-repo <new manifest repo>]
- [-nc/--new-manifest-branch <new manifest branch>]
+ [-nb/--new-manifest-branch <new manifest branch>]
[-np/--new-manifest-path <new manifest path>]
+ [-cs/--create-snapeshot-branch]
[--help]
```
@@ -41,19 +42,45 @@
`-np/--new-manifest-path <new manifest path>`
: (optional) A new manifest (to be created) that points to the new branch
+`-cs/--create-snapeshot-branch`
+: (optional, depends on -nr/-nb/-np) Create a new snapshot manifest branch for
+ the newly created manifest (as defined by -nr, -nb, -np) in the repository
+ defined by -r
+
EXAMPLES
--------
-Branch all projects on the server described in the `default.xml` manifest in commit 5f51acb585b6a of repo `demo/build_manifest` to branch `releases/1.0.0`
+Branch all projects on the server described in the `default.xml` manifest in
+commit 5f51acb585b6a of repo `demo/build_manifest` to branch `releases/1.0.0`
```
ssh -p @SSH_PORT@ @SSH_HOST@ @PLUGIN@ branch -r demo/build_manifest -c 5f51acb585b6a -p default.xml -b releases/1.0.0
```
-Branch all projects on the server described in the `default.xml` manifest in commit v0.9-15-g5f51acb of repo `demo/build_manifest` to branch `releases/1.0.0`
-```
-ssh -p @SSH_PORT@ @SSH_HOST@ @PLUGIN@ branch -r demo/build_manifest -c v0.9-15-g5f51acb -p default.xml -b releases/1.0.0
+Branch all projects on the server described in the `default.xml` manifest in
+commit v0.9-15-g5f51acb of repo `demo/build_manifest` to branch `releases/1.0.0`
+and create a new manifest with path `releases/1.0.0.xml` in repository
+`project/manifest` branch `master`.
```
+ssh -p @SSH_PORT@ @SSH_HOST@ @PLUGIN@ branch -r demo/build_manifest -c v0.9-15-g5f51acb -p default.xml -b releases/1.0.0 -nr project/manifest -nb master -np releases/1.0.0.xml -cs
+
+```
+
+In the following charts, commit 'c' is v0.9-15-g5f51acb.
+
+With -cs:
+```
+ a---b---c---d---e master
+ \
+ f m/master/releases/1.0.0.xml
+```
+
+Without -cs:
+```
+ a---b---c---d---e master
+ \
+ f m/master/releases/1.0.0.xml
+```
SEE ALSO
--------
diff --git a/src/main/resources/Documentation/rest-api-branch.md b/src/main/resources/Documentation/rest-api-branch.md
index 7580424..5a9f2ae 100644
--- a/src/main/resources/Documentation/rest-api-branch.md
+++ b/src/main/resources/Documentation/rest-api-branch.md
@@ -14,6 +14,10 @@
* manifest-commit-ish: commit-ish that points to the commit that contain the manifest (branch name, git describe string, etc.)
* manifest-path: path to the manifest that defines the projects to be branched
* new-branch: name of the branch to be created for each of the project defined in the manifest above
+* new-manifest-repo [optional]:
+* new-manifest-branch [optional]:
+* new-manifest-path [optional]:
+* create-snapshot-branch [optional]:
#### Request
```