Skip to content

Conversation

@sahilm02
Copy link

Fixes JENKINS-75582

MultiBinding implementation for the PersonalAccessTokenImpl class PersonalAccessToken interface.

Testing done

A test was introduced to run the complete pipeline and validate withCredentials, using both the full $class syntax and the personalAccessTokenId binding.

Submitter checklist

  • Make sure you are opening from a topic/feature/bugfix branch (right side) and not your main branch!
  • Ensure that the pull request title represents the desired changelog entry
  • Please describe what you did
  • Link to relevant issues in GitHub or Jira
  • Link to relevant pull requests, esp. upstream and downstream changes
  • Ensure you have provided tests - that demonstrates feature works or fixes the issue

Copy link

@MarkEWaite MarkEWaite left a comment

Choose a reason for hiding this comment

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

Minor change needed to sort the imports in order to satisfy checkstyle.

Testing done:

Confirmed that the Pipeline syntax snippet generator shows the correct syntax, of the form:

withCredentials([giteaPersonalAccessToken(credentialsId: 'my-gitea-token', variable: 'MY_VAR')]) {
    // some block
}

Confirmed that the localized form of the variable property and the
credentials property are displayed as expected.

Confirmed that my sample Pipeline worked:

pipeline {
    agent {
        label 'alpine'
    }
    stages {
        stage('Checkout') {
            steps {
                withCredentials([giteaPersonalAccessToken(credentialsId: 'gitea-token', variable: 'ABC')]) {
                  sh 'git clone http://[email protected]:3000/mwaite/bin.git'
                }
            }
        }
    }
}
@MarkEWaite
Copy link

MarkEWaite commented Apr 25, 2025

The Jenkins Pipeline syntax snippet generator needs some additions to the pull request. The file src/main/resources/org/jenkinsci/plugin/gitea/credentials/PersonalAccessTokenBinding/config.jelly is needed in order to allow the generator to display the form.

I've made several changes and tested my changes interactively and think that they are ready for you to consider including them in this pull request.

https://github.com/MarkEWaite/gitea-plugin/tree/feature/withCredentials-support

sahilm02 and others added 4 commits April 25, 2025 12:29
No need to declare the package of the script.  Use the default.

No need to declare the full path to the PersonalAccessTokenBinding class,
let Jenkins find it by searching.

Add a newline to the end of the file.
…/gitea-plugin into feature/withCredentials-support
@MarkEWaite
Copy link

I added two more changes for your consideration:

  • c214a56 Add giteaPersonalAccessToken documentation and example
  • 33b0b22 Simplify test script

sahilm02 and others added 3 commits April 25, 2025 16:43
Copy link

@MarkEWaite MarkEWaite left a comment

Choose a reason for hiding this comment

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

This has passed my interactive testing, works with the Pipeline syntax snippet generator, works with localized versions of the Variable and Credentials property, includes documentation, and includes automated tests that exercise the new functionality.

I'd appreciate an (optional) review from @jglick as the expert on credentials binding implementations, but I accept that he may not have time to review it. I believe this is ready to merge and release.

@MarkEWaite
Copy link

@sahilm02 I added two more items for your consideration:

@jglick
Copy link
Member

jglick commented Apr 25, 2025

From a ten-second glance this looks like the wrong approach: you should rather implement StringCredentials and use the generic binding.

@MarkEWaite
Copy link

From a ten-second glance this looks like the wrong approach: you should rather implement StringCredentials and use the generic binding.

I'm not sure if I understood your comment correctly. I used StringBinding for the implementation and adjusted PersonalAccessToken to implement StringCredentials.

af1c198 is the change

@sahilm02
Copy link
Author

From a ten-second glance this looks like the wrong approach: you should rather implement StringCredentials and use the generic binding.

I'm not sure if I understood your comment correctly. I used StringBinding for the implementation and adjusted PersonalAccessToken to implement StringCredentials.

af1c198 is the change

@jglick Please let me know if this change looks good to you. If so, I will incorporate it into the PR.

@jglick
Copy link
Member

jglick commented Apr 29, 2025

If PersonalAccessTokenImpl implements StringCredentials then you should not need PersonalAccessTokenBinding at all. Just use the standard StringBinding.

withCredentials([string(credentialsId: 'happens-to-be-gitea', variable: 'GITEA_TOKEN')]) {…}

It is not really clear to my why PersonalAccessTokenImpl exists, either. It does not appear to have any special behavior beyond the standard StringCredentialsImpl other than warning you when the value is not 40 characters. In general, plugins should avoid defining new Credentials interfaces or implementations unless the generic ones fundamentally lack some required structure (typically multiple secret fields); for example, you prevent use of arbitrary CredentialsStore implementations, like https://plugins.jenkins.io/kubernetes-credentials-provider/ etc. or at least force them to add a special-case integration.

@MarkEWaite
Copy link

Thanks for the feedback @jglick . I've updated with two more commits, removing the binding class and updating the automated test. The changes are:

  • 6ae6216 - Document that 'Secret text' must be selected for Gitea tokens
  • ba4aa66 - Use StringCredentials

@MarkEWaite
Copy link

It is not really clear to my why PersonalAccessTokenImpl exists, either.

Since that class has existed since 2017, I left it alone. I didn't want to do the compatibility search to see if other plugins depend on it.

@MarkEWaite
Copy link

Another test case that I ran successfully, using a declarative Pipeline with the environment directive:

pipeline {
    environment {
        ABC = credentials('gitea-token')
    }
    agent {
        label '!cloud'
    }
    stages {
        stage('Checkout') {
            steps {
                cleanWs()
                script {
                    if (isUnix()) {
                        sh 'git clone https://[email protected]/user/repo.git'
                        sh 'ls'
                    } else {
                        bat 'git clone https://%ABC%@gitea.com/user/repo.git'
                        bat 'dir'
                    }
                }
            }
        }
    }
}

@lafriks
Copy link
Contributor

lafriks commented Nov 26, 2025

@MarkEWaite could you please create a new PR with your fixes?

@MarkEWaite
Copy link

MarkEWaite commented Nov 26, 2025

@MarkEWaite could you please create a new PR with your fixes?

I would much prefer that @sahilm02 receives credit for the work. @sahilm02 would you be willing to include the changes from my feature/withCredentials-support-using-StringCredentials branch?

If @sahilm02 does not respond within a week, I can rework my pull request to start with the original commits from @sahilm02 so that the commit history will correctly show the work of @sahilm02 . The current commits on my branch show me as the author of changes that were actually made by @sahilm02

@sahilm02
Copy link
Author

sahilm02 commented Dec 2, 2025

@MarkEWaite could you please create a new PR with your fixes?

I would much prefer that @sahilm02 receives credit for the work. @sahilm02 would you be willing to include the changes from my feature/withCredentials-support-using-StringCredentials branch?

If @sahilm02 does not respond within a week, I can rework my pull request to start with the original commits from @sahilm02 so that the commit history will correctly show the work of @sahilm02 . The current commits on my branch show me as the author of changes that were actually made by @sahilm02

I will incorporate your changes. Thanks

…rt-using-StringCredentials' into feature/withCredentials-support
…/gitea-plugin into feature/withCredentials-support
Copy link

@MarkEWaite MarkEWaite left a comment

Choose a reason for hiding this comment

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

3 files that need to be removed from the pull request and 1 optional change to a test.

Thanks very much @sahilm02

@@ -0,0 +1,58 @@
package org.jenkinsci.plugin.gitea.credentials;

Choose a reason for hiding this comment

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

This file can be deleted. As noted by Jesse Glick, it is not needed because the binding is using the StringCredentials class rather than implementing its own class

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>

Choose a reason for hiding this comment

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

This file can be deleted. As noted by Jesse Glick, it is not needed because the binding is using the StringCredential rather than implementing its own class

@@ -0,0 +1,24 @@
# The MIT License

Choose a reason for hiding this comment

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

This file can be deleted. As noted by Jesse Glick, it is not needed because the binding is using the StringCredential rather than implementing its own class

Run<?, ?> build = jenkins.buildAndAssertSuccess(project);
// Pipeline script outputs a substring of credential so that it will not be masked
jenkins.assertLogContains("Token1 is ecret", build);
jenkins.assertLogContains("Token2 is ecret", build);

Choose a reason for hiding this comment

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

This assertion was added to check that credential masking is working as expected on Windows and Unix. It is optional (no problem if you choose to not include it).

Suggested change
jenkins.assertLogContains("Token2 is ecret", build);
// Pipeline script shell and bat masks credential
jenkins.assertLogContains("API_TOKEN1 is ****", build);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants