diff --git a/services/gitea/gitea-last-commit.service.js b/services/gitea/gitea-last-commit.service.js new file mode 100644 index 0000000000000..cb40bb48becb7 --- /dev/null +++ b/services/gitea/gitea-last-commit.service.js @@ -0,0 +1,138 @@ +import Joi from 'joi' +import { pathParam, queryParam } from '../index.js' +import { optionalUrl } from '../validators.js' +import { formatDate } from '../text-formatters.js' +import { age as ageColor } from '../color-formatters.js' +import GiteaBase from './gitea-base.js' +import { description, httpErrorsFor } from './gitea-helper.js' + +const schema = Joi.array() + .items( + Joi.object({ + commit: Joi.object({ + author: Joi.object({ + date: Joi.string().required(), + }).required(), + committer: Joi.object({ + date: Joi.string().required(), + }).required(), + }).required(), + }).required(), + ) + .required() + .min(1) + +const displayEnum = ['author', 'committer'] + +const queryParamSchema = Joi.object({ + gitea_url: optionalUrl, + display_timestamp: Joi.string() + .valid(...displayEnum) + .default('author'), +}).required() + +export default class GiteaLastCommit extends GiteaBase { + static category = 'activity' + + static route = { + base: 'gitea/last-commit', + pattern: ':user/:repo/:branch*', + queryParamSchema, + } + + static openApi = { + '/gitea/last-commit/{user}/{repo}': { + get: { + summary: 'Gitea Last Commit', + description, + parameters: [ + pathParam({ + name: 'user', + example: 'gitea', + }), + pathParam({ + name: 'repo', + example: 'tea', + }), + queryParam({ + name: 'display_timestamp', + example: 'committer', + schema: { type: 'string', enum: displayEnum }, + description: 'Defaults to `author` if not specified', + }), + queryParam({ + name: 'gitea_url', + example: 'https://gitea.com', + }), + ], + }, + }, + '/gitea/last-commit/{user}/{repo}/{branch}': { + get: { + summary: 'Gitea Last Commit (branch)', + description, + parameters: [ + pathParam({ + name: 'user', + example: 'gitea', + }), + pathParam({ + name: 'repo', + example: 'tea', + }), + pathParam({ + name: 'branch', + example: 'main', + }), + queryParam({ + name: 'display_timestamp', + example: 'committer', + schema: { type: 'string', enum: displayEnum }, + description: 'Defaults to `author` if not specified', + }), + queryParam({ + name: 'gitea_url', + example: 'https://gitea.com', + }), + ], + }, + }, + } + + static defaultBadgeData = { label: 'last commit' } + + static render({ commitDate }) { + return { + message: formatDate(commitDate), + color: ageColor(Date.parse(commitDate)), + } + } + + async fetch({ user, repo, branch, baseUrl }) { + // https://gitea.com/api/swagger#/repository + return super.fetch({ + schema, + url: `${baseUrl}/api/v1/repos/${user}/${repo}/commits`, + options: { searchParams: { sha: branch } }, + httpErrors: httpErrorsFor(), + }) + } + + async handle( + { user, repo, branch }, + { + gitea_url: baseUrl = 'https://gitea.com', + display_timestamp: displayTimestamp, + }, + ) { + const body = await this.fetch({ + user, + repo, + branch, + baseUrl, + }) + return this.constructor.render({ + commitDate: body[0].commit[displayTimestamp].date, + }) + } +} diff --git a/services/gitea/gitea-last-commit.tester.js b/services/gitea/gitea-last-commit.tester.js new file mode 100644 index 0000000000000..bc1e133cbfd68 --- /dev/null +++ b/services/gitea/gitea-last-commit.tester.js @@ -0,0 +1,32 @@ +import { isFormattedDate } from '../test-validators.js' +import { createServiceTester } from '../tester.js' + +export const t = await createServiceTester() + +t.create('Last Commit (recent)').get('/gitea/tea.json').expectBadge({ + label: 'last commit', + message: isFormattedDate, +}) + +t.create('Last Commit (recent) (self-managed)') + .get('/CanisHelix/shields-badge-test.json?gitea_url=https://codeberg.org') + .expectBadge({ + label: 'last commit', + message: isFormattedDate, + }) + +t.create('Last Commit (on-branch) (self-managed)') + .get( + '/CanisHelix/shields-badge-test/scoped.json?gitea_url=https://codeberg.org', + ) + .expectBadge({ + label: 'last commit', + message: isFormattedDate, + }) + +t.create('Last Commit (project not found)') + .get('/CanisHelix/does-not-exist.json?gitea_url=https://codeberg.org') + .expectBadge({ + label: 'last commit', + message: 'user or repo not found', + })