Giter VIP home page Giter VIP logo

gocd-git-path-material-plugin's Introduction

gocd-git-path-material-plugin

Build Status GitHub All Releases License

GoCD plugin to introduce a material that watches on a sub-directory of a Git repository.

This is the missing GoCD support for mono-repos.

What you can do with this plugin

...that you can't do with the built-in Git material:

  • Support mono-repos without excessive triggering from a material that watches the entire repository
  • Implement side-channels into deployment pipelines for source-controlled environment configuration
  • Version control deployment configuration in the same repository as your code without rebuilding software every time unrelated configuration is changed; supporting twelve-factor apps
  • Fix fan-in - materials that monitor different paths in a repo are considered separate when evaluating fan-in conditions
  • Provide clean, filtered change logs for pipeline/VSM comparisons showing only changes on the monitored paths within a repository

This plugin is intended as

  • a drop-in replacement for the built-in GoCD Git material (see known issues for some caveats)
  • replaces the problematic use of whitelists and blacklists
    • whitelists and blacklists in GoCD tend to prevent/block fan-in because materials with different whitelists are still considered equivalent by the fan-in algorithm. This makes them unsuitable for use as environment side-channels or dealing with mono-repos.

Advanced features

Wildcard whitelists - When the Git command line is available on your agents; you can also use wildcards like config/*/prod.yaml. Anything that works with git log will work here. Shallow clones - supported in the same way as the GoCD Git Material supports them

TOC

Installation

Manually

  • Download from releases
  • Follow the installation instructions here

Dockerized GoCD automatic plugin install

  • Find release URL
  • Set environment variable like the below; replacing ${VERSION}
    GOCD_PLUGIN_INSTALL_gocd-git-path-material-plugin=https://github.com/TWChennai/gocd-git-path-material-plugin/releases/download/v${VERSION}/gocd-git-path-material-plugin-${VERSION}.jar
    

Requirements

Plugin Version Requirements Recommended
2.2+ GoCD >= 19.9
Server and agent running Java 11+
GoCD 20.9 for full functionality
git binary available on path
2.1 GoCD >= 18.10
Server and agent running Java 9+
At least GoCD 19.2, but >= 20.9 for full functionality
git binary available on path
1.x GoCD >= 15.1
Server and agent running Java 7+

Usage

Via pipelines-as-code

From GoCD 19.2.0 onwards you can use via pluggable material configuration with gocd-yaml-config-plugin

materials:
  path-filtered-material:
    plugin_configuration:
      id: git-path
    options:
      url: https://github.com/TWChennai/gocd-git-path-sample.git
      username: username # optional
      path: path1, path2/subpath
      shallow_clone: false # optional
    secure_options: # optional
      password: 'encrypted_value'
    destination: destDir

Via UI wizards

Available from GoCD 19.8.0 onwards.

gocd-git-path-material-create-pipeline-wizard

gocd-git-path-material-add-scm-1 gocd-git-path-material-add-scm-2

Via UI advanced configuration

Available on all compatible versions of GoCD.

gocd-git-path-material-plugin-add

gocd-git-path-material-plugin-popup

You can see a sample here.

Visualising changes

VSM view gocd-git-path-material-plugin-view-vsm

View changes grouped by material gocd-git-path-material-plugin-view-comparison

Constructing path expressions

This plugin relies on the underlying Git CLI to interpret path expressions. For that reason, you can construct almost any expression you could do with a git pathspec including

  • including certain paths
  • including only certain files deep inside a path structure
  • excluding certain paths or files (using :(exclude) or :! or :^)
  • using glob syntax (using :(glob))

Restrictions

  • cannot contain commas (used for splitting)
  • whitespace before and after splitting commas is ignored

You can normally test your expressions using something like the below to see the last revision that would have triggered a build

EXPR='path1, :(exclude)*README.md'
git log -1 $(echo "${EXPR}" | tr -d ',' )

For example, these are all valid expressions

# Monitor for changes in path1 and path2/subpath
path1, path2/subpath

# Monitor for changes in path1, but ignore README changes
path1, :(exclude)*README.md

# Monitor for changes to all config files for the qa environment, in any folder
config/*/qa.yaml

Migration from v1 to v2

v2 is a major overhaul of the plugin, and prefers the use of the git command line to the previously preferred jgit. This makes the plugin consistent with more recent GoCD server & agent Docker releases, and improves ability to support standard git features such as shallow and no-checkout clones and wildcard matches in paths.

As a result the plugin ID has changed between the two versions.

v1 plugin id v2+ plugin id
GitPathMaterial git-path
  • If you use the gocd-yaml-config-plugin to configure your pipelines as code; you can update the ID per the above example.
  • If you configure your pipelines via the UI, you will need to add new materials and remove the old ones one-by-one.

Frequently asked questions

Support for GoCD server secrets management interpolation in pipelines as code

Custom source control material plugins like the gocd-git-path-material-plugin only have support for GoCD secrets management and secret variable interpolation (syntax like {{SECRET:[file-secrets][test-password]}}) from GoCD 20.8.0 onwards (changelog).

On earlier versions if you use pipelines-as-code to source control your material definitions, you can however

  • use secure_options to source control an encrypted password (see gocd-yaml-config-plugin#pluggable)
  • use SSH keys within your GoCD server and agent to authenticate with a private repository
    • If running GoCD on Kubernetes, there is support for doing so based on Kubernetes Secrets within the GoCD Helm chart or any other solution that allows mounting of a file into a container.

Support for triggering from webhooks

Custom source control material plugins like the gocd-git-path-material-plugin have support for triggering from webhooks from GoCD 20.9.0 onwards (changelog). This contrasts with the convention material polling approach (see #27 and gocd/gocd#8170)

Stale data in agent repository clones

This plugin uses Git commands to filter the history and determine the most recent revision that matches the monitored paths. This means that changes that are not monitored in your paths may be "stale". The plugin does not rm un-monitored paths from a clone; meaning your build task could accidentally depend on files in the repository that are out-of-date.

Be careful with your repository structure to keep your monitored path expressions simple, so you can easily reason about whether a given pipeline should have been triggered for a given commit.

Creating new pipelines via UI on pre 19.8.0 GoCD versions

You will not be able to see the Git Path material as a material type when creating a new pipeline. Add a dummy git material, then edit to add a new Git Path material and remove the old one. This problem has been resolved in newer GoCD versions via the pipeline creation wizard.

Contributing

Build

execute the following command to build the plugin

./gradlew clean build

Run

You can quickly test the plugin using Docker Compose, via Docker Desktop, Colima or equivalent.

Execute the following gradle task to start the go-server

./gradlew clean startGoCd

You can now access the go-server via port 8153

reload

If you like to reload the go-server with new build run,

./gradlew clean restartGoCd

stop

You can stop the running docker instance with the following gradle task

./gradlew clean stopGoCd

Release

Released via the gocd-plugin-gradle-task-helpers onto GitHub.

  • Check thegocdPlugin.pluginVersion version in build.gradle and bump if necessary
    • The release helpers add a -${COMMIT_NUM} suffix to the version, so this is not strictly necessary for minor changes.
  • Tag and publish
    export GITHUB_TOKEN=blah
    PRERELEASE=no ./gradlew clean build githubRelease
  • Edit the release description on GitHub if necessary.

Acknowledgements

This plugin contains Git sub-process handling code originally written and released under Apache 2 licenses by

gocd-git-path-material-plugin's People

Contributors

arunvelsriram avatar chadlwilson avatar ckaushik avatar dependabot[bot] avatar gayan17 avatar gradle-update-robot avatar jskswamy avatar nithyanatarajan avatar selvakn avatar siliconsenthil avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

gocd-git-path-material-plugin's Issues

GOCD Pipeline stuck on past

I have GOCD 19.8.0 with GitPathMaterial Plugin 1.2.3. I cannot upgrade because all the pipeline must run with at MAX java 8.
I have multiple pipeline stuck to an older commit.

Based on log analysis, the flyweight-folder point to the same UUID path and the revision did not change.

There is a way to purge the latest-revision-since or clean up the history to make the pipelines start as a first time poll to git repository?

thanks

'Unable to de-serialize...' error when using the git path material plugin

My company has recently moved from svn to git for source control so I have a legacy application that consists of multiple projects which all reside in the same git repository (not ideal I know). Now I have been attempting to use the git path material plugin to setup CI for specific components, however I am getting the bellow error message and due to receiving this error go is repeatedly trying to download the code into the flyweight directory. Anyone else encountering this? Running 20.2.0 on Windows.

(changed the uri path slightly and * out the user id)
[132@MessageListener for MaterialUpdateListener] MaterialDatabaseUpdater:127 - [Material Update] Modification check failed for material: [url=https://gitlab.com/projects/myproject.git, username=*****, path=\server\services\Notification, branch=master]
java.lang.RuntimeException: Unable to de-serialize json response. SCM revision cannot be empty
at com.thoughtworks.go.plugin.access.scm.JsonMessageHandler1_0.toSCMRevision(JsonMessageHandler1_0.java:312)
at com.thoughtworks.go.plugin.access.scm.JsonMessageHandler1_0.responseMessageForLatestRevision(JsonMessageHandler1_0.java:156)
at com.thoughtworks.go.plugin.access.scm.SCMExtension$5.onSuccess(SCMExtension.java:117)
at com.thoughtworks.go.plugin.access.scm.SCMExtension$5.onSuccess(SCMExtension.java:109)
at com.thoughtworks.go.plugin.access.PluginRequestHelper.submitRequest(PluginRequestHelper.java:54)
at com.thoughtworks.go.plugin.access.scm.SCMExtension.getLatestRevision(SCMExtension.java:109)
at com.thoughtworks.go.server.service.materials.PluggableSCMMaterialPoller.latestModification(PluggableSCMMaterialPoller.java:60)
at com.thoughtworks.go.server.service.materials.PluggableSCMMaterialPoller.latestModification(PluggableSCMMaterialPoller.java:45)
at com.thoughtworks.go.server.service.MaterialService.latestModification(MaterialService.java:120)
at com.thoughtworks.go.server.materials.LegacyMaterialChecker.findLatestModification(LegacyMaterialChecker.java:50)
at com.thoughtworks.go.server.materials.ScmMaterialUpdater.insertLatestOrNewModifications(ScmMaterialUpdater.java:55)
at com.thoughtworks.go.server.materials.ScmMaterialUpdater.addNewMaterialWithModifications(ScmMaterialUpdater.java:70)
at com.thoughtworks.go.server.materials.PluggableSCMMaterialUpdater.addNewMaterialWithModifications(PluggableSCMMaterialUpdater.java:61)
at com.thoughtworks.go.server.materials.MaterialDatabaseUpdater.addNewMaterialWithModifications(MaterialDatabaseUpdater.java:178)
at com.thoughtworks.go.server.materials.MaterialDatabaseUpdater.initializeMaterialWithLatestRevision(MaterialDatabaseUpdater.java:136)
at com.thoughtworks.go.server.materials.MaterialDatabaseUpdater$1.doInTransaction(MaterialDatabaseUpdater.java:95)
at com.thoughtworks.go.server.transaction.TransactionCallback.doWithExceptionHandling(TransactionCallback.java:23)
at com.thoughtworks.go.server.transaction.TransactionTemplate.lambda$executeWithExceptionHandling$2(TransactionTemplate.java:43)
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:133)
at com.thoughtworks.go.server.transaction.TransactionTemplate.executeWithExceptionHandling(TransactionTemplate.java:40)
at com.thoughtworks.go.server.materials.MaterialDatabaseUpdater.updateMaterial(MaterialDatabaseUpdater.java:92)
at com.thoughtworks.go.server.materials.MaterialUpdateListener.onMessage(MaterialUpdateListener.java:64)
at com.thoughtworks.go.server.materials.MaterialUpdateListener.onMessage(MaterialUpdateListener.java:32)
at com.thoughtworks.go.server.messaging.activemq.JMSMessageListenerAdapter.runImpl(JMSMessageListenerAdapter.java:83)
at com.thoughtworks.go.server.messaging.activemq.JMSMessageListenerAdapter.run(JMSMessageListenerAdapter.java:63)
at java.base/java.lang.Thread.run(Unknown Source)

Let me take a step back on this and ask if anyone has an example of how to properly configure a git path material?

Using 20.2.0

Support for ignore list / blacklist

I've been trying to understand how to achieve ignoring certain paths. As of now, only Wildcard whitelists are supported according to the README. Is this the case, or am I missing something here?

Is the blacklist functionality planned for the future?

Does not support git ssh

This plugin is only working with https:// style git URLs, and fails to connect with git@ style repository URLs.

How to always checkout latest revision?

Hello, we have microservice monorepo and have noticed that plugin checks out latest git revision that only touched paths that plugin monitors. We have one material per service, and each material monitors on its service subpath. When some service is about to be built & deployed, plugin picks up latest commit that touched the service. This is problematic as we want build phase to always checkout latest revision from master instead, as there are indirect dependencies between microservices. Is there a way to enforce plugin to do this for build phase?

Probably not properly used git resource

Every time a pipeline fails with 17.3 windows 64bit agent we get this error:

11:16:28.120 [go] Job Started: 2017-04-17 11:16:28 UTC

11:16:28.120 [go] Start to prepare myPipe/5/Package/1/CreateNuget on MVDC [C:\GA]
11:16:28.214 Clean working directory is set to true. Unable to clean working directory for agent: C:\GA\pipelines\myPipe, with error: Unable to delete file: pipelines\myPipe\local\.git\objects\pack\pack-7424f80058b68300dfd2f2c7e2b67fad474b1e8f.pack
11:16:28.261 [go] Job completed myPipe/5/Package/1/CreateNuget on MVDC [C:\GA]

We have to manually restart the GoAgent. This happens only with this plugin.

Support for secrets plugin interpolation of git passwords

Hi,

When I set git password fetched using secrets (file-based-plugin), material fails.
I configured build stage of pipeline as pipeline-as-code as below

materials:
  git-myrepo:
        plugin_configuration:
          id: git-path
        options:
          url: https://github.com/myrepo.git
          branch: master
          username: user1
          path: src/**
          password: '{{SECRET:[github-credentials][password]}}'
          shallow_clone: true

Appreciate if you can reply to this.

Thanks
Rak

TFS Git support

Unable to connect to TFS Git repo:
Invalid URL format. Should match ^(?:git|ssh|https?|git@[\w-\.]+[\w]+\.[\w]+):(?:\/\/)?[\w\.@:\/~_-]+\.git(?:\/?|\#[\d\w\.\-_]+?)$
I think it's because URL format doesn't ends with "*.git"
Is it supported with this plugin?
Also need to authenticate with TFS token or domain user. Is it possible?

Add support for shallow clones

GoCD server allows use of shallow clones on its Git materials on agents which can massively improve clone performance on larger repositories.

Improve error reporting to server when git cmd-line errors occur on agents

Currently the integration with the git command line client doesn't have great error messages when the git command line exits for some reason when trying to clone/fetch/reset a target repo within an agent.

This is one distinct disadvantage of this plugin from the built-in Git material; it's a bit painful if the Git repo server is having issues; or when diagnosing credential errors (for example), that might only be present on agent instances, but not on the server (e.g connectivity issues; issues with git SSH credentials/keys).

The changes in #24 improved this a little bit by including the git command line run; however this could be improved further:

The plugin sent a response that could not be understood by Go. Plugin returned with code '500' and the following response: '"checkout failed due to [RuntimeException: Exception (Process exited with an error: 128 (Exit value: 128)) Occurred: [git, fetch, origin, --prune, --recurse-submodules=no] - /go/pipelines/my-pipeline/my-material], rootCause [ExecuteException: Process exited with an error: 128 (Exit value: 128)]"'

Exit code 128 just means "git did not exit cleanly".

This probably requires some changes upstream at git-cmd however the basic mechanisms to get this data are already there in terms of being able to collect the streams off stdout and stderr. Just need to find a more standard way to return this back as a nicer error message to the GoCD Server.

Workaround
Set GIT_TRACE=1 env var (and sometimes GIT_SSH=1...) on the agent... but this is very noisy.

Support for multiple paths?

I've tested out this plugin and it's working great, except my source repo is split up according to Pants preferred way. Meaning that my source code lives in src/<lang>/company/<project>/etc and tests in tests/<lang>/company/<project>/etc.

Does this plugin support multiple paths to be specified?
I tried looking through the source, but I couldn't figure it out through GitHub.
If it doesn't, I wouldn't mind having a stab at adding that feature, but I would love any pointers for how I should approach it. :)

Unable to create the pipeline using gitpath plugin git material name

step to reproducue :-

  1. name any material for git e.g. test1 and corresponding url.
  2. delete the pipeline.
  3. create the same name pipeline and use same material previously used.

Result :-
not able to save the add pipeline with this change giving below error :-

Cannot save SCM, found multiple SCMs called 'test1'. SCM names are case-insensitive and must be unique.

@nitink85

Slow polling

CONTEXT
I have two go-cd server installed in two different servers (GO1 in M1 and GO2 in M2) with gitpathmaterial installed manually and a git-server installed in another server (GIT in M3) under the same subnet of the M2.
Go-cd version is 19.8.0 and GitPathMaterial version is 1.2.3. I already know that is obsolete and we have planned to upgrade but actually we need to find a way to work out.

PROBLEM
The pipelines linked with gitpathmaterial in M1 don't start at the same time of the M2s. Reading the GitPathMaterial Log of M2 is constantly writing, as if it pings frequently. M1's Log instead it seems frozen but if I change some reference in material it write something, so it's working but it's not polling at the same way of M2s.
I found out that when I ping from M2 the git server the time response is below 1 ms (eg. time=0.478 ms). From M1, instead, the ping is time=19.7 ms. I don't know if it's related but there is a way to set a time of polling? or to force the polling so it starts immediatly the pipeline?

JGit runs in debug mode

Looks like jgit runs in debug mode and it spits out a lot of debug log statements, which are forwarded to go-server.out.log.

There is another issue in the go server [https://github.com/gocd/gocd/issues/2811] and the log file go-server.out.log is not rotated.

It results in the log file taking the entire disk space.

While the rotation issue shall be handled in the go server, there is no reason for the jgit and the plugin to run in debug mode.

Support pipeline parameters in material definitions

I'm trying to use pipeline parameters for defining the material with git path material plugin. Here's how my definition looks for a material:

my_pipeline:
  group: build
  parameters:
    git-url: [email protected]:test/test-gocd.git
    project-path: sub_pj1
 materials:
   dev-material:
     plugin_configuration:
       id: git-path
     options:
       url: "#{git-url}"
       path: "#{project-path}"
       branch: develop
     destination: my_project

I see a 128 error code when GoCD is trying to parse this pipeline config.

The default git material that gocd has allows this type of material declaration but not the git path material.
This is particularly useful for projects that have huge number of microservices in which we can use yaml aliases for the materials and just define the overriding parameters.

Git HTTPS Credentials exposed in error logs when server fails to fetch materials

We are using this plugin, in combination with the gocd-kubernetes-based-secrets-plugin to specify the username and password to access a Git material over HTTPS with authentication.

When the server fails to clone/ make a git request, the error message exposes the username and password combination, leaking git credentials in the process, e.g.:

Modification check failed for material: [url=https://gitlab-instance/project.git, username={{SECRET:[deploy-token][username]}}, password={{SECRET:[deploy-token][token]}}, branch=main] Affected pipelines are pipeline-A.
The plugin sent a response that could not be understood by Go. Plugin returned with code '500' and the following response: '"latest-revision failed due to [RuntimeException: Exception (Process exited with an error: 128 (Exit value: 128)) Occurred: [git, clone, --branch=main, --no-checkout, https://username:exposed-password@gitlab-instance/project.git, /go/pipelines/mypipeline/my-material] - null], rootCause [ExecuteException: Process exited with an error: 128 (Exit value: 128)]"'

to and from revision for material

Is it possible to get the to and from revisions for a material when using this plugin? When I take a look at the envvar's, I only see the revisions for the materials using the standard set up from gocd.

I'd like to see the triggering revisions if possible:

[go] setting environment variable 'GO_REVISION_mat_name' to value 'abc123'
[go] setting environment variable 'GO_TO_REVISION_mat_name' to value 'abc123'
[go] setting environment variable 'GO_FROM_REVISION_mat_name' to value '123abc'

Support for webhooks triggers of pipeline

gocd-server: 20.3.0
git-path-material-plugin: 2.1.0-78
webhook: bitbucket

Hi, I am struggling to get the pipeline to be triggered by webhook event, currently I have 2 repositories setup 1 setup using standard material and the second one is using the git-path-material-plugin to listen for a specific path change.

When pushing a change the 1st pipeline starts as expected but the 2nd one does not start regardless of what change I make in the path it is supposed to listen.

Add support for `--no-checkout` on server-side clones

GoCD Server's main git material does --no-checkout clones server side when clone repositories in order to watch them for updates on materials. This support would be useful to make the Git Path a drop-in replacement for the off-the-shelf Git material; since this is a more performant approach server-side when building changelogs and checking for versions.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.