Cogito (COncourse GIT status resOurce) is a Concourse resource to update the GitHub commit status during a build. The name is a humble homage to René Descartes.
It can also send a message to a chat system (currently supported: Google Chat). This allows to reduce the verbosity of a Concourse pipeline and especially to reduce the number of resource containers in a Concourse deployment, thus reducing load. Chat and GitHub commit status update can be used independently (see examples below).
Written in Go, it has the following characteristics:
main or that branch main even exists).This document explains how to use this resource. See CONTRIBUTING for how to build the Docker image, develop, test and contribute to this resource.
Please, before opening a PR, open a ticket to discuss your use case. This allows to better understand the why of a new feature and not to waste your time (and ours) developing a feature that for some reason doesn't fit well with the spirit of the project or could be implemented differently. This is in the spirit of Talk, then code.
We care about code quality, readability and tests, so please follow the current style and provide adequate test coverage. In case of doubts about how to tackle testing something, feel free to ask.
This project follows Semantic Versioning and has a CHANGELOG.
NOTE Following semver, no backwards compatibility is guaranteed as long as the major version is 0.
Releases are tagged in the git repository with the semver format vMAJOR.MINOR.PATCH (note the v prefix). The corresponding Docker image has tag MAJOR.MINOR.PATCH and is available from DockerHub.
latest tag always points to the latest release, not to the tip of master, so it is quite stable.MAJOR.MINOR.PATCH.See also pipelines/cogito.yml for a bigger example and for how to use YAML anchors to reduce as much as possible YAML verbosity.
resource_types:
- name: cogito
type: registry-image
check_every: 24h
source:
repository: pix4d/cogito
resources:
- name: gh-status
type: cogito
check_every: never
source:
owner: ((github-owner))
repo: ((your-repo-name))
access_token: ((github-PAT))
- name: the-repo
type: git
source:
uri: https://github.com/((github-owner))/((your-repo-name))
branch: ((branch))
jobs:
- name: autocat
on_success:
put: gh-status
inputs: [the-repo]
params: {state: success}
on_failure:
put: gh-status
inputs: [the-repo]
params: {state: failure}
on_error:
put: gh-status
inputs: [the-repo]
params: {state: error}
on_abort:
put: gh-status
inputs: [repo.git]
params: {state: abort}
plan:
- get: the-repo
trigger: true
- put: gh-status
inputs: [the-repo]
params: {state: pending}
- task: maybe-fail
config:
platform: linux
image_resource:
type: registry-image
source: { repository: alpine }
run:
path: /bin/sh
args:
- -c
- |
set -o errexit
echo "Hello world!"
The absolute minimum is adding key gchat_webhook to the source configuration of the previous example:
- name: gh-status
type: cogito
check_every: never
source:
owner: ((github-owner))
repo: ((your-repo-name))
access_token: ((github-PAT))
gchat_webhook: ((gchat_webhook))
The absolute minimum is setting keys gchat_webhook and sinks in the source configuration:
- name: chat-notify
type: cogito
check_every: never
source:
sinks:
- gchat
gchat_webhook: ((gchat_webhook))
There is only a partial matching between Concourse and GitHub Commit status API, so we map as good as we can according to this table:
| Concourse
State | Color and meaning | GitHub
Commit status API | Chat notification | |----------------------|-----------------------------------------------------------------------------------------------------------|-------------------------------|-------------------| | running | 🟡 - running | pending | pending | | success | 🟢 - task exited 0 | success | success | | failure | 🔴 - task exited non 0 | failure | failure | | error | 🟠 - any other error besides failure or abort (pipeline configuration error, network error, timeout, ...) | error | error | | abort | 🟤 - human-initiated abort | error | abort |
The colors are taken from the Concourse UI and are replicated to the chat message.
With reference to the [GitHub Commit status API], the POST parameters (state, target_url, description, context) are set by Cogito and rendered by GitHub as follows:


The logs for the put step contain a line of key/value pairs like this:
level=INF msg=posted-to-chat ... space=https://chat.google.com/u/0/app/chat/AAA...
You can copy the value of the space key and paste it in your browser.
owner\
The GitHub user or organization.
repo\
The GitHub repository name.
Keys must be provided for one of the following authentication methods: 1. Personal Access Token 2. GitHub app
access_token\
The OAuth access token.\
See also: section GitHub OAuth token.github_app\
Github Application object with the required key-value pairs:client_id \
The client id of the GitHub application
installation_id \
The installation id of the GitHub application. To find out the value go to the application url e.g. https://github.com/settings/apps//installations and then click the gear icon. The installation id can be found in the URL itself: https://github.com/settings/installations/
private_key \
The private key generated for the GitHub application
See also: section GitHub app auth.
The advantage of using a Personal Access Token is that it is simpler to setup, while the advantage of a GitHub App is that it has a more generous rate limit. See section [#Caveat: GitHub rate limiting] for details.
context_prefix\
The prefix for the GitHub Commit status API "context" (see section Effects on GitHub). If present, the context will be set as context_prefix/job_name.\
Default: empty.\
See also: the optional context in the put step.
log_level:\
The log level (one of debug, info, warn, error).\
Default: info, recommended for normal operation.
github_hostname:\
GitHub hostname. This allows to post commit statuses to repositories hosted by GitHub Enterprise (GHE) instances. For example: github.mycompany.org will be expanded by cogito to https://github.mycompany.org/api/v3 \
Default: github.com
omit_target_url:\
If set to true, will omit the GitHub Commit status API target_url (the URL to the build on Concourse).\n
Default: false.
log_url. DEPRECATED, no-op, will be removed\
A Google Hangout Chat webhook. Useful to obtain logging for the check step for Concourse < v7.x
The keys required for Only GitHub commit status
gchat_webhook\
URL of a [Google Chat webhook]. A notification about the build status will be sent to the associated chat space, using a thread key composed by the pipeline name and commit hash.\
See also: chat_notify_on_states and section Effects on Google Chat.
The optional keys for Only GitHub commit status
chat_notify_on_states\
The build states that will cause a chat notification. One or more of abort, error, failure, pending, success.\
Default: [abort, error, failure].\
See also: section Build states mapping.
chat_append_summary\
One of: true, false. If true, append the default build summary to the custom put.params.chat_message and/or put.params.chat_message_file.\
Default: true.\
See also: the default build summary in Effects on Google Chat.
sinks\
The sinks list for chat notification.
Acceptable values: [gchat].
gchat_webhook\
URL of a [Google Chat webhook]. A notification will be sent to the associated chat space.\
See also: chat_notify_on_states and section Effects on Google Chat.
chat_notify_on_states\
The build states that will cause a chat notification. One or more of abort, error, failure, pending, success.\
Default: [abort, error, failure].\
See also: section Build states mapping.
chat_append_summary\
One of: true, false. If true, append the default build summary to the custom put.params.chat_message and/or put.params.chat_message_file.\
Default: true.\
See also: the default build summary in Effects on Google Chat.
We suggest to set a long interval for check_interval, for example 24 hours, as shown in the example above. This helps to reduce the number of check containers in a busy Concourse deployment and, for this resource, has no adverse effects.
No-op. Will always return the same version, dummy.
No-op.
Sets the GitHub commit status for a given commit, following the [GitHub Commit status API].
The same commit can have multiple statuses, differentiated by parameter context.
If the source block has the optional key gchat_webhook, then it will also send a message to the configured chat space, based on the state parameter.
state\
The state to set. One of error, failure, pending, success, abort.\
See also: the mapping explained in section Effects.context\
The value of the non-prefix part of the GitHub Commit status API "context"\
Default: the job name.\
See also: Effects on GitHub, source.context_prefix.sinks\
If present, overrides source.sinks. This allows to run step put for example to send to chat only.
Default: source.sinks.
gchat_webhook\
If present, overrides source.gchat_webhook. This allows to use the same Cogito resource for multiple chat spaces.\
Default: source.gchat_webhook.
chat_message\
Custom chat message; overrides the build summary. Its presence is enough for the chat message to be sent, overriding source.chat_notify_on_states.\
Default: empty.
chat_message_file\
Path to file containing a custom chat message; overrides the build summary. Appended to chat_message. Its presence is enough for the chat message to be sent, overriding source.chat_notify_on_states.\
Default: empty.
chat_append_summary\
Overrides source.chat_append_summary.
Default: `source.chat_append_summ
$ claude mcp add cogito \
-- python -m otcore.mcp_server <graph>