regarding action bindings hosted as Maven artifact...
# github-workflows-kt
p
regarding action bindings hosted as Maven artifact, there's a non-trivial problem to be solved if we want to support not only major versions: actions are versioned differently than Maven artifacts, and can be referred to by different notation. It influences what should be generated by the bindings server under
maven-metadata.xml
enumerating the version. Example: • the original repository of
actions/checkout
exposes tags pointing to the same commit (in theory) like
v3.5.2
or
4.1.2
, and tags like
v3
or
v4
tracking newest version for a given major version • looking at an example Maven package, e.g. versions exposed by github-workflows-kt (see its maven-metadata.xml), one can only release a concrete version and there are no pointers to versions like
io.github.typesafegithub:github-workflows-kt:1
would point to the current
1.14.0
Currently the bindings server produces such
maven-metadata.xml
file for actions/checkout
Copy code
<?xml version="1.0" encoding="UTF-8"?>
<metadata>
  <groupId>actions</groupId>
  <artifactId>checkout</artifactId>
  <versioning>
    <latest>v4</latest>
    <release>v4</release>
    <versions>
      <version>v1</version>
      <version>v2</version>
      <version>v3</version>
      <version>v4</version>
    </versions>
    <lastUpdated>20240417073254</lastUpdated>
  </versioning>
</metadata>
and you can only request artifacts for these versions. I started thinking: what if we want to support referring to minor and patch versions of actions, and still allow the dependency update bots to update both just major versions (
v1
) and the full versions (
v1.2.3
)? Should there even be
v
in front (it's not Maven-esque)? If we wanted to go all Maven: • we should enumerate only full versions in
maven-metadata.xml
, and without
v
, so
<versions>...<version>3.5.2</version>...</versions>
• if someone really wants to allow the newest version for a given major version (emulate the
vN
tags provided by GitHub actions), using Maven version ranges is possible, so instead of the current
actions:checkout:v2
one would have to write sth like
actions:checkout:[2.0,3.0)
. It's explicit, but arguably ugly 🙂 I haven't seen many usages of version ranges in the JVM world, so maybe then it would encourage users to use the full versions? It would also be a breaking change for what the server currently exposes, but the number of users is still low thoughts?
v
Actually, it is questionable to expose
v1
et al at all. If today
v1
points to
v1.0.0
and tomorrow it points to
v1.9.9
that has differences in typings for example, the one requested
v1
today will tomorrow not see the changed version. Theoretically, if one follows the conventions also the Actions typings should be compatible or the major version increased, I'm just not sure people are / will be aware of that. In the beginning I also was not aware that moving from being a node12 to being a node16 action is a breaking change, as the action could be used on custom runners that only support node12. Regarding the
v
in front of the version, there is no necessity that this is even present actually. That is just a convention GitHub suggests that you can follow or not. You can specify any valid ref as version, or also a full SHA value to use an exact commit. I don't think the server should do any reasoning or mangling about it. If versions for GitHub actions typically start with a
v
, why not, even if many Maven-libs follow a different strategy, I don't think you should care about it or treat is specially.
And using a version range is a bad idea actually as long as GitHub has no native support for 3rd party DSLs. Because then executing the Kotlin Script today will resolve to
1.0.0
and write that concrete version to the YAML, and tomorrow it will resolve to
1.9.9
breaking the validation step as the YAML contains
1.0.0
.
p
do I understand correctly that you suggest exposing only versions like
v1.2.3
? also in
maven-metadata.xml
v
I'm not sure what I'm supposing, just noting problems. 😄 Only being able to use concrete versions is probably not a good idea either.
p
yeah, it's convenient to write
v3
even though it has some drawbacks
I'm thinking about exposing two modes, perhaps as two Maven repos (endpoints): one that would support only major versions, and the other one would support only full versions
v
Why?
p
one could specify both repos if they prefer to refer to
v4
for one action and
v1.2.3
for the other, Aether's artifact resolving logic would do the job
why two separate repos: because in one we would list only major versions in
maven-metadata.xml
, and in the other only the full versions. it would let the dependency updating bots work correctly
v
Ah, I see.
p
if they are both in a single
maven-metadata.xml
, it's not clear to me how they would figure out which version is the newest one.
<latest>
points only to a single version, and which one to put there: the major one or the full one?
v
Alternatively, you could provide different coordinates for the same action, one for major-version reference, one for concrete version.
p
I thought about it, but I'm not sure if encoding this piece of info would look nice there. Do you have an example to share?
v
Well, matter of imagination, just something added to the group or name
p
let's play with it:
@file:DependsOn("major__actions:checkout:v4")
vs
@file:DependsOn("full__actions:checkout:v4")
I don't like it 🙈
v
actions:cache:v1
vs.
actions:cache-specific:v1.2.3
and in case
cache
and
cache-specific
actually exist, also
actions:cache-major:v1
so that you can do
action:cache-specific-major:v1
.
As I said, that is then just a matter of imagination and preference. 🙂
p
ok, for completeness, let me show an example for the other approach:
Copy code
// the order of the below lines is random

@file:Repository("<https://github-workflows-kt-bindings.colman.com.br/major-versions/>")
@file:DependsOn("actions:checkout:v4")

@file:Repository("<https://github-workflows-kt-bindings.colman.com.br/specific-versions/>")
@file:DependsOn("actions:cache:v4.1.2")
v
Alos, how do you segragate? Do you then only support actions following the
vX
convention for major and everything else for the other repo? Would both repos support both syntaxes and just the metadata file would be different for update bots, so if you don't care about an update bot you can use either repository for everything? Only supporting
v1
on one and
v1.2.3
on the other would be bad, as you can then not depend on a concrete SHA, or on an action not following the naming convention, or on an action that follows the convention and also provides a
v1.2
.
p
Do you then only support actions following the
vX
convention for major and everything else for the other repo?
I thought of this option initially, but what you propose regarding the two repos differing only in what they serve in
maven-metadata.xml
sounds clever. This assumes that if there's a version
vX.Y.Z
that is not mentioned in
maven-metadata.xml
but its artifacts are available, Kotlin Scripting doesn't protest and just fetches the artifacts. I think it will work since my custom server worked fine even before I started serving
maven-metadata.xml
v
Yeah, the
maven-metadata.xml
should usually only be necessary for resolving version ranges or listing available versions. When requesting concrete versions (
v2
being a concrete version in this context) the metadata file should usually never be queried by any consuming tool.
👍 1
p
cool, seems like we converged to something that can work 🙂 thanks a lot! I'll deploy a change to the server that adds support for just fetching artifacts for the specific version, and I'll create the alternative endpoint that lists specific versions later
@Nikky feel free to try adding
@file:DependsOn("appleboy:ssh-action:v1.0.3")
, you may need to add typings to https://github.com/typesafegithub/github-actions-typing-catalog (ideally ask the owner to provide them with https://github.com/typesafegithub/github-actions-typing)
one note: if you go with adding typings to the catalog, they need to be added under
v1
tag, not
v1.0.3
. The server will figure it out correctly