shields icon indicating copy to clipboard operation
shields copied to clipboard

[Maven] Support for maven central snapshots

Open Doc94 opened this issue 9 months ago • 7 comments

This PR close #10894 making a replicate of the current services for maven-central but for the snapshots feature added recently.

Doc94 avatar Apr 05 '25 15:04 Doc94

Messages
:book: :sparkles: Thanks for your contribution to Shields, @Doc94!

Generated by :no_entry_sign: dangerJS against 732efeac726c2f0474a74f5c35cc069ff8f65258

github-actions[bot] avatar Apr 05 '25 15:04 github-actions[bot]

looking forward to this!

portlek avatar Apr 24 '25 06:04 portlek

OK, so we've got 2 things going on here.

First lets take the last updated badge. This one should be fairly simple to land. Fundamanetally, MavenCentralLastUpdate and MavenCentralSnapshotsLastUpdate are quite similar and there's a lot of copy/paste going on here. I'd like us to restructure both services and DRY this up so the common parts are not duplicated. Here's a suggested implementation:

import Joi from 'joi'
import { pathParams, BaseXmlService } from '../index.js'
import { parseDate, renderDateBadge } from '../date.js'
import { nonNegativeInteger } from '../validators.js'

const updateResponseSchema = Joi.object({
  metadata: Joi.object({
    versioning: Joi.object({
      lastUpdated: nonNegativeInteger,
    }).required(),
  }).required(),
}).required()

class MavenCentralLastUpdateBase extends BaseXmlService {
  static category = 'activity'

  static defaultBadgeData = { label: 'last updated' }

  async handle({ groupId, artifactId }) {
    const { metadata } = await this.fetch({
      groupId,
      artifactId,
      schema: updateResponseSchema,
    })

    const date = parseDate(
      String(metadata.versioning.lastUpdated),
      'YYYYMMDDHHmmss',
    )

    return renderDateBadge(date)
  }

  static encodeParams({ groupId, artifactId }) {
    return {
      group: encodeURIComponent(groupId).replace(/\./g, '/'),
      artifact: encodeURIComponent(artifactId),
    }
  }
}

class MavenCentralLastUpdate extends MavenCentralLastUpdateBase {
  static route = {
    base: 'maven-central/last-update',
    pattern: ':groupId/:artifactId',
  }

  static openApi = {
    '/maven-central/last-update/{groupId}/{artifactId}': {
      get: {
        summary: 'Maven Central Last Update',
        parameters: pathParams(
          { name: 'groupId', example: 'com.google.guava' },
          { name: 'artifactId', example: 'guava' },
        ),
      },
    },
  }

  async fetch({ groupId, artifactId, schema }) {
    const { group, artifact } = this.constructor.encodeParams({
      groupId,
      artifactId,
    })
    return this._requestXml({
      schema,
      url: `https://repo1.maven.org/maven2/${group}/${artifact}/maven-metadata.xml`,
      httpErrors: { 404: 'artifact not found' },
    })
  }
}

class MavenCentralSnapshotsLastUpdate extends MavenCentralLastUpdateBase {
  static route = {
    base: 'maven-central-snapshots/last-update',
    pattern: ':groupId/:artifactId',
  }

  static openApi = {
    '/maven-central-snapshots/last-update/{groupId}/{artifactId}': {
      get: {
        summary: 'Maven Central Snapshots Last Update',
        parameters: pathParams(
          { name: 'groupId', example: 'me.mrdoc.minecraft' },
          { name: 'artifactId', example: 'dlibcustomextensions' },
        ),
      },
    },
  }

  async fetch({ groupId, artifactId, schema }) {
    const { group, artifact } = this.constructor.encodeParams({
      groupId,
      artifactId,
    })
    return this._requestXml({
      schema,
      url: `https://central.sonatype.com/repository/maven-snapshots/${group}/${artifact}/maven-metadata.xml`,
      httpErrors: { 404: 'artifact not found' },
    })
  }
}

export default [MavenCentralLastUpdate, MavenCentralSnapshotsLastUpdate]

(that can all go in one file)

chris48s avatar Apr 26 '25 19:04 chris48s

Hey guys,

what is the progress on that? 😇 @Doc94 still interested in fixing the stuff? I would love to use shields for snapshot releases.

StefMa avatar May 21 '25 10:05 StefMa

Hey guys,

what is the progress on that? 😇 @Doc94 still interested in fixing the stuff? I would love to use shields for snapshot releases.

not sure if wait to the PR for the order of versions based in how this can change how need handle all here for refactor

Doc94 avatar May 22 '25 12:05 Doc94

For the time-being, you could use something like:

![Maven metadata URL](https://img.shields.io/maven-metadata/v?metadataUrl=https%3A%2F%2Fcentral.sonatype.com%2Frepository%2Fmaven-snapshots%2Fcom%2Fexample%2FartifactId%2Fmaven-metadata.xml)

ethauvin avatar Jul 04 '25 23:07 ethauvin

If someone wants to come back and rebase + finish this, we've now merged https://github.com/badges/shields/pull/11077

This badge (snapshot version) can still be a forwarder to the maven metadata badge but..

  • We should ignore the old prefix/sufffix params and just expose filter, which is more versatile
  • We should either expose the strategy param, or possibly hard-code it to release or latest if the default strategy doesn't make sense for snapshots (I'm not really clued up enough to make that judgement)

chris48s avatar Jul 05 '25 08:07 chris48s