badges/shields

Github Actions Workflow badge not working for "branchless" push

chris48s opened this issue · 7 comments

Discussed in #8719

Originally posted by StormFX December 16, 2022
I didn't want to create an issue for what simply be user error on my end, but I can't seem to get my build status badges to work since the change to the badge routes.

I have, for example, a repo at SFX-WoW/Masque. My workflows are in .github/workflows, thus, the URL for a status badge should be https://img.shields.io/github/actions/workflow/status/SFX-WoW/Masque/build-release.yml?branch=main according to #8671, But it doesn't work. It says, "repo or workflow not found". If I remove the workflows/ it changes to, "branch or event not found". Any ideas?

Edit: I also tried the URL generator and it doesn't work, either.

Mind you, I don't know that much about Shields.io's API, but it seems like the changes brought it more in parity with GitHub's API, at least as far as functionality. As I mentioned in #8671, GitHub's badges work with no branch filter in the workflow if no branch parameter is specified in the URL. It seems like the parameters (or lack thereof) target only workflows with explicit filters (or no parameter-specific filters). Therefore, it seems the logical solution would be for Shields API to allow no parameters and in that case, target workflows with no relevant filters.

Example: GitHub with no branch/event parameter:
Example

Having done a bit of work on this, I think there are 2 possible options:

  1. API-based: Introduce some kind of 'branchless' option which just takes the first workflow run for any branch (or ref, or whatever). I think this probably doesn't make sense as the default in all cases if no branch= param is supplied though. Picking the latest workflow run for any branch is one of the things that lead to confusing outputs with the old implementation. If we're going to do this, it should be opt-in for users who want/need it. I think the way I'd probably suggest we do implement if we go down this route is we make this behaviour conditional on ?branch=* (and document that). The reason I suggest that is because we can't have a case where the special value for "use the latest workflow run on any branch" is also the name of a branch in someone's repo. Neither git nor GitHub will allow me to create a branch called *. GitHub says "Sorry, the branch cannot be blank". git says fatal: '*' is not a valid branch name..
  2. Switch the badge from using the API to being a 'scraper' for GitHub's native badge (the version which uses the workflow filename) that just behaves exactly the same way as the native one but allows the shields style customisations (styles, colours, icons, ets) on top of it. Doing this option would make everyone happy in this thread and also solve #8733 too. The one thing we lose by doing that (instead of using the API) is that the people who wanted the ability to use this badge for private repos on a self-hosted shields instance won't be able to have it, but we've yet to put out a tagged docker release with a changelog entry saying that feature exists, so I feel like we're not really pulling the rug out from anyone yet if we do that.

Although they are two different issues, I think I'd like to also consider #8733 (which is slightly more serious IMO as that is reporting actively misleading data in some cases) in working out what we do next. My instinct at this point is to go with option 2. Option 1 would be predicated on adopting one of the other solutions to #8733 . All ears if anyone else has a better plan.

I'd have to concur that if 2 solves the issue in #8733, then it's probably the best option as it solves multiple issues. More importantly, it maintains a degree of backwards compatibility (aside from the route changes) so that users won't need to change their workflows. I'm not sure if there's any performance impact from using scraping, though.

At the same time, I'm not sure if throwing away the self-hosted option is completely ideal. Would it be possible to use a separate route for the "scraping" API and leave the existing API in place for those users that have already made the appropriate changes and then put a redirect for the old badges to the "scraping" route? Alternatively, what about doing a switch based on the parameters passed. Eg, if no branch or event is passed (or another parameter is passed, say native=true or something) via query parameters, scrape the native badge, otherwise, pull the info based on the query like it is now.

Unrelated Side Note: I'm sort of on the fence about the rationale for using branch filters. On the one hand, it does restrict the workflow to the exact branch and/or event, limiting the potential for "misfires". On the other hand, many repos only have a single branch (I have a handful that have no need for additional branches). Perhaps part of the documentation should include a recommendation for using branch filters in workflows, if only for future-proofing.

In case it matters, my preference is also for option 2, but mostly by process of elimination, on account that I believe that having to issue ?branch=* to see builds belonging to tags that, from a user's perspective, should also belong to a branch and therefore be resolved if they specify a branch name, is going to be confusing.

In other words, if you go with ?branch=* for tagged vs ?branch=main for non tagged, you're pretty much guaranteed to get repeat questions in the long run, about why the user can't simply use ?branch=main to get the tagged builds, especially if they have only one branch in the first place...

In that respect, option 2 seems the more intuitive approach for the end user.

Same issue for me with https://github.com/fxstein/GoProX

Will follow this discussion. Thanks!

We've just merged #8738 and deployed to production. Branch is no longer a required param.