Skip to content
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 [Weblate] badges #6677

Merged
merged 7 commits into from
Jul 2, 2021
Merged

Add [Weblate] badges #6677

merged 7 commits into from
Jul 2, 2021

Conversation

SethFalco
Copy link
Contributor

@SethFalco SethFalco commented Jun 27, 2021

This adds Weblate badges to the repository.
Weblate is a free and open-source crowd translation platform.

Currently, it adds 8 badges:

Name Description
Weblate project translated The number of strings of a project that has been translated.
Weblate component license The license that a particular project component is under.
Weblate components/projects/users The total that exist on a Weblate instance.
Weblate user translations/suggestions/languages The number of user has made/done.

Examples:
image

I might make more badges later, but for now, I wanted to get these right.

Related

@shields-ci
Copy link

shields-ci commented Jun 27, 2021

Messages
📖 ✨ Thanks for your contribution to Shields, @SethFalco!

Generated by 🚫 dangerJS against b25ce54

@SethFalco SethFalco force-pushed the weblate-badges branch 5 times, most recently from 17d5be0 to eaf0878 Compare June 27, 2021 17:39
@SethFalco SethFalco marked this pull request as ready for review June 27, 2021 17:39
@calebcartwright calebcartwright added the service-badge Accepted and actionable changes, features, and bugs label Jun 27, 2021
@calebcartwright
Copy link
Member

Thank you for the PR! Haven't gone through the code in detail yet but a few comments/requests:

  • Could you please provide some context around the proposed badges (i.e. what is this badge for, what does it mean, etc.). For example, I'm not really sure what to make of the components or units badges amongst a few others. We want to make sure that the badges we provide make sense/serve a use case, but we don't need to provide a badge for data points just because those data points exist
  • It looks like Webplate heavily throttles unauthenticated requests (100/day) so for this to be a viable candidate we'd have to incorporate authentication on our requests (would also be helpful to get an idea of what if any rate limiting they apply on authenticated requests)
  • We've got a variety of helper functions for badge formatting as well, and based on the badges shown in the screenshot, we'll definitely at least need to leverage the metric formatter on any count/metric type messages
  • In cases where we've got a large quantity of badges we just about always end up encapsulating some of the common bits into either reusable functions defined in some common/helper file and/or via a base class, so probably worth seeing if there would be opportunities do to something similar here

@SethFalco
Copy link
Contributor Author

SethFalco commented Jun 27, 2021

Could you please provide some context around the proposed badges

  • Weblate project translated is the main one I wanted, displays how much of a project was translated.
  • Weblate user translations is how many strings a particular user has translated, I thought it could look nice on a GitHub README for users that translate a lot.
  • Weblate projects/components/users are how many things are on a particular Weblate instance. I'm not sure if these will be useful, but figured they're notable information for public Weblate hosts.

Admittedly, the rest were just convenient data-points to grab while I was doing the above. If it's preferred, I can remove them?

I'm not really sure what to make of the components or units badges amongst

I'll define them just so we're on the same page, but I appreciate your point.

  • Components - A "Project" might have multiple i18n files, or might split it between a "frontend" and "backend" component, for example.
  • Unit - An individual translatable string.

so for this to be a viable candidate we'd have to incorporate authentication on our requests

That would be possible with the public instance. I think overall it might be hard though since there are many hosts for Weblate. Even I host my own Weblate instance for my projects.

A non-exhaustive list can be found on the Discover page on Weblate's official website.

The API requests are rate limited; the default configuration limits it to 100 requests per day for anonymous users and 5000 requests per hour for authenticated users.
- https://docs.weblate.org/en/latest/api.html#api-rate-limiting

need to leverage the metric formatter on any count/metric type messages

Ahh, thanks for that! Will push this in a moment and update the screenshot.

large quantity of badges we just about always end up encapsulating some of the common bits

I've already done this a bit, but I can encapsulate more of it, so it's more reusable. I'll do this tonight/tomorrow.

Edit:
I assume it's fine if I make a new isMetric... test-validator?

