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

[BitbucketLastCommit] Add Bitbucket last commit #10043

Merged
merged 9 commits into from
Mar 25, 2024
81 changes: 81 additions & 0 deletions services/bitbucket/bitbucket-last-commit.service.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import Joi from 'joi'
import { age as ageColor } from '../color-formatters.js'
import { BaseJsonService, NotFound, pathParam, queryParam } from '../index.js'
import { formatDate } from '../text-formatters.js'
import { relativeUri } from '../validators.js'

const schema = Joi.object({
values: Joi.array().items({
date: Joi.string().isoDate().required(),
}),
}).required()

const queryParamSchema = Joi.object({
path: relativeUri,
}).required()

export default class BitbucketLastCommit extends BaseJsonService {
static category = 'activity'
static route = {
base: 'bitbucket/last-commit',
pattern: ':user/:repo/:branch+',
queryParamSchema,
}

static openApi = {
'/bitbucket/last-commit/{user}/{repo}/{branch}': {
get: {
summary: 'Bitbucket last commit',
parameters: [
pathParam({ name: 'user', example: 'shields-io' }),
pathParam({ name: 'repo', example: 'test-repo' }),
pathParam({ name: 'branch', example: 'main' }),
queryParam({
name: 'path',
example: 'README.md',
schema: { type: 'string' },
description: 'File path to resolve the last commit for.',
}),
],
},
},
}

static defaultBadgeData = { label: 'last commit' }

static render({ commitDate }) {
return {
message: formatDate(commitDate),
color: ageColor(Date.parse(commitDate)),
}
}

async fetch({ user, repo, branch, path }) {
// https://developer.atlassian.com/cloud/bitbucket/rest/api-group-commits/#api-repositories-workspace-repo-slug-commits-get
return this._requestJson({
url: `https://bitbucket.org/api/2.0/repositories/${user}/${repo}/commits/${branch}`,
options: {
searchParams: {
path,
pagelen: 1,
fields: 'values.date',
},
},
schema,
httpErrors: {
403: 'private repo',
404: 'user, repo or branch not found',
},
})
}

async handle({ user, repo, branch }, queryParams) {
const { path } = queryParams
const data = await this.fetch({ user, repo, branch, path })
const [commit] = data.values

if (!commit) throw new NotFound({ prettyMessage: 'no commits found' })

return this.constructor.render({ commitDate: commit.date })
}
}
41 changes: 41 additions & 0 deletions services/bitbucket/bitbucket-last-commit.tester.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { isFormattedDate } from '../test-validators.js'
import { ServiceTester } from '../tester.js'

export const t = new ServiceTester({
id: 'BitbucketLastCommit',
title: 'Bitbucket last commit',
pathPrefix: '/bitbucket/last-commit',
})

t.create('last commit')
.get('/shields-io/test-repo/main.json')
.expectBadge({ label: 'last commit', message: isFormattedDate })

t.create('last commit (path)')
.get('/shields-io/test-repo/main.json?path=README.md')
.expectBadge({ label: 'last commit', message: isFormattedDate })

t.create('last commit (user not found)')
.get('/not-a-user/test-repo/main.json')
.expectBadge({
label: 'last commit',
message: 'user, repo or branch not found',
})

t.create('last commit (repo not found)')
.get('/shields-io/not-a-repo/main.json')
.expectBadge({
label: 'last commit',
message: 'user, repo or branch not found',
})

t.create('last commit (branch not found)')
.get('/shields-io/test-repo/not-a-branch.json')
.expectBadge({
label: 'last commit',
message: 'user, repo or branch not found',
})

t.create('last commit (path not found)')
.get('/shields-io/test-repo/main.json?path=not/a/dir')
.expectBadge({ label: 'last commit', message: 'no commits found' })
Loading