Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
237 changes: 118 additions & 119 deletions pom.xml
Original file line number Diff line number Diff line change
@@ -1,124 +1,123 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>plugin</artifactId>
<version>6.2116.v7501b_67dc517</version>
<relativePath/>
</parent>

<groupId>io.jenkins.plugins</groupId>
<artifactId>quay-tag-parameter</artifactId>
<version>${changelist}</version>
<packaging>hpi</packaging>

<name>Quay Tag Parameter Plugin</name>
<description>Jenkins plugin to fetch and select Docker images/tags from Quay.io repositories</description>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>plugin</artifactId>
<version>6.2116.v7501b_67dc517</version>
<relativePath />
</parent>

<groupId>io.jenkins.plugins</groupId>
<artifactId>quay-tag-parameter</artifactId>
<version>${changelist}</version>
<packaging>hpi</packaging>

<name>Quay Tag Parameter Plugin</name>
<description>Jenkins plugin to fetch and select Docker images/tags from Quay.io repositories</description>
<url>https://github.com/jenkinsci/quay-tag-parameter-plugin</url>

<licenses>
<license>
<name>MIT License</name>
<url>https://opensource.org/licenses/MIT</url>
</license>
</licenses>

<scm>
<connection>scm:git:https://github.com/jenkinsci/quay-tag-parameter-plugin.git</connection>
<developerConnection>scm:git:git@github.com:jenkinsci/quay-tag-parameter-plugin.git</developerConnection>
<tag>${scmTag}</tag>
<url>https://github.com/jenkinsci/quay-tag-parameter-plugin</url>

<licenses>
<license>
<name>MIT License</name>
<url>https://opensource.org/licenses/MIT</url>
</license>
</licenses>

<scm>
<connection>scm:git:https://github.com/jenkinsci/quay-tag-parameter-plugin.git</connection>
<developerConnection>scm:git:git@github.com:jenkinsci/quay-tag-parameter-plugin.git</developerConnection>
<url>https://github.com/jenkinsci/quay-tag-parameter-plugin</url>
<tag>${scmTag}</tag>
</scm>

<properties>
<changelist>999999-SNAPSHOT</changelist>
<jenkins.baseline>2.528</jenkins.baseline>
<jenkins.version>${jenkins.baseline}.3</jenkins.version>
<gitHubRepo>jenkinsci/quay-tag-parameter-plugin</gitHubRepo>
<hpi.compatibleSinceVersion>1.0.0</hpi.compatibleSinceVersion>
<spotless.check.skip>false</spotless.check.skip>
<hpi.strictBundledArtifacts>true</hpi.strictBundledArtifacts>
<ban-commons-lang-2.skip>false</ban-commons-lang-2.skip>
</properties>

<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.jenkins.tools.bom</groupId>
<artifactId>bom-${jenkins.baseline}.x</artifactId>
<version>5983.v443959746f1f</version>
<scope>import</scope>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>

</scm>

<properties>
<changelist>999999-SNAPSHOT</changelist>
<jenkins.baseline>2.528</jenkins.baseline>
<jenkins.version>${jenkins.baseline}.3</jenkins.version>
<gitHubRepo>jenkinsci/quay-tag-parameter-plugin</gitHubRepo>
<hpi.compatibleSinceVersion>1.0.0</hpi.compatibleSinceVersion>
<spotless.check.skip>false</spotless.check.skip>
<hpi.strictBundledArtifacts>true</hpi.strictBundledArtifacts>
<ban-commons-lang-2.skip>false</ban-commons-lang-2.skip>
<ban-junit4-imports.skip>false</ban-junit4-imports.skip>
</properties>

<dependencyManagement>
<dependencies>
<!-- Jenkins Credentials Plugin -->
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>credentials</artifactId>
</dependency>

<!-- Plain Credentials for Secret Text -->
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>plain-credentials</artifactId>
</dependency>

<!-- Jenkins Pipeline Support -->
<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-step-api</artifactId>
</dependency>

<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-cps</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-job</artifactId>
<scope>test</scope>
</dependency>

<!-- OkHttp API Plugin -->
<dependency>
<groupId>io.jenkins.plugins</groupId>
<artifactId>okhttp-api</artifactId>
</dependency>

<!-- Jackson API Plugin -->
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>jackson2-api</artifactId>
</dependency>

<!-- Test dependencies -->
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.jenkins.tools.bom</groupId>
<artifactId>bom-${jenkins.baseline}.x</artifactId>
<version>5983.v443959746f1f</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>

<repositories>
<repository>
<id>repo.jenkins-ci.org</id>
<url>https://repo.jenkins-ci.org/public/</url>
</repository>
</repositories>

<pluginRepositories>
<pluginRepository>
<id>repo.jenkins-ci.org</id>
<url>https://repo.jenkins-ci.org/public/</url>
</pluginRepository>
</pluginRepositories>
</dependencyManagement>

<dependencies>

<!-- OkHttp API Plugin -->
<dependency>
<groupId>io.jenkins.plugins</groupId>
<artifactId>okhttp-api</artifactId>
</dependency>
<!-- Jenkins Credentials Plugin -->
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>credentials</artifactId>
</dependency>

<!-- Jackson API Plugin -->
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>jackson2-api</artifactId>
</dependency>

<!-- Plain Credentials for Secret Text -->
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>plain-credentials</artifactId>
</dependency>

<!-- Jenkins Pipeline Support -->
<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-step-api</artifactId>
</dependency>

<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-cps</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-job</artifactId>
<scope>test</scope>
</dependency>

<!-- Test dependencies -->
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<repositories>
<repository>
<id>repo.jenkins-ci.org</id>
<url>https://repo.jenkins-ci.org/public/</url>
</repository>
</repositories>

<pluginRepositories>
<pluginRepository>
<id>repo.jenkins-ci.org</id>
<url>https://repo.jenkins-ci.org/public/</url>
</pluginRepository>
</pluginRepositories>
</project>
39 changes: 19 additions & 20 deletions src/main/java/io/jenkins/plugins/quay/QuayClient.java
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
package io.jenkins.plugins.quay;

import com.fasterxml.jackson.databind.ObjectMapper;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import hudson.util.Secret;
import io.jenkins.plugins.quay.model.QuayTag;
import io.jenkins.plugins.quay.model.QuayTagResponse;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
Expand All @@ -17,6 +14,9 @@
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

/**
* Client for interacting with Quay.io REST API v1.
Expand Down Expand Up @@ -141,9 +141,7 @@ public List<QuayTag> getTags(String organization, String repository, int limit)
public boolean validateRepository(String organization, String repository) {
try {
String url = String.format("%s/repository/%s/%s", QUAY_API_BASE, organization, repository);
Request.Builder requestBuilder = new Request.Builder()
.url(url)
.get();
Request.Builder requestBuilder = new Request.Builder().url(url).get();

addAuthHeader(requestBuilder);

Expand Down Expand Up @@ -175,16 +173,15 @@ public static String buildImageReference(String organization, String repository,
return String.format("quay.io/%s/%s:%s", organization, repository, tag);
}

@SuppressFBWarnings("NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE")
Copy link
Author

Choose a reason for hiding this comment

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

Build failed otherwise.

private List<QuayTag> fetchTagsFromApi(String organization, String repository, int limit) throws QuayApiException {
String url = String.format("%s/repository/%s/%s/tag/?limit=%d&onlyActiveTags=true",
String url = String.format(
"%s/repository/%s/%s/tag/?limit=%d&onlyActiveTags=true",
QUAY_API_BASE, organization, repository, limit);

LOGGER.fine("Fetching tags from: " + url);

Request.Builder requestBuilder = new Request.Builder()
.url(url)
.get()
.header("Accept", "application/json");
Request.Builder requestBuilder = new Request.Builder().url(url).get().header("Accept", "application/json");

addAuthHeader(requestBuilder);

Expand Down Expand Up @@ -221,7 +218,8 @@ private void addAuthHeader(Request.Builder requestBuilder) {
}
}

private void handleErrorResponse(Response response, String organization, String repository) throws QuayApiException {
private void handleErrorResponse(Response response, String organization, String repository)
throws QuayApiException {
int code = response.code();
String message;

Expand All @@ -230,12 +228,12 @@ private void handleErrorResponse(Response response, String organization, String
message = "Authentication failed. Please check your Quay.io credentials.";
break;
case 403:
message = "Access denied to repository " + organization + "/" + repository +
". Ensure you have permission and valid credentials.";
message = "Access denied to repository " + organization + "/" + repository
+ ". Ensure you have permission and valid credentials.";
break;
case 404:
message = "Repository " + organization + "/" + repository + " not found. " +
"Please verify the organization and repository names.";
message = "Repository " + organization + "/" + repository + " not found. "
+ "Please verify the organization and repository names.";
break;
case 429:
message = "Rate limit exceeded. Please try again later.";
Expand All @@ -254,13 +252,14 @@ private void validateInput(String value, String fieldName) throws QuayApiExcepti
}
// Basic validation - no special characters that could cause issues
if (!value.matches("^[a-zA-Z0-9._/-]+$")) {
throw new QuayApiException(fieldName + " contains invalid characters. " +
"Only alphanumeric characters, dots, underscores, slashes, and hyphens are allowed.");
throw new QuayApiException(fieldName + " contains invalid characters. "
+ "Only alphanumeric characters, dots, underscores, slashes, and hyphens are allowed.");
}
}

private String buildCacheKey(String organization, String repository, int limit) {
String tokenHash = apiToken != null ? String.valueOf(apiToken.getEncryptedValue().hashCode()) : "public";
String tokenHash =
apiToken != null ? String.valueOf(apiToken.getEncryptedValue().hashCode()) : "public";
return String.format("%s/%s:%d:%s", organization, repository, limit, tokenHash);
}

Expand Down
Loading