java.lang.Object
io.github.intisy.gradle.github.impl.github.GitHub
All Implemented Interfaces:
Credentials, Publishing, Releases, Repositories

public class GitHub extends Object implements Credentials, Repositories, Releases, Publishing
GitHub helper class for managing GitHub repositories, releases, and assets. Provides methods for cloning, pulling, and fetching repository information.
  • Constructor Details

    • GitHub

      public GitHub(GitHubLogger logger, ResourceSettings resourcesExtension, GitHubConfig githubExtension)
      Constructs a new GitHub helper instance.
      Parameters:
      logger - the logger instance for debug and error messages
      resourcesExtension - the resources extension containing repository configuration
      githubExtension - the github extension containing access token configuration
  • Method Details

    • getApiKey

      public String getApiKey()
      Gets the GitHub token used for REST calls and HTTPS git operations, resolving it from the auth extension (or the deprecated accessToken fallback). Cached after the first resolution.
      Returns:
      the resolved token, or null if none is configured
    • getSshKey

      public String getSshKey()
      Gets the SSH private key contents used for git transport, resolving it from auth.sshKey (or the deprecated accessToken fallback when that holds an SSH key). Cached after the first resolution.
      Returns:
      the SSH private key contents, or null if none is configured
    • getResourceRepoName

      public String getResourceRepoName()
      Extracts the repository name from the configured repository URL.
      Returns:
      the repository name, or null if not configured
    • getResourceRepoOwner

      public String getResourceRepoOwner()
      Extracts the repository owner from the configured repository URL.
      Returns:
      the repository owner, or null if not configured; a root-level repo URL (host/repo, no distinct owner segment, the ordinary shape for a self-hosted git instance dedicated to one team) falls back to the URL's own redacted host rather than null, so a caller's fail-fast "is this configured" check does not reject a legitimately root-level URL
    • getCredentialsProvider

      public org.eclipse.jgit.transport.CredentialsProvider getCredentialsProvider(String repoOwner, String cloneUrl)
      Creates a credentials provider for Git operations, scoped to github.com only.
      Parameters:
      repoOwner - the repository owner for authentication
      cloneUrl - the clone URL this credentials provider is for; the configured GitHub token is offered only when this is a github.com URL, never to any other host
      Returns:
      the credentials provider, or null if SSH authentication is used, no token is configured, or cloneUrl does not target github.com
    • getRepositoryURL

      public String getRepositoryURL(String repoOwner, String repoName)
      Constructs the appropriate github.com Git repository URL based on authentication type.
      Parameters:
      repoOwner - the repository owner
      repoName - the repository name
      Returns:
      the Git repository URL (SSH or HTTPS), always on github.com
      Implementation Note:
      public so a caller resolving a GitHub clone URL for a host-agnostic consumer (such as GitHubSourceBuilds) can reuse this instance's SSH-vs-HTTPS decision instead of duplicating it.
    • cloneRepository

      public void cloneRepository(File path, String repoOwner, String repoName) throws org.eclipse.jgit.api.errors.GitAPIException
      Clones a GitHub repository to the specified path.
      Parameters:
      path - the directory to clone the repository into
      repoOwner - the repository owner
      repoName - the repository name
      Throws:
      org.eclipse.jgit.api.errors.GitAPIException - if the clone operation fails
    • cloneRepository

      public void cloneRepository(File path) throws org.eclipse.jgit.api.errors.GitAPIException
      Clones the configured resource repository to the specified path.
      Parameters:
      path - the directory to clone the repository into
      Throws:
      org.eclipse.jgit.api.errors.GitAPIException - if the clone operation fails
    • doesRepoExist

      public boolean doesRepoExist(File path)
      Checks if a Git repository exists at the specified path.
      Parameters:
      path - the directory to check
      Returns:
      true if a repository exists, false otherwise
    • isRepoUpToDate

      public boolean isRepoUpToDate(File path)
      Checks if the local repository is up-to-date with the remote.
      Parameters:
      path - the repository directory
      Returns:
      true if up-to-date, false otherwise
    • pullRepository

      public void pullRepository(File path, String branch) throws org.eclipse.jgit.api.errors.GitAPIException, IOException
      Pulls the latest changes from the remote repository.
      Parameters:
      path - the repository directory
      branch - the branch to pull, or null for the current branch
      Throws:
      org.eclipse.jgit.api.errors.GitAPIException - if the pull operation fails
      IOException - if an I/O error occurs
    • pullRepository

      public void pullRepository(File path) throws org.eclipse.jgit.api.errors.GitAPIException, IOException
      Pulls the latest changes from the current branch of the remote repository.
      Parameters:
      path - the repository directory
      Throws:
      org.eclipse.jgit.api.errors.GitAPIException - if the pull operation fails
      IOException - if an I/O error occurs
    • cloneOrPullRepository

      public void cloneOrPullRepository(File path, String repoOwner, String repoName, String branch) throws org.eclipse.jgit.api.errors.GitAPIException, IOException
      Clones a repository if it doesn't exist, otherwise pulls the latest changes.
      Parameters:
      path - the repository directory
      repoOwner - the repository owner
      repoName - the repository name
      branch - the branch to pull, or null for the current branch
      Throws:
      org.eclipse.jgit.api.errors.GitAPIException - if the clone or pull operation fails
      IOException - if an I/O error occurs
    • cloneOrPullFromUrl

      public void cloneOrPullFromUrl(File target, String cloneUrl, String authUsername, String branch) throws IOException
      Clones or pulls cloneUrl into target, using the given URL directly for a fresh clone instead of deriving one via getRepositoryURL(java.lang.String, java.lang.String), so any git host works. An existing checkout is updated through its own origin remote, which already points at cloneUrl from a previous clone, so the URL is not needed again there.
      Parameters:
      target - the repository directory
      cloneUrl - the exact URL to clone from on a fresh checkout
      authUsername - the username presented for HTTPS token auth on a fresh clone, and for fetch/pull when this instance's resourcesExtension.repoUrl does not resolve one
      branch - the branch to clone or pull, or null for the current/default branch
      Throws:
      IOException - if the clone, fetch, or checkout operation fails
    • cloneOrPullRepository

      public void cloneOrPullRepository(File path, String branch) throws org.eclipse.jgit.api.errors.GitAPIException, IOException
      Clones the configured resource repository if it doesn't exist, otherwise pulls the latest changes.
      Parameters:
      path - the repository directory
      branch - the branch to pull, or null for the current branch
      Throws:
      org.eclipse.jgit.api.errors.GitAPIException - if the clone or pull operation fails
      IOException - if an I/O error occurs
    • cloneOrPullRepository

      public void cloneOrPullRepository(File path) throws org.eclipse.jgit.api.errors.GitAPIException, IOException
      Clones the configured resource repository if it doesn't exist, otherwise pulls the latest changes from the current branch.
      Parameters:
      path - the repository directory
      Throws:
      org.eclipse.jgit.api.errors.GitAPIException - if the clone or pull operation fails
      IOException - if an I/O error occurs
    • fetchReleaseByTag

      public com.google.gson.JsonObject fetchReleaseByTag(String repoOwner, String repoName, String version)
      Attempts to fetch a GitHub release by tag, trying the given tag first and then a "v"-prefixed or "v"-stripped variant as a fallback.
      Parameters:
      repoOwner - the repository owner
      repoName - the repository name
      version - the release version tag as declared by the consumer
      Returns:
      the parsed release JSON object
      Throws:
      RuntimeException - if neither tag variant resolves to a release
    • selectJarAsset

      public com.google.gson.JsonObject selectJarAsset(com.google.gson.JsonArray assets, String repoName, String version)
      Selects the best JAR asset from a release using a prioritized matching strategy: (1) exact repoName.jar, (2) repoName-version.jar, (3) repoName-standalone.jar, (4) first .jar not ending in -sources.jar or -javadoc.jar.
      Parameters:
      assets - the release assets JSON array
      repoName - the repository name
      version - the release version tag
      Returns:
      the selected asset JSON object, or null if no suitable JAR found
    • getAsset

      public File getAsset(String repoOwner, String repoName, String version)
      Downloads and caches a release asset JAR file from a GitHub repository.
      Parameters:
      repoOwner - the repository owner
      repoName - the repository name
      version - the release version tag
      Returns:
      the downloaded JAR file
    • getAsset

      public File getAsset(String version)
      Downloads and caches a release asset JAR file from the configured resource repository.
      Parameters:
      version - the release version tag
      Returns:
      the downloaded JAR file
    • readGithubDependencies

      public List<String[]> readGithubDependencies(File jar)
      Reads the embedded github-dependencies metadata from a JAR file. The metadata is stored at META-INF/github-dependencies.json and contains a JSON array of objects with group, name, and version fields. This location is safe from obfuscation tools (ProGuard, R8, etc.) which only process class files.
      Parameters:
      jar - the JAR file to read metadata from
      Returns:
      a list of dependency entries as [group, name, version] arrays, empty if no metadata entry exists or if the entry is unreadable or malformed; the unreadable case logs a warning naming jar.
    • getAssetWithTransitives

      public void getAssetWithTransitives(String repoOwner, String repoName, String version, Set<String> resolved, List<File> collected)
      Downloads a release asset JAR and recursively resolves its transitive GitHub dependencies. Each dependency's JAR is inspected for embedded META-INF/github-dependencies.json metadata, and any listed dependencies are downloaded recursively. A resolved-set prevents cycles and duplicate downloads.
      Parameters:
      repoOwner - the repository owner
      repoName - the repository name
      version - the release version tag
      resolved - set of already-resolved dependency keys ("owner:name:version") for cycle detection
      collected - list that all resolved JAR files (including transitives) are added to
    • getAssetWithClassifier

      public File getAssetWithClassifier(String repoOwner, String repoName, String version, String classifier)
      Downloads and caches a classifier-specific JAR asset from a GitHub release.

      The expected asset name on the release is repoName-classifier.jar. The file is cached under the same owner directory as getAsset(java.lang.String, java.lang.String, java.lang.String).

      Parameters:
      repoOwner - the repository owner
      repoName - the repository name
      version - the release version tag
      classifier - the artifact classifier (e.g. "api", "fat")
      Returns:
      the downloaded JAR file, or null if no matching asset exists in the release
    • getAllModuleAssets

      public void getAllModuleAssets(String repoOwner, String repoName, String version, List<File> collected)
      Downloads every module asset from a multi-module release (all assets named repoName-<classifier>.jar, excluding -sources.jar/-javadoc.jar). Backs the reserved :all classifier so a consumer can pull the whole library without listing each module. Each jar is cached under the same owner directory as getAsset(java.lang.String, java.lang.String, java.lang.String).
      Parameters:
      repoOwner - the repository owner
      repoName - the repository name
      version - the release version tag
      collected - list that the downloaded module JAR files are added to
    • downloadAsset

      @Deprecated public void downloadAsset(File direction, Object asset, String repoOwner, String repoName)
      Deprecated.
      Use downloadAssetFromUrl instead
      Downloads a GitHub release asset to the specified file location.
      Parameters:
      direction - the destination file
      asset - the GitHub asset object (no longer supported)
      repoOwner - the repository owner
      repoName - the repository name
    • getLatestRelease

      public com.google.gson.JsonObject getLatestRelease(String repoOwner, String repoName)
      Fetches the latest release from a GitHub repository.
      Parameters:
      repoOwner - the repository owner
      repoName - the repository name
      Returns:
      JSON object representing the latest release, or null if no releases exist
    • getLatestRelease

      public com.google.gson.JsonObject getLatestRelease()
      Fetches the latest release from the configured resource repository.
      Returns:
      JSON object representing the latest release, or null if no releases exist
    • getLatestVersion

      public String getLatestVersion(String repoOwner, String repoName)
      Gets the latest version tag from a GitHub repository.
      Parameters:
      repoOwner - the repository owner
      repoName - the repository name
      Returns:
      the latest version tag, or null if no releases exist
    • getLatestVersion

      public String getLatestVersion()
      Gets the latest version tag from the configured resource repository.
      Returns:
      the latest version tag, or null if no releases exist
    • getRemoteOwnerAndRepo

      public String[] getRemoteOwnerAndRepo(File projectDir)
      Reads the git remote "origin" URL from the project directory and parses it into [owner, repo]. Supports both HTTPS and SSH remote URLs.
      Parameters:
      projectDir - the root directory of the Git repository
      Returns:
      a two-element array {owner, repo}
      Throws:
      RuntimeException - if no "origin" remote is configured or the URL cannot be parsed
    • createRelease

      public com.google.gson.JsonObject createRelease(String owner, String repo, String tagName, String releaseName)
      Creates a GitHub release for the given tag, reusing the existing release if the tag already exists.

      If a release for tagName already exists it is returned as-is so that additional assets can still be uploaded to it without failing the build.

      Parameters:
      owner - the repository owner
      repo - the repository name
      tagName - the git tag for the release (GitHub auto-creates a lightweight tag if absent)
      releaseName - the human-readable release title; if null, defaults to tagName
      Returns:
      the release JSON object (contains upload_url)
      Throws:
      RuntimeException - if auth fails or the API errors
    • uploadReleaseAsset

      public void uploadReleaseAsset(String uploadUrl, File file, String assetName) throws IOException
      Uploads a file as a release asset to GitHub.
      Parameters:
      uploadUrl - the upload_url from the release object (URI template stripped automatically)
      file - the file to upload
      assetName - the asset name as it will appear in the release
      Throws:
      IOException - if the upload fails
    • apiKey

      public String apiKey()
      Specified by:
      apiKey in interface Credentials
      Returns:
      the resolved API token, or null if none is configured.
    • sshKey

      public String sshKey()
      Specified by:
      sshKey in interface Credentials
      Returns:
      the resolved SSH private key contents, or null if none is configured.
    • cloneOrPull

      public void cloneOrPull(File target, String owner, String repo, String branch) throws IOException
      Description copied from interface: Repositories
      Clones owner/repo into target if no checkout exists there yet, otherwise pulls the latest changes for branch (or the current branch, if null).
      Specified by:
      cloneOrPull in interface Repositories
      Parameters:
      target - the local directory to clone into or pull within.
      owner - the GitHub account or organization that owns the repository.
      repo - the repository name, without the owner prefix.
      branch - the branch to clone or pull, or null for the current/default branch.
      Throws:
      IOException - if the clone or pull fails.
    • cloneOrPullFrom

      public void cloneOrPullFrom(File target, String cloneUrl, String branch) throws IOException
      Description copied from interface: Repositories
      Clones or pulls cloneUrl into target, using the given URL directly rather than reconstructing one from an owner and repo, so any git host is honoured exactly as configured (github.com, GitHub Enterprise, or any other host).
      Specified by:
      cloneOrPullFrom in interface Repositories
      Parameters:
      target - the local directory to clone into or pull within.
      cloneUrl - the exact URL to clone from.
      branch - the branch to clone or pull, or null for the current/default branch.
      Throws:
      IOException - if the clone or pull fails.
    • exists

      public boolean exists(File path)
      Specified by:
      exists in interface Repositories
      Parameters:
      path - the directory to check.
      Returns:
      true if a git repository checkout exists at path.
    • isUpToDate

      public boolean isUpToDate(File path)
      Specified by:
      isUpToDate in interface Repositories
      Parameters:
      path - the checkout to check, whose own origin remote identifies the repository.
      Returns:
      true if path's current branch matches its remote counterpart, false if it is behind or the check itself fails (e.g. no network access).
    • remoteOf

      public RemoteRepo remoteOf(File projectDir)
      Specified by:
      remoteOf in interface Repositories
      Parameters:
      projectDir - the checkout whose origin remote is parsed.
      Returns:
      the owner and repository name parsed from projectDir's origin remote URL.
    • configuredRepo

      public RemoteRepo configuredRepo()
      Description copied from interface: Repositories
      The owner and repository parsed from the implementation's own configured repository URL.
      Specified by:
      configuredRepo in interface Repositories
      Returns:
      the configured owner and repo, or a RemoteRepo with null fields if none is configured.
    • latestVersion

      public String latestVersion(String owner, String repo)
      Specified by:
      latestVersion in interface Releases
      Parameters:
      owner - the GitHub account or organization that owns the repository.
      repo - the repository name, without the owner prefix.
      Returns:
      the latest release's tag, or null if the repository has no releases.
    • releaseByTag

      public Release releaseByTag(String owner, String repo, String tag)
      Specified by:
      releaseByTag in interface Releases
      Parameters:
      owner - the GitHub account or organization that owns the repository.
      repo - the repository name, without the owner prefix.
      tag - the release tag to resolve (a "v" prefix is tried both with and without).
      Returns:
      the release identified by tag.
    • latestRelease

      public Release latestRelease(String owner, String repo)
      Specified by:
      latestRelease in interface Releases
      Parameters:
      owner - the GitHub account or organization that owns the repository.
      repo - the repository name, without the owner prefix.
      Returns:
      the latest release, or null if the repository has no releases.
    • downloadJar

      public Optional<File> downloadJar(String owner, String repo, String version)
      Description copied from interface: Releases
      Downloads the default release jar, matching repo.jar, repo-version.jar, repo-standalone.jar, or the first plain .jar asset in that order.
      Specified by:
      downloadJar in interface Releases
      Parameters:
      owner - the GitHub account or organization that owns the repository.
      repo - the repository name, without the owner prefix.
      version - the release tag to resolve (a "v" prefix is tried both with and without).
      Returns:
      the downloaded (or cached) jar file, or an empty Optional if the release exists but has no matching jar asset. A release that does not exist at all is a different kind of absence and is never represented this way (see @throws below): the two are not the same thing, since a missing release is almost always a caller mistake (a typo'd version, a deleted or renamed tag) while a missing asset within a release that does exist is a normal outcome.
    • downloadJar

      public Optional<File> downloadJar(String owner, String repo, String version, String classifier)
      Description copied from interface: Releases
      Downloads a specific classifier asset, matching repo-classifier.jar exactly.
      Specified by:
      downloadJar in interface Releases
      Parameters:
      owner - the GitHub account or organization that owns the repository.
      repo - the repository name, without the owner prefix.
      version - the release tag to resolve (a "v" prefix is tried both with and without).
      classifier - the artifact classifier identifying the asset (e.g. "api").
      Returns:
      the classifier asset's jar, or an empty Optional if the release exists but has no asset named repo-classifier.jar. As with the 3-argument overload above, a release that does not exist at all is a different kind of absence and is never represented this way.
    • downloadAllModuleJars

      public List<File> downloadAllModuleJars(String owner, String repo, String version)
      Description copied from interface: Releases
      Downloads every module asset published under the reserved :all classifier, so a consumer of a multi-module release can pull every module jar without naming each one.
      Specified by:
      downloadAllModuleJars in interface Releases
      Parameters:
      owner - the GitHub account or organization that owns the repository.
      repo - the repository name, without the owner prefix.
      version - the release tag to resolve (a "v" prefix is tried both with and without).
      Returns:
      the downloaded module jars; never null or empty (a release with no module assets throws).
    • resolveWithDependencies

      public List<File> resolveWithDependencies(String owner, String repo, String version)
      Description copied from interface: Releases
      Resolves owner:repo:version and its full transitive closure of GitHub-hosted dependencies declared via each jar's embedded META-INF/github-dependencies.json, including the root jar itself.

      Cycle detection is local to a single call. A caller resolving many independent coordinates that may share transitive dependencies (for example, one call per declared dependency across several build configurations) must deduplicate the combined results itself if it wants each distinct jar added only once.

      Specified by:
      resolveWithDependencies in interface Releases
      Parameters:
      owner - the GitHub account or organization that owns the root repository.
      repo - the root repository name, without the owner prefix.
      version - the release tag to resolve (a "v" prefix is tried both with and without).
      Returns:
      the root jar followed by every transitively resolved jar, each appearing once.
    • declaredDependencies

      public List<DeclaredDependency> declaredDependencies(File jar)
      Specified by:
      declaredDependencies in interface Releases
      Parameters:
      jar - the jar file to inspect; not modified.
      Returns:
      the dependencies declared by jar's embedded META-INF/github-dependencies.json, or an empty list if the jar has no such entry, or if the entry exists but is unreadable or malformed. The unreadable case logs a warning naming jar so a corrupt artifact is not silently treated as having no dependencies.
    • ensureRelease

      public Release ensureRelease(String owner, String repo, String tag, String name)
      Description copied from interface: Publishing
      Creates a release for tag, or returns the existing release if one already exists for that tag.
      Specified by:
      ensureRelease in interface Publishing
      Parameters:
      owner - the GitHub account or organization that owns the repository.
      repo - the repository name, without the owner prefix.
      tag - the git tag for the release (GitHub auto-creates a lightweight tag if absent).
      name - the human-readable release title; if null, defaults to tag.
      Returns:
      the created or pre-existing release, including its asset upload URL.
    • uploadAsset

      public void uploadAsset(Release release, File file, String assetName) throws IOException
      Description copied from interface: Publishing
      Uploads a file as an asset attached to release.
      Specified by:
      uploadAsset in interface Publishing
      Parameters:
      release - the release to attach the asset to, as returned by Publishing.ensureRelease(java.lang.String, java.lang.String, java.lang.String, java.lang.String).
      file - the file to upload.
      assetName - the asset name as it will appear in the release.
      Throws:
      IOException - if the upload request fails.