We have one called isMetricOpenIssues, I'd like to make one inspired by this which uses custom text instead?
At least I don't see something which does this already, I think something like this might be nice?

const isMetricWithText = text => {
  const pattern = `^([1-9][0-9]*[kMGTPEZY]?|[1-9]\\.[1-9][kMGTPEZY]) ${text}$`
  const regexp = new RegExp(pattern)
  return withRegex(regexp)
}

const isMetricOpenIssues = isMetricWithText('open')

Unfortunately, JavaScript doesn't support \Q and \Z, so I can't make them literal, it seems. 🤔

@calebcartwright
Copy link
Member

I assume it's fine if I make a new isMetric... test-validator?

We have one called isMetricOpenIssues, I'd like to make one inspired by this which uses custom text instead?
At least I don't see something which does this already, I think something like this might be nice?

Sure! It's a bit of a balancing act of course as we don't want to bloat the helper files with single-use functions for bespoke cases, but we also don't want to reinvent the wheel in the individual service classes/tester files either.

I suspect we've probably got a few cases of such duplication, and if you see opportunities for encapsulating such a helper (regardless of whether that's with these proposed badges or things already merged) definitely feel free to suggest improvements/submit a PR.

I do think that'd probably be best handled via a separate PR which we could land first and this PR could then grab and utilize

@calebcartwright
Copy link
Member

That would be possible with the public instance. I think overall it might be hard though since there are many hosts for Weblate. Even I host my own Weblate instance for my projects.

Let me know if I'm off base but so far this sounds similar to some other badges we support, where there's a defacto public instance typically a SaaS-style offering but also comes in a downloadable/self-hostable form too. In these cases we add support to the service class for authenticated requests, configure our production environment with the auth info from an account we own against the main public instance, and then users that need to access an instance other than the main one and/or with their own auth will run their own self-hosted instance of the Shields server

@SethFalco
Copy link
Contributor Author

SethFalco commented Jun 29, 2021

  • I've updated this to use the new isMetricWithPattern method test-helper.
  • Removed the badge for units because the endpoint was incredibly slow and had timeouts often even with 10+ seconds.

this sounds similar to some other badges we support

Sounds valid for this one as well. I'll check how other services are configured and update this one to follow suit.

@SethFalco SethFalco marked this pull request as ready for review June 29, 2021 17:16
@calebcartwright
Copy link
Member

because the endpoint was incredibly slow and had timeouts often even with 10+ seconds.

Yikes! That's a good call. We have a ceiling of ~3-4 seconds total for the entire round trip to get the badges response back to users, otherwise they timeout and don't render in GitHub

@shields-cd shields-cd temporarily deployed to shields-staging-pr-6677 June 30, 2021 02:54 Inactive
Copy link
Member

@calebcartwright calebcartwright left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks again @SethFalco! Have taken a first pass through this and left some specific feedback inline below.

I'm not sure where we landed as far as which badges make sense to keep (i.e. which badges users will want/consume), so if some of the files/badges have gone out of scope feel free to remove those files and disregard feedback in those files

services/weblate/weblate-component-license.service.js Outdated Show resolved Hide resolved
services/weblate/weblate-component-license.tester.js Outdated Show resolved Hide resolved
services/weblate/weblate-entity-count.service.js Outdated Show resolved Hide resolved
services/weblate/weblate-entity-count.tester.js Outdated Show resolved Hide resolved
services/weblate/weblate-entity-count.service.js Outdated Show resolved Hide resolved
services/weblate/weblate-user-statistics.tester.js Outdated Show resolved Hide resolved
services/weblate/weblate-user-statistics.tester.js Outdated Show resolved Hide resolved
Co-authored-by: Caleb Cartwright <calebcartwright@users.noreply.github.com>
@shields-cd shields-cd temporarily deployed to shields-staging-pr-6677 July 1, 2021 13:09 Inactive
@lgtm-com
Copy link

lgtm-com bot commented Jul 1, 2021

This pull request introduces 1 alert when merging e9b517b into 08b8153 - view on LGTM.com

new alerts:

  • 1 for Unused variable, import, function or class

@shields-cd shields-cd temporarily deployed to shields-staging-pr-6677 July 1, 2021 13:30 Inactive
@shields-cd shields-cd temporarily deployed to shields-staging-pr-6677 July 1, 2021 13:33 Inactive
@SethFalco
Copy link
Contributor Author

SethFalco commented Jul 1, 2021

Thank you very much for giving such thorough feedback! I'll be sure to keep this in mind for future pull requests as well.

I believe I've adhered to all feedback. I've resolved the ones that I'm pretty confident I've done exactly as asked.
The ones left unresolved I'm hoping you can review for me, and resolve them if you think they're done, or drop a comment if I've missed something.

The only change I haven't done is the JSDoc one, thought I'd wait for further opinion.

I've also updated the screenshot in the PR description.*

I'm not sure where we landed as far as which badges make sense to keep

The only ones I'm pretty adamant on keeping are the following, as I have hopes to use these 2 myself:

  • Weblate project translated percentage
  • Weblate user translations

I've looked over the badges and removed 3 which, I believe, would have little to no use-case:

  • Weblate languages
  • Weblate user comments
  • Weblate user uploads

I've left the rest in, as I'd imagine there could be a use-case for them, however you're welcome to suggest otherwise. I have no strong feelings on the matter.

Edit: Sorry, I didn't think to edit the PR title until after I made all the changes. ^-^' Might want to rerun CI.

@shields-cd shields-cd temporarily deployed to shields-staging-pr-6677 July 1, 2021 13:45 Inactive
@shields-cd shields-cd temporarily deployed to shields-staging-pr-6677 July 1, 2021 13:50 Inactive
@SethFalco SethFalco changed the title [Weblate] Add badges Add Weblate badges [WeblateComponentLicense WeblateEntity WeblateProjectTranslatedPercentage WeblateUserStatistic] Jul 1, 2021
@calebcartwright calebcartwright changed the title Add Weblate badges [WeblateComponentLicense WeblateEntity WeblateProjectTranslatedPercentage WeblateUserStatistic] Add [Weblate] badges Jul 2, 2021
@calebcartwright
Copy link
Member

The only ones I'm pretty adamant on keeping are the following, as I have hopes to use these 2 myself:
I've looked over the badges and removed 3 which, I believe, would have little to no use-case:
I've left the rest in, as I'd imagine there could be a use-case for them, however you're welcome to suggest otherwise. I have no strong feelings on the matter.

No worries! I genuinely don't know enough about the service/what's meaningful for users so I'm not prescribing anything one way or another, just wasn't sure if we'd done any passes through

Edit: Sorry, I didn't think to edit the PR title until after I made all the changes. ^-^' Might want to rerun CI.

Have updated and restarted the ci jobs accordingly. The test matcher is smart enough (most of the time) to be able to just use the service name when you want to run all the tests like we do here, but we still give the individual testers more specific names so that we also have the option of running a subset of the tests, i.e. if in the future we make a change to the user translation badge then we can run just those tests vs. having to run the entire weblate suite.

Copy link
Member

@calebcartwright calebcartwright left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excellent work, thank you!

@SethFalco
Copy link
Contributor Author

SethFalco commented Jul 3, 2021

@calebcartwright Sorry to pester, just a few questions.

I just realized I forgot to add authentication on the PR.
I'll look into that and PR it separately.

Could I just check, should I only add support for an API key with the official instance, or could we try and support other instances?

For example, using the key WEBLATE_API_KEY for the official instance.
But supporting API keys for other Weblate instances on a per-instance basis with WEBLATE_API_KEY_I18N_EXAMPLE_ORG?

