feature[TW18355]: Add REST calls to relate worklfows to incorporated releases
Change-Id: Ibfa26b8171e33993d259ddf20d32115e7e158e57
Signed-off-by: kenn.r.luecke <kenn.r.luecke@boeing.com>
diff --git a/plugins/org.eclipse.osee.ats.api/src/org/eclipse/osee/ats/api/data/AtsArtifactTypes.java b/plugins/org.eclipse.osee.ats.api/src/org/eclipse/osee/ats/api/data/AtsArtifactTypes.java
index 6f077ac..d9babb0 100644
--- a/plugins/org.eclipse.osee.ats.api/src/org/eclipse/osee/ats/api/data/AtsArtifactTypes.java
+++ b/plugins/org.eclipse.osee.ats.api/src/org/eclipse/osee/ats/api/data/AtsArtifactTypes.java
@@ -157,7 +157,7 @@
.zeroOrOne(ReviewFormalType, ReviewFormalType.Formal)
.any(Role)
.zeroOrOne(VerificationCodeInspection));
- ArtifactTypeToken ReleaseArtifact = ats.add(ats.artifactType(61L, "ats.Release Artifact", true, Artifact)
+ ArtifactTypeToken ReleaseArtifact = ats.add(ats.artifactType(61L, "ats.Release Artifact", false, Artifact)
.zeroOrOne(Released));
ArtifactTypeToken Task = ats.add(ats.artifactType(74L, "Task", false, AbstractWorkflowArtifact)
.zeroOrOne(RelatedToState)
diff --git a/plugins/org.eclipse.osee.ats.api/src/org/eclipse/osee/ats/api/data/AtsRelationTypes.java b/plugins/org.eclipse.osee.ats.api/src/org/eclipse/osee/ats/api/data/AtsRelationTypes.java
index 3263448..b63d4a4 100644
--- a/plugins/org.eclipse.osee.ats.api/src/org/eclipse/osee/ats/api/data/AtsRelationTypes.java
+++ b/plugins/org.eclipse.osee.ats.api/src/org/eclipse/osee/ats/api/data/AtsRelationTypes.java
@@ -29,6 +29,7 @@
import static org.eclipse.osee.ats.api.data.AtsArtifactTypes.InsertionActivity;
import static org.eclipse.osee.ats.api.data.AtsArtifactTypes.Program;
import static org.eclipse.osee.ats.api.data.AtsArtifactTypes.Project;
+import static org.eclipse.osee.ats.api.data.AtsArtifactTypes.ReleaseArtifact;
import static org.eclipse.osee.ats.api.data.AtsArtifactTypes.Task;
import static org.eclipse.osee.ats.api.data.AtsArtifactTypes.TeamDefinition;
import static org.eclipse.osee.ats.api.data.AtsArtifactTypes.TeamWorkflow;
@@ -201,6 +202,10 @@
RelationTypeSide TeamWorkflowToFoundInVersion_TeamWorkflow = RelationTypeSide.create(TeamWorkflowToFoundInVersion, SIDE_A);
RelationTypeSide TeamWorkflowToFoundInVersion_Version = RelationTypeSide.create(TeamWorkflowToFoundInVersion, SIDE_B);
+ RelationTypeToken TeamWorkflowToRelease = ats.add(2531996123289575340L, "TeamWorkflowToRelease", MANY_TO_MANY, UNORDERED, TeamWorkflow, "Team Workflow", ReleaseArtifact, "Release Artifact");
+ RelationTypeSide TeamWorkflowToRelease_TeamWorkflow = RelationTypeSide.create(TeamWorkflowToRelease, SIDE_A);
+ RelationTypeSide TeamWorkflowToRelease_Release = RelationTypeSide.create(TeamWorkflowToRelease, SIDE_B);
+
RelationTypeToken TeamWorkflowToReview = ats.add(2305843009213694321L, "TeamWorkflowToReview", MANY_TO_MANY, UNORDERED, TeamWorkflow, "Team Workflow", AbstractReview, "Review");
RelationTypeSide TeamWorkflowToReview_TeamWorkflow = RelationTypeSide.create(TeamWorkflowToReview, SIDE_A);
RelationTypeSide TeamWorkflowToReview_Review = RelationTypeSide.create(TeamWorkflowToReview, SIDE_B);
diff --git a/plugins/org.eclipse.osee.ats.api/src/org/eclipse/osee/ats/api/workflow/AtsTeamWfEndpointApi.java b/plugins/org.eclipse.osee.ats.api/src/org/eclipse/osee/ats/api/workflow/AtsTeamWfEndpointApi.java
index 7ab6f44..76243f9 100644
--- a/plugins/org.eclipse.osee.ats.api/src/org/eclipse/osee/ats/api/workflow/AtsTeamWfEndpointApi.java
+++ b/plugins/org.eclipse.osee.ats.api/src/org/eclipse/osee/ats/api/workflow/AtsTeamWfEndpointApi.java
@@ -60,4 +60,11 @@
@Path("{id}/goal")
@Produces({MediaType.APPLICATION_JSON})
List<IAtsGoal> getGoals(@PathParam("id") String id);
+
+ @PUT
+ @Path("build/{build}")
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ XResultData setReleases(@PathParam("build") String build, @HeaderParam(OSEE_ACCOUNT_ID) UserId userId, List<String> changeIds);
+
}
\ No newline at end of file
diff --git a/plugins/org.eclipse.osee.ats.rest/src/org/eclipse/osee/ats/rest/internal/workitem/AtsTeamWfEndpointImpl.java b/plugins/org.eclipse.osee.ats.rest/src/org/eclipse/osee/ats/rest/internal/workitem/AtsTeamWfEndpointImpl.java
index 6a9b342..ba828d4 100644
--- a/plugins/org.eclipse.osee.ats.rest/src/org/eclipse/osee/ats/rest/internal/workitem/AtsTeamWfEndpointImpl.java
+++ b/plugins/org.eclipse.osee.ats.rest/src/org/eclipse/osee/ats/rest/internal/workitem/AtsTeamWfEndpointImpl.java
@@ -32,11 +32,13 @@
import org.eclipse.osee.ats.api.IAtsWorkItem;
import org.eclipse.osee.ats.api.ai.IAtsActionableItem;
import org.eclipse.osee.ats.api.config.TeamDefinition;
+import org.eclipse.osee.ats.api.data.AtsArtifactTypes;
import org.eclipse.osee.ats.api.data.AtsRelationTypes;
import org.eclipse.osee.ats.api.team.IAtsTeamDefinition;
import org.eclipse.osee.ats.api.user.AtsUser;
import org.eclipse.osee.ats.api.util.IAtsChangeSet;
import org.eclipse.osee.ats.api.version.IAtsVersion;
+import org.eclipse.osee.ats.api.workdef.IRelationResolver;
import org.eclipse.osee.ats.api.workflow.AtsTeamWfEndpointApi;
import org.eclipse.osee.ats.api.workflow.IAtsGoal;
import org.eclipse.osee.ats.api.workflow.IAtsTeamWorkflow;
@@ -48,6 +50,7 @@
import org.eclipse.osee.framework.core.enums.CoreAttributeTypes;
import org.eclipse.osee.framework.core.model.change.ChangeItem;
import org.eclipse.osee.framework.jdk.core.result.XResultData;
+import org.eclipse.osee.framework.jdk.core.util.Lib;
/**
* @author Donald G. Dunne
@@ -180,4 +183,66 @@
}
return goalList;
}
-}
+
+ @Override
+ @PUT
+ @Path("build/{build}")
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ public XResultData setReleases(@PathParam("build") String build, @HeaderParam(OSEE_ACCOUNT_ID) UserId userId, List<String> changeIds) {
+ XResultData rd = new XResultData();
+ try {
+ rd.setTitle("Add Workflow to Release Relations");
+
+ Collection<ArtifactToken> allWorkflows =
+ atsApi.getQueryService().createQuery(AtsArtifactTypes.TeamWorkflow).andAttr(CoreAttributeTypes.GitChangeId,
+ changeIds).getArtifacts();
+ AtsUser asUser = atsApi.getUserService().getUserByAccountId(userId);
+ if (asUser.isInvalid()) {
+ rd.errorf("%s is an invalid ATS user.", userId);
+ return rd;
+ }
+
+ IAtsChangeSet changes = atsApi.createChangeSet("Add Build Incorporation(s)", asUser);
+ for (IAtsWorkItem workItem : atsApi.getWorkItemService().getWorkItems(allWorkflows)) {
+ if (!workItem.isTeamWorkflow()) {
+ rd.errorf("%s is not a valid team workflow id.", workItem.toStringWithId());
+ return rd;
+ }
+
+ Set<String> distinctChangeIds = new HashSet<String>(
+ atsApi.getAttributeResolver().getAttributesToStringList(workItem, CoreAttributeTypes.GitChangeId));
+ boolean isBuildValid = false;
+ for (String changeId : changeIds) {
+ if (distinctChangeIds.contains(changeId)) {
+ isBuildValid = true;
+ break;
+ }
+ }
+ Collection<ArtifactToken> release =
+ atsApi.getQueryService().createQuery(AtsArtifactTypes.ReleaseArtifact).andName(build).getArtifacts();
+ if (isBuildValid) {
+ if (release.size() > 1) {
+ rd.errorf("%s has multiple releases", build);
+ return rd;
+ }
+ if (release.isEmpty()) {
+ rd.errorf("%s has no elements", build);
+ return rd;
+ }
+ IRelationResolver relationResolver = atsApi.getRelationResolver();
+ if (!relationResolver.areRelated(workItem.getArtifactId(),
+ AtsRelationTypes.TeamWorkflowToRelease_Release, release.stream().findFirst().get())) {
+ changes.relate(workItem, AtsRelationTypes.TeamWorkflowToRelease_Release,
+ release.stream().findFirst().get());
+ }
+ }
+ }
+ changes.executeIfNeeded();
+ } catch (Exception Ex) {
+ rd.errorf("Exception %s", Lib.exceptionToString(Ex));
+ }
+
+ return rd;
+ }
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.osee.define.api/src/org/eclipse/osee/define/api/GitEndpoint.java b/plugins/org.eclipse.osee.define.api/src/org/eclipse/osee/define/api/GitEndpoint.java
index 700423d..1efca5b 100644
--- a/plugins/org.eclipse.osee.define.api/src/org/eclipse/osee/define/api/GitEndpoint.java
+++ b/plugins/org.eclipse.osee.define.api/src/org/eclipse/osee/define/api/GitEndpoint.java
@@ -14,7 +14,9 @@
package org.eclipse.osee.define.api;
import static org.eclipse.osee.framework.core.data.OseeClient.OSEE_ACCOUNT_ID;
+import java.util.List;
import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
import javax.ws.rs.HeaderParam;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
@@ -39,9 +41,15 @@
ArtifactId trackGitBranch(@PathParam("branch") BranchId branch, @HeaderParam(OSEE_ACCOUNT_ID) UserId account, @QueryParam("git-branch") String gitBranchName, @QueryParam("clone") boolean clone, String gitRepoUrl);
@POST
- @Path("{branch}/repo/{repository-name}")
+ @Path("{branch}/repo/{repositoryName}")
@Consumes(MediaType.TEXT_PLAIN)
@Produces(MediaType.APPLICATION_JSON)
- ArtifactId updateGitTrackingBranch(@PathParam("branch") BranchId branch, @PathParam("repository-name") String repositoryName, @HeaderParam(OSEE_ACCOUNT_ID) UserId account, @QueryParam("fetch") boolean fetch, String gitBranchName);
+ ArtifactId updateGitTrackingBranch(@PathParam("branch") BranchId branch, @PathParam("repositoryName") String repositoryName, @HeaderParam(OSEE_ACCOUNT_ID) UserId account, @QueryParam("fetch") boolean fetch, String gitBranchName);
+
+ @GET
+ @Path("{branch}/repo/{repositoryName}/changeId/tags")
+ @Consumes(MediaType.TEXT_PLAIN)
+ @Produces(MediaType.APPLICATION_JSON)
+ List<String> getChangeIdBetweenTags(@PathParam("branch") BranchId branch, @PathParam("repositoryName") String repositoryName, @QueryParam("startTag") String startTag, @QueryParam("endTag") String endTag);
}
\ No newline at end of file
diff --git a/plugins/org.eclipse.osee.define.api/src/org/eclipse/osee/define/api/GitOperations.java b/plugins/org.eclipse.osee.define.api/src/org/eclipse/osee/define/api/GitOperations.java
index f9e8095..2b42f51 100644
--- a/plugins/org.eclipse.osee.define.api/src/org/eclipse/osee/define/api/GitOperations.java
+++ b/plugins/org.eclipse.osee.define.api/src/org/eclipse/osee/define/api/GitOperations.java
@@ -13,6 +13,7 @@
package org.eclipse.osee.define.api;
+import java.util.List;
import org.eclipse.osee.framework.core.data.ArtifactId;
import org.eclipse.osee.framework.core.data.ArtifactToken;
import org.eclipse.osee.framework.core.data.BranchId;
@@ -39,4 +40,7 @@
void fetch(ArtifactReadable repoArtifact, String password);
ArtifactToken getCommitArtifactId(BranchId branch, String changeId);
+
+ List<String> getChangeIdBetweenTags(BranchId branch, ArtifactReadable repoArtifact, String startTag, String endTag);
+
}
\ No newline at end of file
diff --git a/plugins/org.eclipse.osee.define.rest/src/org/eclipse/osee/define/rest/GitEndpointImpl.java b/plugins/org.eclipse.osee.define.rest/src/org/eclipse/osee/define/rest/GitEndpointImpl.java
index 7cdc6ce..6d2a79d 100644
--- a/plugins/org.eclipse.osee.define.rest/src/org/eclipse/osee/define/rest/GitEndpointImpl.java
+++ b/plugins/org.eclipse.osee.define.rest/src/org/eclipse/osee/define/rest/GitEndpointImpl.java
@@ -13,6 +13,7 @@
package org.eclipse.osee.define.rest;
+import java.util.List;
import org.eclipse.osee.activity.api.ActivityLog;
import org.eclipse.osee.define.api.DefineApi;
import org.eclipse.osee.define.api.GitEndpoint;
@@ -46,4 +47,10 @@
return gitOps.updateGitTrackingBranch(branch, gitOps.getRepoArtifact(branch, repositoryName), account,
gitBranchName, fetch, null, false);
}
+
+ @Override
+ public List<String> getChangeIdBetweenTags(BranchId branch, String repositoryName, String startTag, String endTag) {
+ return gitOps.getChangeIdBetweenTags(branch, gitOps.getRepoArtifact(branch, repositoryName), startTag, endTag);
+ }
+
}
\ No newline at end of file
diff --git a/plugins/org.eclipse.osee.define.rest/src/org/eclipse/osee/define/rest/GitOperationsImpl.java b/plugins/org.eclipse.osee.define.rest/src/org/eclipse/osee/define/rest/GitOperationsImpl.java
index 0abed8f..11eba79 100644
--- a/plugins/org.eclipse.osee.define.rest/src/org/eclipse/osee/define/rest/GitOperationsImpl.java
+++ b/plugins/org.eclipse.osee.define.rest/src/org/eclipse/osee/define/rest/GitOperationsImpl.java
@@ -52,6 +52,7 @@
import org.eclipse.jgit.lib.ConfigConstants;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectReader;
+import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevSort;
@@ -158,7 +159,7 @@
private void fetch(Repository localRepo, String passphrase) {
try (Git git = new Git(localRepo)) {
- FetchCommand fetchCommand = git.fetch().setCheckFetchedObjects(true).setTagOpt(TagOpt.NO_TAGS);
+ FetchCommand fetchCommand = git.fetch().setCheckFetchedObjects(true).setTagOpt(TagOpt.FETCH_TAGS);
configurateAuthentication(localRepo, fetchCommand, passphrase);
@@ -268,6 +269,41 @@
return repoArtifact;
}
+ @Override
+ public List<String> getChangeIdBetweenTags(BranchId branch, ArtifactReadable repoArtifact, String startTag, String endTag) {
+
+ Repository jgitRepo = getLocalRepoReference(repoArtifact.getSoleAttributeValue(FileSystemPath));
+ /* fetch second arg (passPhrase) provide a key or password to enter repo. Here we have no pass phrase. */
+ fetch(jgitRepo, "");
+ try (Git git = new Git(jgitRepo)) {
+
+ Ref tag1 = git.getRepository().exactRef("refs/tags/" + startTag);
+ Ref tag2 = git.getRepository().exactRef("refs/tags/" + endTag);
+ Iterable<RevCommit> commits = git.log().addRange(tag1.getPeeledObjectId(), tag2.getPeeledObjectId()).call();
+
+ // parse through commits to get specific tags with specific commits and change ids
+ List<String> changeIdList = new ArrayList<>();
+ for (RevCommit revCommit : commits) {
+ if (revCommit.getShortMessage() != "") {
+ String commitSHA = revCommit.getId().name();
+
+ if (changeIdMatcher.reset(revCommit.getFullMessage()).find()) {
+ String changeId = changeIdMatcher.group(1);
+ changeIdList.add(changeId);
+ } else {
+ changeIdList.add(commitSHA);
+ }
+
+ }
+ }
+
+ return changeIdList;
+
+ } catch (Exception ex) {
+ throw OseeCoreException.wrap(ex);
+ }
+ }
+
public ArtifactReadable clone(String gitRepoUrl, BranchId branch, UserId account, String gitBranchName, boolean clone, String passphrase) {
String serverDataLocation = systemPrefs.getValue(OseeClient.OSEE_APPLICATION_SERVER_DATA);
String repoName = gitRepoUrl.substring(gitRepoUrl.lastIndexOf('/') + 1).replaceAll("\\.git$", "");
@@ -366,26 +402,24 @@
}
}
- private ArtifactId parseGitCommit(ObjectReader objectReader, DiffFormatter df, ArtifactReadable repoArtifact, RevCommit revCommit, BranchId branch, UserId account, HistoryImportStrategy importStrategy) {
+ private ArtifactId createCommitArtifact(RevCommit revCommit, TransactionBuilder tx, BranchId branch) {
+
+ String commitSHA = revCommit.getId().name();
+
+ String commitId;
+ if (changeIdMatcher.reset(revCommit.getFullMessage()).find()) {
+ String changeId = changeIdMatcher.group(1);
+ commitId = changeId;
+
+ } else {
+ commitId = commitSHA;
+ }
+
try {
- TransactionBuilder tx = importStrategy.getTransactionBuilder(orcsApi, branch, account);
-
- String commitSHA = revCommit.getId().name();
-
- String commitId;
- if (changeIdMatcher.reset(revCommit.getFullMessage()).find()) {
- String changeId = changeIdMatcher.group(1);
- commitId = changeId;
-
- if (importStrategy.hasChangeIdAlredyImported(changeId)) {
- return ArtifactId.SENTINEL;
- }
- } else {
- commitId = commitSHA;
- }
-
+ return queryFactory.fromBranch(branch).andIsOfType(CoreArtifactTypes.GitCommit).andNameEquals(
+ revCommit.getShortMessage()).asArtifact();
+ } catch (Exception ex) {
ArtifactId commitArtifact = tx.createArtifact(GitCommit, revCommit.getShortMessage());
-
tx.setSoleAttributeValue(commitArtifact, CoreAttributeTypes.GitCommitSha, commitSHA);
tx.setSoleAttributeValue(commitArtifact, CoreAttributeTypes.UserArtifactId, SystemUser.OseeSystem); //TODO: this must convert author to the corresponding user artifact
tx.setSoleAttributeValue(commitArtifact, CoreAttributeTypes.GitCommitAuthorDate,
@@ -393,9 +427,18 @@
tx.setSoleAttributeValue(commitArtifact, CoreAttributeTypes.GitCommitMessage, revCommit.getFullMessage());
tx.setSoleAttributeValue(commitArtifact, GitChangeId, commitId);
+ return commitArtifact;
- importFileChanges(objectReader, df, repoArtifact, revCommit, commitSHA, commitArtifact, branch, tx,
- importStrategy);
+ }
+ }
+
+ private ArtifactId parseGitCommit(ObjectReader objectReader, DiffFormatter df, ArtifactReadable repoArtifact, RevCommit revCommit, BranchId branch, UserId account, HistoryImportStrategy importStrategy) {
+ try {
+ TransactionBuilder tx = importStrategy.getTransactionBuilder(orcsApi, branch, account);
+
+ ArtifactId commitArtifact = createCommitArtifact(revCommit, tx, branch);
+ importFileChanges(objectReader, df, repoArtifact, revCommit, revCommit.getId().name(), commitArtifact, branch,
+ tx, importStrategy);
importStrategy.finishGitCommit(tx);
return commitArtifact;
diff --git a/plugins/org.eclipse.osee.framework.core/src/org/eclipse/osee/framework/core/enums/CoreAttributeTypes.java b/plugins/org.eclipse.osee.framework.core/src/org/eclipse/osee/framework/core/enums/CoreAttributeTypes.java
index 190c4d9..c02ead6 100644
--- a/plugins/org.eclipse.osee.framework.core/src/org/eclipse/osee/framework/core/enums/CoreAttributeTypes.java
+++ b/plugins/org.eclipse.osee.framework.core/src/org/eclipse/osee/framework/core/enums/CoreAttributeTypes.java
@@ -100,6 +100,7 @@
FunctionalGroupingAttributeType FunctionalGrouping = osee.createEnum(new FunctionalGroupingAttributeType());
AttributeTypeString GeneralStringData = osee.createStringNoTag(1152921504606847096L, "General String Data", MediaType.TEXT_PLAIN, "");
GfeCfeAttributeType GfeCfe = osee.createEnum(new GfeCfeAttributeType());
+ AttributeTypeString GitBuildId = osee.createString(1714059195608838442L, "Git Build-Id", MediaType.TEXT_PLAIN, "Build-Id embedded in Git commit message that is intended to be immutable even during rebase and amending the commit");
AttributeTypeString GitChangeId = osee.createString(1152921504606847702L, "Git Change-Id", MediaType.TEXT_PLAIN, "Change-Id embedded in Git commit message that is intended to be immutable even during rebase and amending the commit");
AttributeTypeDate GitCommitAuthorDate = osee.createDate(1152921504606847704L, "Git Commit Author Date", MediaType.TEXT_PLAIN, "when this commit was originally made");
AttributeTypeString GitCommitMessage = osee.createString(1152921504606847705L, "Git Commit Message", MediaType.TEXT_PLAIN, "Full message minus Change-Id");