-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add [snapcraft] version badge #9976
Conversation
I think we can get away without auth tbh. I think the macaroon auth is needed if you want to do stuff like publish snaps, for example. I'm not seeing anything that indicates the |
}, | ||
}) | ||
|
||
const version = parsedData['channel-map'][0].version |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry.. one more question
You said in the top post
Takes the latest value, might be a problem with mix of channels
Can you expand on that. Can we actually rely on array position 0 to be the latest version?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Snapstore allows devs to have more then one version channel, for example stable/beta/edge
They also seem to allow freedom when adding channel names.
Some snaps don't have stable channel, in those cases i found beta first or other channel.
I tested out a bunch of snaps and learned that:
- It appears that regardless of change date, the order of channels is fixed
- If stable exists i always saw it first in the list.
The docs indicate here that:
Some considerations about this structure:
if the channel doesn't have any revision released into it (e.g. beta is closed, so it just redirects to stable), it will be not present
branches will not be returned
items in the channel-map list will be ordered by (track, risk,
architecture); the track that is None will come always first in the list, using name 'latest'fields inside the channel object could potentially grow to include other relevant info
if the snap doesn't have any released revision for the given request, channel-map will be present and empty
IMO its safe enough to assume the first channel has the most "mainstream" version, but i can not guarantee it won't fail.
I think we should not limit it to the stable/latest channel as some packages don't have it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK. Thanks for explaining that.
Although just picking the first one in the list means we will definitely put some value on the badge, I think it is maybe more important to focus on making sure it is clear and explainable what the value is.
I've had a bit of a look into this myself.
Lets take an example like chromium that has multiple channels and architectures
curl "https://api.snapcraft.io/v2/snaps/info/chromium" --header "Snap-Device-Series: 16"
Response
{ "channel-map": [ { "channel": { "architecture": "amd64", "name": "stable", "released-at": "2024-02-26T08:09:42.508032+00:00", "risk": "stable", "track": "latest" }, "created-at": "2024-02-23T16:36:20.431472+00:00", "download": { "deltas": [], "sha3-384": "b12abc7c87caca9ef974d13e673ec25c44086376ec8c0480b9082e29779b1b451aa873cc7a0e31fefafc95b5979e9d46", "size": 168206336, "url": "https://api.snapcraft.io/api/v1/snaps/download/XKEcBqPM06H1Z7zGOdG5fbICuf8NWK5R_2764.snap" }, "revision": 2764, "type": "app", "version": "122.0.6261.69" }, { "channel": { "architecture": "arm64", "name": "stable", "released-at": "2024-02-26T08:09:43.882125+00:00", "risk": "stable", "track": "latest" }, "created-at": "2024-02-24T05:26:00.972509+00:00", "download": { "deltas": [], "sha3-384": "30f878166c08cd54f9c313e356d8d9ed9b5f1f381de042cdbc454a68f5430b93071fdd39d09b96d60f8c313772e9c06e", "size": 168894464, "url": "https://api.snapcraft.io/api/v1/snaps/download/XKEcBqPM06H1Z7zGOdG5fbICuf8NWK5R_2765.snap" }, "revision": 2765, "type": "app", "version": "122.0.6261.69" }, { "channel": { "architecture": "armhf", "name": "stable", "released-at": "2024-01-19T23:45:32.994812+00:00", "risk": "stable", "track": "latest" }, "created-at": "2024-01-19T10:39:30.179580+00:00", "download": { "deltas": [], "sha3-384": "63bcad9179720f327a337dac5ed94b22bb432632f5a1f5a25844c90bcd9c098f71568647e43b0d02b6bac75ae0eed7c8", "size": 144773120, "url": "https://api.snapcraft.io/api/v1/snaps/download/XKEcBqPM06H1Z7zGOdG5fbICuf8NWK5R_2737.snap" }, "revision": 2737, "type": "app", "version": "120.0.6099.224" }, { "channel": { "architecture": "i386", "name": "stable", "released-at": "2023-03-10T12:36:35.652771+00:00", "risk": "stable", "track": "latest" }, "created-at": "2021-12-18T00:25:55.524093+00:00", "download": { "deltas": [], "sha3-384": "0635ccb12ca8aedcc95ff1505c0e313820140773567c344d79fcb5007492eea08c02ca19d727b9c7848fd4d2d564cf10", "size": 156057600, "url": "https://api.snapcraft.io/api/v1/snaps/download/XKEcBqPM06H1Z7zGOdG5fbICuf8NWK5R_1862.snap" }, "revision": 1862, "type": "app", "version": "98.0.4758.9" }, { "channel": { "architecture": "amd64", "name": "candidate", "released-at": "2024-02-28T15:51:03.536793+00:00", "risk": "candidate", "track": "latest" }, "created-at": "2024-02-28T15:50:29.081075+00:00", "download": { "deltas": [], "sha3-384": "a4204c9d44bfe0d44a1e892c384d9e92700fac7af80b52dcfb61c8a6c8822c20d4e83b100d426cbc34891be250a0e1b7", "size": 168333312, "url": "https://api.snapcraft.io/api/v1/snaps/download/XKEcBqPM06H1Z7zGOdG5fbICuf8NWK5R_2768.snap" }, "revision": 2768, "type": "app", "version": "122.0.6261.94" }, { "channel": { "architecture": "arm64", "name": "candidate", "released-at": "2024-02-24T05:26:48.734893+00:00", "risk": "candidate", "track": "latest" }, "created-at": "2024-02-24T05:26:00.972509+00:00", "download": { "deltas": [], "sha3-384": "30f878166c08cd54f9c313e356d8d9ed9b5f1f381de042cdbc454a68f5430b93071fdd39d09b96d60f8c313772e9c06e", "size": 168894464, "url": "https://api.snapcraft.io/api/v1/snaps/download/XKEcBqPM06H1Z7zGOdG5fbICuf8NWK5R_2765.snap" }, "revision": 2765, "type": "app", "version": "122.0.6261.69" }, { "channel": { "architecture": "armhf", "name": "candidate", "released-at": "2024-01-19T10:39:59.939262+00:00", "risk": "candidate", "track": "latest" }, "created-at": "2024-01-19T10:39:30.179580+00:00", "download": { "deltas": [], "sha3-384": "63bcad9179720f327a337dac5ed94b22bb432632f5a1f5a25844c90bcd9c098f71568647e43b0d02b6bac75ae0eed7c8", "size": 144773120, "url": "https://api.snapcraft.io/api/v1/snaps/download/XKEcBqPM06H1Z7zGOdG5fbICuf8NWK5R_2737.snap" }, "revision": 2737, "type": "app", "version": "120.0.6099.224" }, { "channel": { "architecture": "i386", "name": "candidate", "released-at": "2023-03-08T11:02:34.371272+00:00", "risk": "candidate", "track": "latest" }, "created-at": "2021-12-18T00:25:55.524093+00:00", "download": { "deltas": [], "sha3-384": "0635ccb12ca8aedcc95ff1505c0e313820140773567c344d79fcb5007492eea08c02ca19d727b9c7848fd4d2d564cf10", "size": 156057600, "url": "https://api.snapcraft.io/api/v1/snaps/download/XKEcBqPM06H1Z7zGOdG5fbICuf8NWK5R_1862.snap" }, "revision": 1862, "type": "app", "version": "98.0.4758.9" }, { "channel": { "architecture": "amd64", "name": "beta", "released-at": "2024-02-15T17:26:15.226443+00:00", "risk": "beta", "track": "latest" }, "created-at": "2024-02-15T17:25:17.671423+00:00", "download": { "deltas": [], "sha3-384": "1c080882c47b2b884a8f036e6ea81af0707eccd228846e19dd3ebea89b958412d506236387ee2d64d851b6df0528bf6c", "size": 167301120, "url": "https://api.snapcraft.io/api/v1/snaps/download/XKEcBqPM06H1Z7zGOdG5fbICuf8NWK5R_2759.snap" }, "revision": 2759, "type": "app", "version": "122.0.6261.39" }, { "channel": { "architecture": "arm64", "name": "beta", "released-at": "2024-02-23T16:10:06.237907+00:00", "risk": "beta", "track": "latest" }, "created-at": "2024-02-23T16:09:28.544255+00:00", "download": { "deltas": [], "sha3-384": "1557258f72d3a850ad0db062bcc1d2da31a1c041f241c827d7b284fd20a739b006b39853331f7e4d12cc24bda63994ee", "size": 168894464, "url": "https://api.snapcraft.io/api/v1/snaps/download/XKEcBqPM06H1Z7zGOdG5fbICuf8NWK5R_2763.snap" }, "revision": 2763, "type": "app", "version": "122.0.6261.57" }, { "channel": { "architecture": "armhf", "name": "beta", "released-at": "2023-12-06T08:46:56.603790+00:00", "risk": "beta", "track": "latest" }, "created-at": "2023-12-06T08:46:25.832262+00:00", "download": { "deltas": [], "sha3-384": "f78e48a268263ff645028445bc71e6f5ea0a9945ac2abb67e07ee1d6014844d53a5e00128bc9ce9e66d3dbfb0ed373c4", "size": 144764928, "url": "https://api.snapcraft.io/api/v1/snaps/download/XKEcBqPM06H1Z7zGOdG5fbICuf8NWK5R_2711.snap" }, "revision": 2711, "type": "app", "version": "120.0.6099.62" }, { "channel": { "architecture": "i386", "name": "beta", "released-at": "2023-01-12T18:03:15.819763+00:00", "risk": "beta", "track": "latest" }, "created-at": "2021-12-18T00:25:55.524093+00:00", "download": { "deltas": [], "sha3-384": "0635ccb12ca8aedcc95ff1505c0e313820140773567c344d79fcb5007492eea08c02ca19d727b9c7848fd4d2d564cf10", "size": 156057600, "url": "https://api.snapcraft.io/api/v1/snaps/download/XKEcBqPM06H1Z7zGOdG5fbICuf8NWK5R_1862.snap" }, "revision": 1862, "type": "app", "version": "98.0.4758.9" }, { "channel": { "architecture": "amd64", "name": "edge", "released-at": "2024-02-26T17:45:11.738171+00:00", "risk": "edge", "track": "latest" }, "created-at": "2024-02-26T17:44:37.242988+00:00", "download": { "deltas": [], "sha3-384": "f6517f9cb7faf4997719cf2580ba49049686c0ab8f05d9442baa6d244e704fc4f797e2654fadda6cfe4147f79ba3f183", "size": 168693760, "url": "https://api.snapcraft.io/api/v1/snaps/download/XKEcBqPM06H1Z7zGOdG5fbICuf8NWK5R_2766.snap" }, "revision": 2766, "type": "app", "version": "124.0.6315.2" }, { "channel": { "architecture": "arm64", "name": "edge", "released-at": "2024-02-10T10:35:54.549248+00:00", "risk": "edge", "track": "latest" }, "created-at": "2024-02-10T10:35:21.513150+00:00", "download": { "deltas": [], "sha3-384": "6ff1b84f222cf53425b19256d9d0e108d9835ab1b62f07c745d29c6e3aa27fbba2d3e906df2f6a19db782e6275a1a92a", "size": 168415232, "url": "https://api.snapcraft.io/api/v1/snaps/download/XKEcBqPM06H1Z7zGOdG5fbICuf8NWK5R_2756.snap" }, "revision": 2756, "type": "app", "version": "123.0.6286.0" }, { "channel": { "architecture": "armhf", "name": "edge", "released-at": "2023-11-18T04:22:03.340428+00:00", "risk": "edge", "track": "latest" }, "created-at": "2023-11-18T04:21:38.521227+00:00", "download": { "deltas": [], "sha3-384": "dfac4a0a8da4b24c69e8ca8ffa17dbe3f195c2a5bb0675b72e1fb9b7a86021bdb195e43348e14b19e00b3609371d81df", "size": 145645568, "url": "https://api.snapcraft.io/api/v1/snaps/download/XKEcBqPM06H1Z7zGOdG5fbICuf8NWK5R_2700.snap" }, "revision": 2700, "type": "app", "version": "121.0.6129.0" }, { "channel": { "architecture": "i386", "name": "edge", "released-at": "2021-12-18T00:28:11.939534+00:00", "risk": "edge", "track": "latest" }, "created-at": "2021-12-18T00:25:55.524093+00:00", "download": { "deltas": [], "sha3-384": "0635ccb12ca8aedcc95ff1505c0e313820140773567c344d79fcb5007492eea08c02ca19d727b9c7848fd4d2d564cf10", "size": 156057600, "url": "https://api.snapcraft.io/api/v1/snaps/download/XKEcBqPM06H1Z7zGOdG5fbICuf8NWK5R_1862.snap" }, "revision": 1862, "type": "app", "version": "98.0.4758.9" } ], "default-track": null, "name": "chromium", "snap": { "license": "Apache-2.0 AND BSD-3-Clause AND LGPL-2.0 AND LGPL-2.1 AND MIT AND MS-PL AND (GPL-2.0+ OR LGPL-2.1+ OR MPL-1.1)", "name": "chromium", "prices": {}, "publisher": { "display-name": "Canonical", "id": "canonical", "username": "canonical", "validation": "verified" }, "snap-id": "XKEcBqPM06H1Z7zGOdG5fbICuf8NWK5R", "store-url": "https://snapcraft.io/chromium", "summary": "Chromium web browser, open-source version of Chrome", "title": "chromium" }, "snap-id": "XKEcBqPM06H1Z7zGOdG5fbICuf8NWK5R" }
the way this gets expressed through the command line is
$ snap info chromium
name: chromium
summary: Chromium web browser, open-source version of Chrome
publisher: Canonical✓
store-url: https://snapcraft.io/chromium
contact: https://bugs.launchpad.net/ubuntu/+source/chromium-browser/+bugs?field.tag=snap
license: unset
description: |
An open-source browser project that aims to build a safer, faster, and more
stable way for all Internet users to experience the web.
commands:
- chromium.chromedriver
- chromium
snap-id: XKEcBqPM06H1Z7zGOdG5fbICuf8NWK5R
tracking: latest/stable
refresh-date: 2 days ago, at 09:54 GMT
channels:
latest/stable: 122.0.6261.69 2024-02-26 (2764) 168MB -
latest/candidate: 122.0.6261.94 2024-02-28 (2768) 168MB -
latest/beta: 122.0.6261.39 2024-02-15 (2759) 167MB -
latest/edge: 124.0.6315.2 2024-02-26 (2766) 168MB -
installed: 122.0.6261.69 (2764) 168MB -
It seems to me like "channel" is really track
and risk
seperated by a slash.
Another decision we could make here is we say the route is /snapcraft/v/:package/:track/:risk
e.g: /snapcraft/v/chromium/latest/stable
or /snapcraft/v/chromium/latest/edge
. Then it is totally clear and unambiguous what we are showing. I don't think it should be too onerous for the publisher of the package to supply those extra params. That's primarily who we're envisaging will be constructing the URL.
The other thing here is that for a given channel there may be multiple architectures in play. I think here we could take a cue from what we do with the docker version badge and take an optional ?arch
query param, which defaults to amd64
.
Some other snap packages you might find useful for testing are:
- gtk-common-themes (available for lots of architectures)
- thunderbird (multiple different channels all at different versions)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The project convention is using namedLogo by default only for social badges. This commit removes the default logo usage as this badge is not in the social category.
Keep 1 convention for the snapcraft badge, use only snapcraft and ditch snapstore.
Replace the costume render in SnapcraftVersion with renderVersionBadge
enhancing control and clarity
Added architecture query parameter: The snapcraft-version.service.js file now accepts an optional arch query parameter to specify the desired architecture for the Snap package. This defaults to amd64 if not provided. If an unsupported architecture is specified in the query parameter, a NotFound error is thrown with a specific message indicating that the requested architecture is not found. The snapcraft-version.tester.js file is updated to include a new test case that verifies the behavior when using the arch query parameter and also includes a test case for handling an invalid architecture.
const channelMap = parsedData['channel-map'] | ||
let filteredChannelMap = channelMap.filter( | ||
({ channel }) => channel.architecture === arch, | ||
) | ||
if (filteredChannelMap.length === 0) { | ||
throw new NotFound({ prettyMessage: 'arch not found' }) | ||
} | ||
filteredChannelMap = channelMap.filter( | ||
({ channel }) => channel.track === track, | ||
) | ||
if (filteredChannelMap.length === 0) { | ||
throw new NotFound({ prettyMessage: 'track not found' }) | ||
} | ||
filteredChannelMap = channelMap.filter( | ||
({ channel }) => channel.risk === risk, | ||
) | ||
if (filteredChannelMap.length === 0) { | ||
throw new NotFound({ prettyMessage: 'risk not found' }) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This code looks wrong to me. These filters should be combined with AND logic, but we're filtering channelMap
, assigning the result to filteredChannelMap
and then essentially throwing away that result and overwriting filteredChannelMap
. We're only really applying the last filter.
I think you really want to be doing
filteredChannelMap = filteredChannelMap.filter(...
for the second and third pass.
What would really help here would be if we split this filtering logic out into a transform()
function and write a few unit tests (in a spec.js) to make sure this is working as expected.
You might look at something like
services/docker/docker-version.spec.js
or
services/crates/crates-base.spec.js
as a point of inspiration.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The goal here was to filter by all conditions with logic and. Before this fix the only the logic of the last filter is used.
🚀 Updated review app: https://pr-9976-badges-shields.fly.dev |
This latest iteration is solid. Nice work 👍 |
When will this be available? 🤔 |
I ran a deploy this evening |
Thank you! |
Example badge render:
Path:
http://HOST/snapstore/v/:package
A few notes:
Fixes #9103