Then we could just take the domain (https://i18n.example.org) to get the respective API key if it's defined:

  • _ -> __
  • /[!A-Za-z\d]/g -> _
  • toUpperCase()

If there's a better way to do it, that'd be nicer. Meanwhile, I find it's very unlikely someone will define keys for i18n.example.domain.org and i18n.example-domain.org, for example. (which would become the same environment variable)


I also learned in the PR to Wikiapiary that it's possible to define enums in the URL pattern. 🤔
Would I be welcome to update the Weblate badge to change all user-statistic badges into a single badge that just uses:
weblate/user/:user/:statistic(translated|suggestions|languages|uploaded|commented)

I can also abstract the entity count one similarly:
weblate/:type(components|projects|users|languages)

This will reduce the total badge count (only 4 badges in total), and clean up the code/tests. Could be nice to leave in some of those extra options as well, since they'll just be part of the same badge?

(If required, I can do so while preserving backward compatibility as well I think.)

@SethFalco SethFalco deleted the weblate-badges branch July 3, 2021 13:07
@calebcartwright
Copy link
Member

Sorry to pester, just a few questions.

No worries at all, don't hesitate to ask any questions!

Would I be welcome to update the Weblate badge to change all user-statistic badges into a single badge that just uses:

Yes indeed. To be honest we need to adjust a few of these routes anyway to align with our badge route guidelines. In this case the badges are so new (and unused) that we don't need to bother with a redirector, so let's just correct the routes to what we want them to be and try to get it completed quickly. By any chance do you think you'll have bandwidth to get this done soon?

@SethFalco
Copy link
Contributor Author

By any chance do you think you'll have bandwidth to get this done soon?

No problem! Sorry about that.

Tomorrow I'll make a PR with the following changes:

  • Reduce the total badges and use the (...|...) syntax. (as mentioned above)

  • Replace /license with /l.

    License: /l

  • Default to https://hosted.weblate.org (it seems I can make server optional based on the docs)

    The parameter is for an uncommon optional attribute, like an alternate registry URL.

  • Review badge paths

    /SERVICE/NOUN/PARAMETERS?QUERYSTRING e.g: /github/issues/:user/:repo

After that PR is merged, I'll look at authentication again.
Feel free to let me know if there's anything you think I'm missing in that list.

@calebcartwright
Copy link
Member

I just realized I forgot to add authentication on the PR.
I'll look into that and PR it separately.

That one slipped my mind as well. That's a lower priority compared to adjusting the routes, but we should try to get this plugged in fairly quickly too given the low rate limit.

Could I just check, should I only add support for an API key with the official instance, or could we try and support other instances?

I'm not sure I follow what you're asking so will provide a broad answer to see if that covers, but please let me know if you still have any outstanding questions.

There are two core patterns we support for incorporating auth info in the requests we make to the upstream services

  • Private service-specific secrets with values set in the server runtime environment (either as an environment variable or in the config file)
  • User-provided values that are included in the badge request that we receive via a route or query parameter

The second one is something we tend to prefer to avoid as it's only viable in cases where the upstream service makes it possible to generate a strictly read-only token. Our codecov badge is one example of this where the badge route accepts a token query parameter.

The other cases follow that first pattern, where support for a secret is added to the server (currently supported secrets enumerated here) which allows any deployment of the badge server to define a value for that secret.

For the Shields.io service (which is essentially just the main deployment of the Shields server), we deploy with values provided for those various secrets using accounts that we own and manage on those upstream platforms (more details here: https://github.com/badges/shields/blob/master/doc/production-hosting.md).

Our secrets-setting mechanism doesn't support a variable number of secrets for multiple instances/tenants of a given service; there is a 1:1 mapping between a target service/platform and the corresponding auth secret for that service. This is just a basic reflection of practicality, as it wouldn't be realistic nor necessary for that matter for the main Shields.io instance to be able to authenticate with an open ended number of instances of a given service/tool/platform.

That pattern needs to apply here as well: there should only be one secret defined for weblate. It sounds like there's a de facto public instance, so once the server code is updated to support the new weblate secret then one of us on the Shields maintainer team will create an account and generate the corresponding values, which we'll then plug in to the Shields.io runtime.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
service-badge Accepted and actionable changes, features, and bugs
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants