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

5.0.0-beta.1 incompatible with lightweight checkout in Jenkins #112

Open
ajoberstar opened this issue Nov 18, 2024 · 9 comments
Open

5.0.0-beta.1 incompatible with lightweight checkout in Jenkins #112

ajoberstar opened this issue Nov 18, 2024 · 9 comments
Labels

Comments

@ajoberstar
Copy link
Owner

ajoberstar commented Nov 18, 2024

Originally posted by @ciscoo in #111 (comment)

Some early feedback from trying out 5.0.0-beta.1, it does not seem to work with the lightweight checkout in Jenkins. Previously it did without issue.

Disabling that and manually cloning the repo yields a different error:

hint: Using 'master' as the name for the initial branch. This default branch name
hint: is subject to change. To configure the initial branch name to use in all
hint: of your new repositories, which will suppress this warning, call:
hint: 
hint: 	git config --global init.defaultBranch <name>
hint: 
hint: Names commonly chosen instead of 'master' are 'main', 'trunk' and
hint: 'development'. The just-created branch can be renamed via this command:
hint: 
hint: 	git branch -m <name>
fatal: couldn't find remote ref refs/heads/gh-pages

Doing a git branch -a before ./gradlew gitPublishPush yields:

+ git branch -a
* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/gh-pages
  remotes/origin/master

So, to me there is some regression here I think since the previous implementation worked when using grgit/jgit.

@ajoberstar ajoberstar added the bug label Nov 18, 2024
@ajoberstar
Copy link
Owner Author

@ciscoo Can you provide more details about how Jenkins lightweight checkout works?

I'm presuming the failure you saw was during gitPublishReset? If so, the behavior here should help cross reference against what Jenkins is doing to figure out where the issue is.

https://github.com/ajoberstar/gradle-git-publish/blob/main/src/main/java/org/ajoberstar/gradle/git/publish/tasks/GitPublishReset.java#L65

@ciscoo
Copy link

ciscoo commented Nov 19, 2024

To my understanding, it doesn't checkout the full repo and it's history/branches. Instead, it checks out a specific commit (detached?) which is typically the one that triggered the build. I'm not an expert in this area, a different team manages our CI/CD infrastructure.

I've since modified my project's pipeline to do a full checkout as far as I can tell, but it stills fails.

Yes, it fails on gitPublishReset. I can provide some redacted logs as to what is happening when I get back into work.

@ciscoo
Copy link

ciscoo commented Nov 20, 2024

Here's some more details.

Prior to using the beta, my publishing configuration was:

gitPublish {
    repoUri = "https://github.acmecompany.com/example-org/example.git"
    branch = "gh-pages"

    contents {
        from(layout.buildDirectory.dir("docs"))
        into("docs")
    }

    preserve {
        include("**/*")
        exclude("docs/**")
    }
}

Documentation is built with Asciidoctor and versioned. This arrangement has worked fine for a while up until my company introduced Sedated a while ago. When I noticed the change to using the git CLI directly, I migrated quickly.

With the beta, I changed the configuration to the following (based on looking at the changes:

gitPublish {
    branch = "gh-pages"

    contents {
        from(layout.buildDirectory.dir("docs"))
        into("docs")
    }

    preserve {
        include("**/*")
        exclude("docs/**")
    }
}

With this configuration, the logs/commands from a failed run are:

2024-11-20 09:04:38.606  > Task :documentation:gitPublishReset FAILED
2024-11-20 09:04:38.606  Starting process 'command 'git''. Working directory: /opt/app/workspace/a-org-build_example_master Command: git remote get-url origin
2024-11-20 09:04:38.606  Successfully started process 'command 'git''
2024-11-20 09:04:38.606  Caching disabled for task ':documentation:gitPublishReset' because:
2024-11-20 09:04:38.606    Build cache is disabled
2024-11-20 09:04:38.606  Task ':documentation:gitPublishReset' is not up-to-date because:
2024-11-20 09:04:38.606    Task is untracked because: Git tracks the state
2024-11-20 09:04:38.606  Starting process 'command 'git''. Working directory: /opt/app/workspace/a-org-build_example_master/documentation/build/gitPublish/main Command: git init
2024-11-20 09:04:38.606  Successfully started process 'command 'git''
2024-11-20 09:04:38.606  hint: Using 'master' as the name for the initial branch. This default branch name
2024-11-20 09:04:38.606  hint: is subject to change. To configure the initial branch name to use in all
2024-11-20 09:04:38.606  hint: of your new repositories, which will suppress this warning, call:
2024-11-20 09:04:38.606  hint: 
2024-11-20 09:04:38.606  hint: 	git config --global init.defaultBranch <name>
2024-11-20 09:04:38.606  hint: 
2024-11-20 09:04:38.607  hint: Names commonly chosen instead of 'master' are 'main', 'trunk' and
2024-11-20 09:04:38.607  hint: 'development'. The just-created branch can be renamed via this command:
2024-11-20 09:04:38.607  hint: 
2024-11-20 09:04:38.607  hint: 	git branch -m <name>
2024-11-20 09:04:38.607  Starting process 'command 'git''. Working directory: /opt/app/workspace/a-org-build_example_master/documentation/build/gitPublish/main Command: git remote add origin https://x-access-token:****@github.example.com/example-org/example.git
2024-11-20 09:04:38.607  Successfully started process 'command 'git''
2024-11-20 09:04:38.607  Starting process 'command 'git''. Working directory: /opt/app/workspace/a-org-build_example_master Command: git rev-parse --absolute-git-dir
2024-11-20 09:04:38.607  Successfully started process 'command 'git''
2024-11-20 09:04:38.607  Starting process 'command 'git''. Working directory: /opt/app/workspace/a-org-build_example_master/documentation/build/gitPublish/main Command: git remote add reference /opt/app/workspace/a-org-build_example_master/.git
2024-11-20 09:04:38.607  Successfully started process 'command 'git''
2024-11-20 09:04:38.607  Starting process 'command 'git''. Working directory: /opt/app/workspace/a-org-build_example_master/documentation/build/gitPublish/main Command: git ls-remote --exit-code reference gh-pages
2024-11-20 09:04:38.607  Successfully started process 'command 'git''
2024-11-20 09:04:38.607  Starting process 'command 'git''. Working directory: /opt/app/workspace/a-org-build_example_master/documentation/build/gitPublish/main Command: git fetch reference +refs/heads/gh-pages:refs/remotes/reference/gh-pages
2024-11-20 09:04:38.607  Successfully started process 'command 'git''
2024-11-20 09:04:38.607  fatal: couldn't find remote ref refs/heads/gh-pages
2024-11-20 09:04:38.607  [Incubating] Problems report is available at: file:///opt/app/workspace/a-org-build_example_master/build/reports/problems/problems-report.html
2024-11-20 09:04:38.607  
2024-11-20 09:04:38.607  FAILURE: Build failed with an exception.
2024-11-20 09:04:38.607  
2024-11-20 09:04:38.607  * What went wrong:
2024-11-20 09:04:38.607  Execution failed for task ':documentation:gitPublishReset'.
2024-11-20 09:04:38.607  > Process 'command 'git'' finished with non-zero exit value 128
2024-11-20 09:04:38.607  
2024-11-20 09:04:38.607  * Try:
2024-11-20 09:04:38.607  > Run with --debug option to get more log output.
2024-11-20 09:04:38.607  > Run with --scan to get full insights.
2024-11-20 09:04:38.607  > Get more help at https://help.gradle.org.
2024-11-20 09:04:38.607  
2024-11-20 09:04:38.607  * Exception is:
2024-11-20 09:04:38.607  org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':documentation:gitPublishReset'.

One thing I noticed was the git init command being executed which it shouldn't since I now do a full checkout of the project and the .git folder should exist. The convention of repoDir isn't accurate, so modify the config to:

gitPublish {
    branch = "gh-pages"
+   repoDir = rootProject.layout.projectDirectory

    contents {
        from(layout.buildDirectory.dir("docs"))
        into("docs")
    }

    preserve {
        include("**/*")
        exclude("docs/**")
    }
}

Which fixes the unnecessary git init step but still yields the same error above:

2024-11-20 09:38:03.936  > Task :documentation:gitPublishReset FAILED
2024-11-20 09:38:03.936  Starting process 'command 'git''. Working directory: /opt/app/workspace/a-org-build_example_master Command: git remote get-url origin
2024-11-20 09:38:03.936  Successfully started process 'command 'git''
2024-11-20 09:38:03.936  Caching disabled for task ':documentation:gitPublishReset' because:
2024-11-20 09:38:03.936    Build cache is disabled
2024-11-20 09:38:03.936  Task ':documentation:gitPublishReset' is not up-to-date because:
2024-11-20 09:38:03.936    Task is untracked because: Git tracks the state
2024-11-20 09:38:03.936  Starting process 'command 'git''. Working directory: /opt/app/workspace/a-org-build_example_master Command: git remote add origin https://x-access-token:****@github.example.com/example-org/example.git
2024-11-20 09:38:03.936  Successfully started process 'command 'git''
2024-11-20 09:38:03.936  Starting process 'command 'git''. Working directory: /opt/app/workspace/a-org-build_example_master Command: git remote set-url origin https://x-access-token:****@github.example.com/example-org/example.git
2024-11-20 09:38:03.936  Successfully started process 'command 'git''
2024-11-20 09:38:03.936  Starting process 'command 'git''. Working directory: /opt/app/workspace/a-org-build_example_master Command: git rev-parse --absolute-git-dir
2024-11-20 09:38:03.936  Successfully started process 'command 'git''
2024-11-20 09:38:03.936  Starting process 'command 'git''. Working directory: /opt/app/workspace/a-org-build_example_master Command: git remote add reference /opt/app/workspace/a-org-build_example_master/.git
2024-11-20 09:38:03.936  Successfully started process 'command 'git''
2024-11-20 09:38:03.936  Starting process 'command 'git''. Working directory: /opt/app/workspace/a-org-build_example_master Command: git ls-remote --exit-code reference gh-pages
2024-11-20 09:38:03.936  Successfully started process 'command 'git''
2024-11-20 09:38:03.936  Starting process 'command 'git''. Working directory: /opt/app/workspace/a-org-build_example_master Command: git fetch reference +refs/heads/gh-pages:refs/remotes/reference/gh-pages
2024-11-20 09:38:03.936  Successfully started process 'command 'git''
2024-11-20 09:38:03.936  fatal: couldn't find remote ref refs/heads/gh-pages
2024-11-20 09:38:03.936  [Incubating] Problems report is available at: file:///opt/app/workspace/a-org-build_example_master/build/reports/problems/problems-report.html
2024-11-20 09:38:03.936  
2024-11-20 09:38:03.936  FAILURE: Build failed with an exception.
2024-11-20 09:38:03.936  
2024-11-20 09:38:03.936  * What went wrong:
2024-11-20 09:38:03.936  Execution failed for task ':documentation:gitPublishReset'.
2024-11-20 09:38:03.936  > Process 'command 'git'' finished with non-zero exit value 128
2024-11-20 09:38:03.936  
2024-11-20 09:38:03.936  * Try:
2024-11-20 09:38:03.936  > Run with --debug option to get more log output.
2024-11-20 09:38:03.936  > Run with --scan to get full insights.
2024-11-20 09:38:03.936  > Get more help at https://help.gradle.org.
2024-11-20 09:38:03.936  
2024-11-20 09:38:03.936  * Exception is:
2024-11-20 09:38:03.936  org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':documentation:gitPublishReset'.

If I do those commands manually, I get an error:

2024-11-20 15:43:10.860  + git remote get-url origin
2024-11-20 15:43:10.860  https://x-access-token:****@github.example.com/example-org/example.git
2024-11-20 15:43:11.128  + git remote add origin https://x-access-token:****@github.example.com/example-org/example.git
2024-11-20 15:43:11.128  error: remote origin already exists.

which makes sense, so removing some redundant portions yields the same error:

2024-11-20 15:46:48.022  + git remote get-url origin
2024-11-20 15:46:48.022  https://x-access-token:****@github.example.com/example-org/example.git
2024-11-20 15:46:48.288  + git rev-parse --absolute-git-dir
2024-11-20 15:46:48.288  /opt/app/workspace/a-org-build_example_master/.git
2024-11-20 15:46:48.557  + git remote add reference  /opt/app/workspace/a-org-build_example_master/.git
2024-11-20 15:46:48.824  + git ls-remote --exit-code reference gh-pages
2024-11-20 15:46:48.824  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx	refs/remotes/origin/gh-pages
2024-11-20 15:46:49.093  + git fetch reference +refs/heads/gh-pages:refs/remotes/reference/gh-pages
2024-11-20 15:46:49.093  fatal: couldn't find remote ref refs/heads/gh-pages

@ajoberstar
Copy link
Owner Author

If you use a full checkout with your old configuration, do you see errors still? Nothing should have changed in v5 that would affect how you configure the extension.

gitPublish {
    repoUri = "https://github.acmecompany.com/example-org/example.git"
    branch = "gh-pages"

    contents {
        from(layout.buildDirectory.dir("docs"))
        into("docs")
    }

    preserve {
        include("**/*")
        exclude("docs/**")
    }
}

Regarding the two changes you made when upgrading to the beta. There are three repositories in use when you use this plugin:

  • The remote repo you're pushing to. This is denoted by repoUri.
  • Your project's checkout repo, usually the .git/ sibling to your settings.gradle. This location is autodetected.
  • The working repo denoted by repoDir (defaults to build/gitPublish/main)

The repoUri is defaulted to the checkout repo's origin remote URL (if present). So it should be safe for you to remove repoUri.

However, the working repo's git init is intended even if you have a full checkout. It's a separate copy of the repository than your checkout repo, partially because there are some cases where you might publish to a different repo than your code is stored.

If the checkout repo's origin remote matches remote repo it will use the checkout repo as a reference, fetching from the checkout repo before fetching from the remote repo to reduce network traffic.

If you try to set the repoDir to the project root in order to reuse the checkout repo you run the risk of blowing away your whole project because repoDir is what's used as the destination of the copy step, beyond it also switching branches on you.

With grgit out of the picture, it probably opens up other optimization approaches that avoid a 3rd full repo. Maybe something with worktrees could be used instead. Or even just using shallow clones instead of full ones.

But those are just performance questions. Ultimately, I'd say there's nothing wrong with the original configuration you have. I definitely agree there's a bug in 5.0.0-beta.1, I just need to work out what's needed to account for the lightweight checkout.

If you still see an issue with your full checkout and the original gitPublish config, I'd suggest a new issue for that, as I think it would be unrelated.

ajoberstar added a commit that referenced this issue Nov 23, 2024
Old behavior was to use the reference repo (usually the project's
checkout repo) as a full remote that we would fetch from. However, Git
has a more direct way to reference an existing repo, using
`objects/info/alternates`. This mechanism will just let you reuse
objects that already exist in the reference repo rather than fetching
from the real remotes.

So now only origin is a remote and we just try to reuse objects from
the remote. This also simplifies things where we had to check if the
branch we cared about existed. Now, we don't care and if the objects
are relevant they get used and if not, it should be no harm, no foul.

This will hopefully address the issue that reported in #112.
ajoberstar added a commit that referenced this issue Nov 23, 2024
@ajoberstar
Copy link
Owner Author

@ciscoo 5.0.0-beta.2 is rolling out now with a different implementation of the "reference repo" mechanism which I hope will avoid any issues with a lightweight checkout. Can you try that and let me know if you still see an issue?

@ciscoo
Copy link

ciscoo commented Nov 26, 2024

It works again with a full checkout (git clone) with 5.0.0-beta.2.

Still does not seem to work for lightweight checkout. For more context, here's what Jenkins is doing:

The recommended git tool is: NONE
using credential example-org-ghapp
Cloning the remote Git repository
Avoid second fetch
Checking out Revision xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx (origin/master)
Commit message: "Back to declarative checkout"
Cloning repository https://github.acme.com/example-org/example-framework.git
 > git init /opt/jenkins/workspace/a-org-build_example-framework_master # timeout=10
Fetching upstream changes from https://github.acme.com/example-org/example-framework.git
 > git --version # timeout=10
 > git --version # 'git version 2.43.5'
using GIT_ASKPASS to set credentials example-org-ghapp
 > git fetch --tags --force --progress -- https://github.acme.com/example-org/example-framework.git +refs/heads/*:refs/remotes/origin/* # timeout=10
 > git config remote.origin.url https://github.acme.com/example-org/example-framework.git # timeout=10
 > git config --add remote.origin.fetch +refs/heads/*:refs/remotes/origin/* # timeout=10
 > git rev-parse origin/master^{commit} # timeout=10
 > git config core.sparsecheckout # timeout=10
 > git checkout -f xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # timeout=10

@ajoberstar
Copy link
Owner Author

That's useful context, though I'm surprised anything in there would cause an issue.

Could you provide fresh Gradle output with the error you're receiving on beta.2?

@ajoberstar
Copy link
Owner Author

FYI, I tried recreating this by setting up a repo using the commands from your Jenkins output. So far I wasn't able to cause an error. It's possible I'm missing something (particularly with the spare checkout piece that doesn't seem to do anything).

@ajoberstar
Copy link
Owner Author

I ended up making my own Jenkins install and trying this out on a random project. I did get an error with 5.0.0-beta.1, but 5.0.0-beta.2 worked. This was my test pipeline. Let me know if there's some difference in there that would explain why yours is still failing.

pipeline {
  agent any

  stages {
    stage('Publish Docs') {
      steps {
        checkout scm
        sh './gradlew gitPublishPush'
      }
    }
  }
}

I'm going to release 5.0.0 (unchanged from 5.0.0-beta.2). If you have more error output or context you can provide let me know.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants