Tags: Git
You might have a successfully executing build task in Jenkins, then suddenly need that build task to push to a Github repository. For example, it might render a statically generated website to push to the gh-pages branch for display using Github Pages. But this inscrutable error message comes up. There is a fairly simple fix, especially if you're using an HTTPS URL to access the Github repository.
In your normal user environment on your laptop you're probably using an SSH URL (git@github.com:{USER}/{REPO}.git
) to access your repository. But on Jenkins, you're probably using an HTTPS URL instead (https://github.com/{USER}/{REPO}.git
). This URL works great to clone the repository into a Jenkins workspace and perform a build. But as soon as that job needs to push to a Github repository that URL will not work because the HTTPS URL does not have authentication.
On your normal user environment you might dimly remember how you set up remote Github access. That involves uploading an SSH public key into the Github back-end for every account you have. You might try the same in the Jenkins environment, but that then relies on using the git@github.com:{USER}/{REPO}.git
URL which might not work correctly in Jenkins. (I did not test that)
One option is to initialize a Git Credentials Store using a process like this:
$ git config credential.helper store
$ git push http://example.com/repo.git
Username: <type your username>
Password: <type your password>
[several days later]
$ git push http://example.com/repo.git
[your credentials are used automatically]
This stores the user name and password into ~/.git-credentials
and is supposed to let you push to an HTTPS Git URL without entering a password. In my case this did not solve the issue.
What worked for me was creating a Github Personal Access Token and using an HTTPS URL that looks like this: https://{TOKEN}@github.com/{USER}/{REPO}.git
The personal access token is what it sounds like, an encoded string that identifies you to Github. It should be treated carefully, like a password, since that's what it is. In my case I'm the only person using my Jenkins installation, so I simply entered the URL as shown above into Jenkins. If this were a multi-person Jenkins installation there might be a different best practice.
Github has instructions for setting up the personal access token. One goes to the Settings area, clicks on Developer Settings, and on the following page clicks on Personal Access Tokens. That page has some description, then a button labeled Generate New Token.
While generating the token you're given a long list of checkboxes. These determine the permissions levels associated with the token. In my case I simply clicked on the repo choice to give this token full permissions over repositories. The other permissions didn't seem appropriate. At the bottom is a button, Generate Token, that takes you to the access tokens dashboard, at which point you can copy the encoded string to the dashboard.
In Jenkins, go to the dashboard for one of your projects and click on the Configure button. In my project, I have the Github URL in two locations -- I checked the Github project choice, and entered the URL there -- and under Source Code Management I selected Git and entered the URL there.
The URL to enter has this format: https://{TOKEN}@github.com/{USER}/{REPO}.git
Later in the Jenkins job, I'm having it poll the source repository every 30 minutes.
Finally, in the build section, I added the command that causes a push to the Github repository. Prior to setting up this personal access token, that command failed, but after adding the token to the Github HTTPS URL, the command works.