{"id":19227407,"url":"https://github.com/spinnaker/igor","last_synced_at":"2025-05-14T18:05:30.423Z","repository":{"id":21537449,"uuid":"24856964","full_name":"spinnaker/igor","owner":"spinnaker","description":"Integration with Jenkins and Git for Spinnaker","archived":false,"fork":false,"pushed_at":"2025-05-12T16:28:13.000Z","size":3034,"stargazers_count":147,"open_issues_count":12,"forks_count":661,"subscribers_count":68,"default_branch":"master","last_synced_at":"2025-05-12T17:41:15.671Z","etag":null,"topics":["hacktoberfest"],"latest_commit_sha":null,"homepage":"","language":"Groovy","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"hilongjw/vue-recyclerview","license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/spinnaker.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":"AUTHORS","dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2014-10-06T17:49:51.000Z","updated_at":"2025-04-28T13:01:14.000Z","dependencies_parsed_at":"2023-01-14T13:10:55.997Z","dependency_job_id":"9b602daf-b0f4-415f-8e34-0514691305ed","html_url":"https://github.com/spinnaker/igor","commit_stats":{"total_commits":1241,"total_committers":110,"mean_commits":"11.281818181818181","dds":0.6067687348912167,"last_synced_commit":"6a9012807cce0aa932375df863401a1fae0756d5"},"previous_names":[],"tags_count":402,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spinnaker%2Figor","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spinnaker%2Figor/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spinnaker%2Figor/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spinnaker%2Figor/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/spinnaker","download_url":"https://codeload.github.com/spinnaker/igor/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254198514,"owners_count":22030965,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["hacktoberfest"],"created_at":"2024-11-09T15:23:08.908Z","updated_at":"2025-05-14T18:05:25.414Z","avatar_url":"https://github.com/spinnaker.png","language":"Groovy","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Build Status](https://api.travis-ci.org/spinnaker/igor.svg?branch=master)](https://travis-ci.org/spinnaker/igor)\n\n[![](https://github.com/spinnaker/igor/workflows/Igor%20CI/badge.svg)](https://github.com/spinnaker/igor/actions?query=workflow%3A%22Igor+CI%22+branch%3Amaster)\n\nIgor is a service that provides a single point of integration with Continuous Integration (CI) and Source Control Management (SCM) services for Spinnaker.\n\n# Common Polling Architecture\n\nIgor runs a number of pollers that all share the same common architecture. At a high level, they all:\n\n- periodically get a list of items from an external resource (e.g. builds on a Jenkins master)\n- compare that list against their own persisted cache of items (the difference is called _delta size_)\n- send an echo event for each new item\n- cache the new list of items\n\nFeatures:\n\n- *health*: igor has a `HealthIndicator` that reports `Down` if no pollers are running or if they have not had a successful polling cycle in a long time\n- *locking*: pollers can optionally acquire a distributed lock in the storage system before attempting to complete a polling cycle. This makes it possible to run igor in a high-availability configuration and scale it horizontally.\n- *safeguards*: abnormally large delta sizes can indicate a problem (e.g. lost or corrupt cache data) and cause downstream issues. If a polling cycle results in a delta size above the threshold, the new items will not be cached and events will not be submitted to echo to prevent a trigger storm. Manual action will be needed to resolve this, such as using the fast-forward admin endpoint: `/admin/pollers/fastforward/{monitorName}[?partition={partition}]`. Fast-forwarding means that all pending cache state will be polled and saved, but will not send echo notifications.\n\nRelevant properties:\n\n| *Property* | *Default value* | *Description* |\n| --- | --- | --- |\n| `spinnaker.build.pollingEnabled` | true | Defines whether or not the build system polling mechanism is enabled. Disabling this will effectively disable any integration with a build system that depends on Igor polling it. |\n| `spinnaker.build.pollInterval` | `60` | Interval in seconds between polling cycles |\n| `spinnaker.pollingSafeguard.itemUpperThreshold` | `1000` | Defines the upper threshold for number of new items before a cache update cycle will be rejected |\n| `locking.enabled` | `false` | Enables distributed locking so that igor can run on multiple nodes without interference |\n\nRelevant metrics:\n\n| *Metric* | *Type* | *Description* |\n| --- | --- | --- |\n| `pollingMonitor.newItems` | gauge | represents the number of new items cached by a given monitor during a polling cycle |\n| `pollingMonitor.itemsOverThreshold` | gauge | 0 if deltaSize \u003c threshold, deltaSize otherwise |\n| `pollingMonitor.pollTiming` | timer | published for every polling cycle with the duration it took to complete |\n| `pollingMonitor.failed` | counter | an error counter indicating a failed polling cycle |\n\nAll these metrics can be grouped by a `monitor` tag (e.g. `DockerMonitor`, `JenkinsMonitor`...) to track down issues.\n\n\n# Storage\n\nThe following storage backends are supported:\n\n- Redis\n\nRelevant properties:\n```\nredis:\n  enabled: true\n  connection: redis://host:port\n```\n\n\n# Integration with SCM services\n\nThe following SCM services are supported:\n\n- Bitbucket\n- Github\n- Gitlab\n- Stash\n\n`Commit` controller classes expose APIs to retrieve lists of commits, such as `/github/{{projectKey}}/{{repositorySlug}}/compareCommits?from={{fromHash}}\u0026to={{toHash}}`\n\nAt the moment, igor only exposes read APIs, there are no pollers and no triggers involving SCM services directly.\n\nRelevant properties:\n\n```\ngithub:\n  baseUrl: \"https://api.github.com\"\n  accessToken: '\u003cyour github token\u003e'\n  commitDisplayLength: 8\n\nstash:\n  baseUrl: \"\u003cstash url\u003e\"\n  username: '\u003cstash username\u003e'\n  password: '\u003cstash password\u003e'\n\nbitbucket:\n  baseUrl: \"https://api.bitbucket.org\"\n  username: '\u003cbitbucket username\u003e'\n  password: '\u003cbitbucket password\u003e'\n  commitDisplayLength: 7\n\ngitlab:\n  baseUrl: \"https://gitlab.com\"\n  privateToken: '\u003cyour gitlab token\u003e'\n  commitDisplayLength: 8\n```\n\n# Integration with CI services\n\nThe following CI services are supported:\n\n- Artifactory\n- Nexus\n- Concourse\n- Gitlab CI\n- Google Cloud Build (GCB)\n- Jenkins\n- Travis\n- Wercker\n\nFor each of these services, a poller can be enabled (e.g. with `jenkins.enabled`) that will start monitoring new builds/pipelines/artifacts, caching them and submitting events to echo, thus supporting pipeline triggers. GCB is a bit different in that it doesn't poll and requires setting up [pubsub subscriptions](https://www.spinnaker.io/setup/ci/gcb/).\n\nThe `BuildController` class also exposes APIs for services that support them such as:\n\n- getting build status\n- listing builds/jobs on a master\n- listing queued builds\n- starting and stopping builds/jobs\n\nThese APIs are used to provide artifact information for bake stages.\n\n\n## Configuring Jenkins Masters\n\nIn your configuration block (either in igor.yml, igor-local.yml, spinnaker.yml or spinnaker-local.yml), you can define multiple masters blocks by using the list format.\n\nYou can obtain a Jenkins API token by navigating to `http://your.jenkins.server/me/configure` (where `me` is your username).\n\n```\njenkins:\n  enabled: true\n  masters:\n    -\n      address: \"https://spinnaker.cloudbees.com/\"\n      name: cloudbees\n      password: f5e182594586b86687319aa5780ebcc5\n      username: spinnakeruser\n    -\n      address: \"http://hostedjenkins.amazon.com\"\n      name: bluespar\n      password: de4f277c81fb2b7033065509ddf31cd3\n      username: spindoctor\n```\n\n\n## Configuring Travis Masters\n\nIn your configuration block (either in igor.yml, igor-local.yml, spinnaker.yml or spinnaker-local.yml), you can define multiple masters blocks by using the list format.\n\nTo authenticate with Travis you use a \"Personal access token\" on a git user with permissions `read:org, repo, user`. This is added in `settings -\u003e Personal access tokens` on github/github-enterprise.\n\n```\ntravis:\n  enabled: true\n  # Travis names are prefixed with travis- inside igor.\n  masters:\n  - name: ci # This will show as travis-ci inside spinnaker.\n    baseUrl: https://travis-ci.com\n    address: https://api.travis-ci.com\n    githubToken: 6a7729bdba8c4f9abc58b175213d83f072d1d832\n  regexes:\n  - /Upload https?:\\/\\/.+\\/(.+\\.(deb|rpm))/\n```\n\nWhen parsing artifact information from Travis builds, igor uses a default regex\nthat will match on output from the `jfrog rt`/`art` CLI tool.  Different regexes than the\ndefault may be configured using the `regexes` list.\n\n\n## Configuring Gitlab CI Masters\n\nIn your configuration block (either in igor.yml, igor-local.yml, spinnaker.yml or spinnaker-local.yml), you can define multiple masters blocks by using the list format.\n\nTo authenticate with Gitlab CI use a [Personal Access Token](https://docs.gitlab.com/ee/security/token_overview.html#personal-access-tokens) with permissions `read_api`.\n\n```\ngitlab-ci:\n  enabled: true\n  itemUpperThreshold: 1000 # Optional, default 1000.  Determines max new pipeline count before a cache cycle is rejected\n  masters:\n    - address: \"https://git.mycompany.com\"\n      name: mygitlab\n      privateToken: kjsdf023ofku209823\n      # Optional:\n      defaultHttpPageLength: 100 # defaults 100, page length when querying paginated Gitlab API endpoints (100 is max per Gitlab docs)\n      limitByOwnership: false # defaults false, limits API results to projects/groups owned by the token creator\n      limitByMembership: true # defaults true, limits API results to projects/groups the token creator is a member in\n      httpRetryMaxAttempts: 5 # defaults 5, # default max number of retries when hitting Gitlab APIs and errors occur\n      httpRetryWaitSeconds: 2 # defaults 2, # of seconds to wait between retries\n      httpRetryExponentialBackoff: false # deafults false, if true retries to Gitlab will increase exponentially using the httpRetryWaitSeconds option's value\n```\n\nBuild properties are automatically read from successful Gitlab CI Pipelines using the pattern `SPINNAKER_PROPERTY_*=value`.  For example a log containing a line\n`SPINNAKER_PROPERTY_HELLO=world` will create a build property item `hello=world`.  Gitlab CI artifacts are not yet supported.\n\n\n## Integration with Docker Registry\n\nClouddriver can be [configured to poll your registries](http://www.spinnaker.io/v1.0/docs/target-deployment-configuration#section-docker-registry). When that is the case, igor can then create a poller that will list the registries indexed by clouddriver, check each one for new images and submit events to echo (hence allowing Docker triggers)\n\nRelevant properties:\n\n- `dockerRegistry.enabled`\n- requires `services.clouddriver.baseUrl` to be configured\n\n\n# Running igor\n\nIgor requires redis server to be up and running.\n\nStart igor via `./gradlew bootRun`. Or by following the instructions using the [Spinnaker installation scripts](https://www.github.com/spinnaker/spinnaker).\n\n\n## Debugging\n\nTo start the JVM in debug mode, set the Java system property `DEBUG=true`:\n```\n./gradlew -DDEBUG=true\n```\n\nThe JVM will then listen for a debugger to be attached on port 8188.  The JVM will _not_ wait for the debugger to be attached before starting igor; the relevant JVM arguments can be seen and modified as needed in `build.gradle`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fspinnaker%2Figor","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fspinnaker%2Figor","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fspinnaker%2Figor/lists"}