Sending and updating a patch / MR

(1) Opening a merge request / patch

In the current representation I’m using for patches and Merge Requests, there’s an OrderedCollection containing the patch versions. So each time you update a patch, or git-push into your MR’s source branch, a new version is added to the list. Listing the versions is needed for clients to be able to display them, and for servers to support federation of e.g. comments on code review of pieces of code from the different versions.

However, when opening a new MR/patch, obviously there’s just one version, so I’m thinking, instead of the OrderedCollection with one item, we could have just the Patch object itself. Thoughts?

Representation of MR:

{ "@context": [ ... ],
  "id": "https://dev.example/alice/objects/34583485354",
  "type": "Ticket",
  "attributedTo": "https://dev.example/alice",
  "context": "https://forge.example/bob/coolBobRepo",
  "summary": "Fix the bug bla bla bla",
  "content": "This MR should fix issue #54 etc. etc.",
  "replies": "https://dev.example/alice/objects/34583485354/replies",

  "attachment": {
    "type": "Offer",
    "origin": "https://dev.example/alice/coolBobRepo/branches/bug54",
    "target": "https://forge.example/bob/coolBobRepo/branches/master",
    "object": {
      "type": "OrderedCollection",
      "totalItems": 1,
      "orderedItems": [
        { "id": "https://dev.example/alice/objects/34583485354/ver1",
          "type": "Patch",
          "attributedTo": "https://dev.example/alice",
          "mediaType": "application/x-darcs-patch",
          "content": "...",
          "replies": "https://dev.example/alice/objects/34583485354/ver1/replies"
        }
      ]
    }
  }
}

When submitting a new MR, e.g. using a Create activity, instead of the OrderedCollection what if we put just a Patch object? Like this:

{ "@context": [ ... ],
  "type": "Create",
  "actor": "https://dev.example/alice",
  "object": {
    "type": "Ticket",
    "attributedTo": "https://dev.example/alice",
    "context": "https://forge.example/bob/coolBobRepo",
    "summary": "Fix the bug bla bla bla",
    "content": "This MR should fix issue #54 etc. etc.",

    "attachment": {
      "type": "Offer",
      "origin": "https://dev.example/alice/coolBobRepo/branches/bug54",
      "target": "https://forge.example/bob/coolBobRepo/branches/master",
      "object": {
            "id": "https://dev.example/alice/objects/34583485354/ver1",
            "type": "Patch",
            "attributedTo": "https://dev.example/alice",
            "mediaType": "application/x-darcs-patch",
            "content": "..."
      }
    }
  }
}

Possibility: Support both options i.e. object can be either a Patch as above, or an OrderedCollection with one Patch item.

(2) Uploading a new version

Which AP activity to use for uploading a new version of a patch? There’s the Update activity, which may sound nice because you’re indeed updating your patch, but in terms of the actual AS2 representation, you aren’t really updating: You’re adding a new version. Because the representation has a separate ID URI for each version. So you’re adding.

How about Add where object is a Patch and target is the ID URI of the OrderedCollection (or perhaps the ID URI of the Ticket?)

(As follow-up to my Creating a ticket dependency feedback, here an Offer does make perfect sense.)

I have an alternative proposal, which may make more sense. It’s a small change but I think it makes things much nicer: How about instead of an OrderedCollection of the patch versions, there’s a Patch object with a ‘versions’ property that maps to the collection of (previous) versions?

Downside: Adding a new property ‘versions’ (although maybe there’s one in some existing RDF ontology)

Upside: It’s more obvious what the type of attachment is, and software that doesn’t care about versions can just safely ignore that ‘versions’ property and deal with the latest-version Patch object. Submission of new versions could perhaps be done using Update rather than a more obscure Add-a-new-Patch-to-the-collection. Also, when there’s a single version (e.g. when opening a new Merge Request), there’s no single-item OrderedCollection in the way.

Thoughts?

There’s little feedback here so I’m going forward with this and implementing this new representation. Then I’ll probably put it in the spec if nobody objects.

Hmm question about the ‘versions’ collection: Should it include the latest version too? Or only previous versions? What if we call it ‘previousVersions’ and then require it doesn’t include the latest?

Idea 1: Not require, just let implementations decide, it’s a trivial tiny detail

Idea 2: Use SHOULD or MUST in the spec for this - but I’m finding it difficult to pick - require to include the latest version or require to not include it? Any arguments for either option?

Also, perhaps now it’s easy to switch from OrderedCollection to a simple silly RDF list? So in the JSON-LD it can be a regular JSON array, and the ‘versions’ term in the ForgeFed JSON-LD context will have @type set to @list, or whatever it was that makes it be interpreted as an RDF linked list.

What I’m going to implement for now: Calling the property ‘previousVersions’, not putting the latest version there, and the property maps to a simple JSON array (which would turn into an RDF list if you did JSON-LD processing).

Idea: Instead of ‘previousVersions’ being a list, we could have a ‘versions’ that has its own @id and is an OrderedCollection, and all the Patch objects point to it (in addition to ‘context’, which points to the Ticket). Idk if there’s any benefit in that, just mentioning the idea. For now implementing as said above with ‘previousVersions’.

It’s time to account for the possibility of MRs with multiple patches. This isn’t needed for Darcs, but it’s needed for Git, and surely for some other VCSs too. PROPOSAL: The ‘object’ of the ‘Offer’ is going to be an ‘OrderedCollection’! I guess it could be an RDF list as well, but it would need to use @list explicitly since ‘object’ is a standard generic term. That RDF list would also be having the ‘previousVersions’ property. I guess it’s fine, maybe a bit weird. Anyway, going for ‘OrderedCollection’ for now just for the example:

{ "@context": [ ... ],
  "type": "Create",
  "actor": "https://dev.example/alice",
  "object": {
    "type": "Ticket",
    "attributedTo": "https://dev.example/alice",
    "context": "https://forge.example/bob/coolBobRepo",
    "summary": "Fix the bug bla bla bla",
    "content": "This MR should fix issue #54 etc. etc.",

    "attachment": {
      "type": "Offer",
      "origin": "https://dev.example/alice/coolBobRepo/branches/bug54",
      "target": "https://forge.example/bob/coolBobRepo/branches/master",
      "object": {
        "id": "https://dev.example/alice/objects/34583485354/ver1",
        "type": "OrderedCollection",
        "totalItems": 1,
        "orderedItems": [
          { "type": "Patch",
            "attributedTo": "https://dev.example/alice",
            "mediaType": "application/x-darcs-patch",
            "content": "..."
          }
        ]
      }
    }
  }
}