From fde6040eda2fa6413c2ed831ff1a286aa96edd9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Palmeiro?= Date: Mon, 5 Aug 2024 08:15:12 +0100 Subject: [PATCH] Added support for fetching latest release from GitLab (#7418) * Fetch version for GitLab repositories * Update documentation about repositories * Fix code formatting --- docs/setup/adding-a-git-repository.md | 13 ++++-- .../components/source/facts/gitlab/index.ts | 45 +++++++++++++++---- 2 files changed, 46 insertions(+), 12 deletions(-) diff --git a/docs/setup/adding-a-git-repository.md b/docs/setup/adding-a-git-repository.md index 955bdb95160..6ddbc0fce30 100644 --- a/docs/setup/adding-a-git-repository.md +++ b/docs/setup/adding-a-git-repository.md @@ -22,20 +22,25 @@ repo_url: https://github.com/squidfunk/mkdocs-material The link to the repository will be rendered next to the search bar on big screens and as part of the main navigation drawer on smaller screen sizes. -Additionally, for public repositories hosted on [GitHub] or [GitLab], the -number of stars and forks is automatically requested and rendered. -GitHub repositories also include the tag of the latest release.[^1] +Additionally, for public repositories hosted on [GitHub] or [GitLab], the +latest release tag[^1], as well as the number of stars and forks, are +automatically requested and rendered. [^1]: Unfortunately, GitHub only provides an API endpoint to obtain the [latest release] - not the latest tag. Thus, make sure to [create a release] (not pre-release) for the latest tag you want to display next to the number of - stars and forks. + stars and forks. For GitLab, although it is possible to get a [list of tags + sorted by update time], the [equivalent API endpoint] is used. So, make sure + you also [create a release for GitLab repositories]. [repo_url]: https://www.mkdocs.org/user-guide/configuration/#repo_url [latest release]: https://docs.github.com/en/rest/reference/releases#get-the-latest-release [create a release]: https://docs.github.com/en/repositories/releasing-projects-on-github/managing-releases-in-a-repository#creating-a-release + [list of tags sorted by update time]: https://docs.gitlab.com/ee/api/tags.html#list-project-repository-tags + [equivalent API endpoint]: https://docs.gitlab.com/ee/api/releases/#get-the-latest-release + [create a release for GitLab repositories]: https://docs.gitlab.com/ee/user/project/releases/#create-a-release #### Repository name diff --git a/src/templates/assets/javascripts/components/source/facts/gitlab/index.ts b/src/templates/assets/javascripts/components/source/facts/gitlab/index.ts index c32772e2f29..034a6757a2a 100644 --- a/src/templates/assets/javascripts/components/source/facts/gitlab/index.ts +++ b/src/templates/assets/javascripts/components/source/facts/gitlab/index.ts @@ -26,13 +26,25 @@ import { Observable, catchError, defaultIfEmpty, - map + map, + zip } from "rxjs" import { requestJSON } from "~/browser" import { SourceFacts } from "../_" +/* ---------------------------------------------------------------------------- + * Helper types + * ------------------------------------------------------------------------- */ + +/** + * GitLab release (partial) + */ +interface Release { // @todo remove and use the ReleaseSchema type instead after switching from gitlab to @gitbeaker/rest + tag_name: string /* Tag name */ +} + /* ---------------------------------------------------------------------------- * Functions * ------------------------------------------------------------------------- */ @@ -49,13 +61,30 @@ export function fetchSourceFactsFromGitLab( base: string, project: string ): Observable { const url = `https://${base}/api/v4/projects/${encodeURIComponent(project)}` - return requestJSON(url) + return zip( + + /* Fetch version */ + requestJSON(`${url}/releases/permalink/latest`) + .pipe( + catchError(() => EMPTY), // @todo refactor instant loading + map(({ tag_name }) => ({ + version: tag_name + })), + defaultIfEmpty({}) + ), + + /* Fetch stars and forks */ + requestJSON(url) + .pipe( + catchError(() => EMPTY), // @todo refactor instant loading + map(({ star_count, forks_count }) => ({ + stars: star_count, + forks: forks_count + })), + defaultIfEmpty({}) + ) + ) .pipe( - catchError(() => EMPTY), // @todo refactor instant loading - map(({ star_count, forks_count }) => ({ - stars: star_count, - forks: forks_count - })), - defaultIfEmpty({}) + map(([release, info]) => ({ ...release, ...info })) ) }