Code Monkey home page Code Monkey logo

brigade-github-app's Introduction

⚠️  This repo contains the source for a component of the Brigade v1.x ecosystem. Brigade v1.x reached end-of-life on June 1, 2022 and as a result, this component is no longer maintained.

Brigade v2 users can utilize the Brigade GitHub Gateway to support the use cases previously supported by this gateway.

Brigade Github App: Advanced GitHub Gateway for Brigade

This is a Brigade gateway that provides a GitHub App with deep integration to GitHub's new Check API.

screenshot

Installation

The installation for this gateway is multi-part, and not particularly easy at the moment.

Prerequisites:

  • A Kubernetes cluster running Brigade
  • kubectl and Helm

You will also need to pick out a domain name (referenced as YOUR_DOMAIN below) to send GitHub requests to. Example: gh-gateway.example.com. If you don't want to do this, see the notes in Step 3.

1. Create a GitHub App

A GitHub app is a special kind of trusted entity that is associated with either your account or an orgs account.

https://developer.github.com/apps/building-github-apps/creating-a-github-app/

  • Set the Homepage URL to https://brigade.sh
  • Set the User Authorization Callback URL to FIXME
  • Set the Webhook URL to https://YOUR_DOMAIN/events/github
  • Set the Webhook Secret to a randomly generated string. Make note of that string
  • Subscribe to the following events:
    • Repository contents: read
    • Issues: read
    • Repository metadata: read
    • Pull requests: read
    • Repository webhooks: read
    • Commit Statuses: Read And Write
    • Checks: Read and Write
  • Subscribe to the following webhooks:
    • Check suite
    • Check run
    • Issue comment (if intending to handle issue or general PR comments)
    • Pull request (if opting to create/rerequest Check suites from incoming PRs)
    • Push (if needing to handle push events, such as tag pushes)
  • Choose "Only This Account" to connect to the app.

Once you have submitted you will be prompted to create a private key. Create one and save it locally. You will put this in your values.yaml file in the next step.

2. Install the Helm chart into your cluster

The [Brigade Github App Helm Chart][brigade-github-app-chart] is hosted at the [brigadecore/charts][charts] repository.

You must install this gateway into the same namespace in your cluster where Brigade is already running.

Make sure the gateway is accessible on a public IP address. You can do that either by setting the Service to be a load balancer, or setting up the Ingress. We STRONGLY recommend setting up an ingress to use Kube-LEGO or another SSL proxy.

$ helm repo add brigade https://brigadecore.github.io/charts
$ helm inspect values brigade/brigade-github-app > values.yaml
$ # Edit values.yaml
$ helm install -n gh-app brigade/brigade-github-app

The private key you created in Step 1 should be put in your values.yaml file:

# Other stuff...
github:
  key: |
    YOUR KEY DATA GOES HERE!
    AND EVERY LINE NEEDS TO BE INDENTED

On RBAC-enabled clusters, pass --set rbac.enabled=true to the helm install command.

3. (RECOMMENDED) Create a DNS entry for your app

In the prerequisites section, we suggested that you create a domain. At this point, you should be able to link that domain to the IP generated by your Service or Ingress created above.

For example, to map an Ingress IP on our cluster (where we are using the kube-lego chart with the nginx-ingress chart), we can run this to get our IP:

$ kubectl get svc -n kube-system nginx-nginx-ingress-controller

(helm status on the appropriate charts will also give you this information)

NOTE: If you do not want to use a domain name, go change your GitHub App configuration to use the IP address directly.

4. Test the App from GitHub

Go to the Advanced tab and check out the Recent Deliveries section. This should show a successful test run. If it is not successful, you will need to troubleshoot why GitHub could not successfully contact your app.

Likely reasons:

  • Your app is not listening on a public IP
  • SSL certificate is invalid
  • The URL you entered is wrong (Go to the General tab and fix it)
  • The Brigade Github App is returning incorrect data

5. Install the App

Go to the Install App tab and enable this app for your account.

Accept the permissions it asks for. You can choose between All repos and Only select repositories, and click Install

It is easy to change from All Repos to Only Selected, and vice versa, so we recommend starting with one repo, and adding the rest later.

6. Add Brigade projects for each GitHub project

For each GitHub project that you enabled the app for, you will now need to create a Project.

Remember that projects contain secret data, and should be handled with care.

$ helm inspect values brigade/brigade-project > values.yaml
$ # Edit values.yaml

You will want to make sure to set:

  • project, repository, and cloneURL to point to your repo
  • sharedSecret to use the shared secret you created when creating the app

7. (OPTIONAL): Forwarding pull_request to check_suite

This gateway can enable a feature that converts certain PR events to Check Suite requests. (Namely, PR events with an action that indicates code was affected and may be in need of checking.) Currently, this is enabled by default.

To disable this feature, set the environment variable CHECK_SUITE_ON_PR=false on the deployment for the server. This can also be done by setting github.checkSuiteOnPR to false in the chart's values.yaml.

To forward a pull request (pull_request) to a check suite run, you will need to provide the ID for your GitHub Brigade App instance. (Here also set at the chart-level via values.yaml):

github:
...
  appID: APP_ID

This value is provided after the GitHub App is created on GitHub (see 1. Create a GitHub App). To find this value after creation, visit https://github.com/settings/apps/your-app-name.

Using the application ID and the private key configured when deploying the Helm chart, this gateway creates a new GitHub token for each request, meaning that we don't have to create a per-repository token.

When these parameters are set, incoming pull requests will also trigger check_suite:created events.

Handling Events in brigade.js

This gateway behaves differently than the gateway that ships with Brigade. Because this is a GitHub App, an authentication token is generated for each request on-the-fly. And each token is only good for 60 minutes.

The token is generated for you on the gateway, and sent in the payload, which looks like this:

{
  "token": "some.really.long.string",
  "body": {
    "action": "requested",
    "check_suite": {},
    "...": "..."
  }
}

The above shows just the very top level of the object. The object you will really receive will be much more detailed.

Events Emitted by this Gateway

Select events received by this gateway from Github are, in turn, emitted into Brigade. In some cases, events received from Github contain an action field. For all such events, two events will be emitted into Brigade. One will be a coarse-grained event, unaqualified by action. The second will be more finely-grained and qualified by action. The latter permits Brigade users to to more easily subscribe to a relevant subset of events that are of interest to them. For instance, if a user is interested in subscribing only to events that indicate a new pull request was opened, they may subscribe to pull_request:opened instead of subscribing to the more broad pull_request event, which would have burdened the user with writing logic to select on the basis of action themselves.

The events emitted by this gateway into Brigade are:

  • check_run: A check run event with any action. A second event qualified by action will also be emitted.
  • check_run:completed: The status of a check run was updated to completed.
  • check_run:created: A new check run was created.
  • check_run:requested_action: Someone requested that an action be taken.
  • check_run:rerequested: Someone requested to re-run your check run.
  • check_suite:completed: The status of a check suite was updated to completed.
  • check_suite:requested: A new check suite was created.
  • check_suite:rerequested: Someone requested to re-run your check suite.
  • commit_comment: A commit comment event with any action. A second event qualified by action will also be emitted.
  • commit_comment:created: A commit comment was created.
  • create: A branch or tag was created.
  • deployment: A deployment was created.
  • deployment_status: A deployment's sdtatus has changed.
  • issue_comment: An issue comment event with any action. A second event qualified by action will also be emitted.
  • issue_comment:created: An issue comment was created.
  • issue_comment:edited: An issue comment was edited.
  • issue_comment:deleted: An issue comment was deleted.
  • pull_request: A pull request event with any action. A second event qualified by action will also be emitted.
  • pull_request:assigned: A pull request was assigned.
  • pull_request:closed: A pull request was closed.
  • pull_request:edited: A pull request was edited (e.g. title or body is edited).
  • pull_request:labeled: A new label was assigned to a pull request.
  • pull_request:locked: A pull request was locked.
  • pull_request:opened: A new pull request was opened.
  • pull_request:ready_for_review: A pull request is ready for review.
  • pull_request:reopened: A closed pulled request was re-opened.
  • pull_request:review_request_removed: An existing request for pull request review was removed.
  • pull_request:review_requested: A pull request review was re-requested.
  • pull_request:unassigned: A pull request was unassigned.
  • pull_request:unlabeled: A label was removed from a pull request.
  • pull_request:unlocked: A pull request was unlocked.
  • pull_request_review: A pull request review with any action. A second event qualified by action will also be emitted.
  • pull_request_review:submitted: A pull request review was submitted.
  • pull_request_review:edited: A pull request review was edited.
  • pull_request_review:dismissed: A pull request review was dismissed.
  • pull_request_review_comment: A pull request review comment with any action. A second event qualified by action will also be emitted.
  • pull_request_review_comment:created: A new pull request review comment was created.
  • pull_request_review_comment:deleted: An existing pull request review comment was deleted.
  • pull_request_review_comment:edited: An existing pull request review comment was edited.
  • push: A commit was pushed to a branch or a new tag was applied.
  • release: A release event with any action. A second event qualified by action will also be emitted.
  • release:created: A new release was created.
  • release:deleted: An existing release was deleted.
  • release:edited: An existing release was edited.
  • release:prereleased: A release is pre-released.
  • release:published: A release is published.
  • release:unpublished: A release is unpublished.
  • status: The status of a git commit was changed.

Each of these events is described in greater detail in Github's own API documentation.

A special note on an issue_comment event: Since GitHub considers Pull Requests as Issues with code, this event will also be produced for general comments on Pull Requests -- meaning, outside of a dedicated Pull Request review or a comment on a commit directly. (The latter events would be pull_request_review_comment and commit_comment, respectively.)

The check_suite events will let you start all of your tests at once, while the check_run events will let you work with individual tests. The example in the next section shows how to work with suites, while still supporting re-runs of the main test.

Running a new set of checks

Currently this gateway forwards all events on to the Brigade.js script, and does not create new check_run requests. The brigade.js must create a run, and then update GitHub as to the status of that run.

Here's an example that starts a new run, does a test, and then marks that run complete. On error, it marks the run failed.

const {events, Job, Group} = require("brigadier");
const checkRunImage = "brigadecore/brigade-github-check-run:latest"

events.on("check_suite:requested", checkRequested)
events.on("check_suite:rerequested", checkRequested)
events.on("check_run:rerequested", checkRequested)

function checkRequested(e, p) {
  console.log("check requested")
  // Common configuration
  const env = {
    CHECK_PAYLOAD: e.payload,
    CHECK_NAME: "MyService",
    CHECK_TITLE: "Echo Test",
  }

  // This will represent our build job. For us, it's just an empty thinger.
  const build = new Job("build", "alpine:3.7", ["sleep 60", "echo hello"])

  // For convenience, we'll create three jobs: one for each GitHub Check
  // stage.
  const start = new Job("start-run", checkRunImage)
  start.imageForcePull = true
  start.env = env
  start.env.CHECK_SUMMARY = "Beginning test run"

  const end = new Job("end-run", checkRunImage)
  end.imageForcePull = true
  end.env = env

  // Now we run the jobs in order:
  // - Notify GitHub of start
  // - Run the test
  // - Notify GitHub of completion
  //
  // On error, we catch the error and notify GitHub of a failure.
  start.run().then(() => {
    return build.run()
  }).then( (result) => {
    end.env.CHECK_CONCLUSION = "success"
    end.env.CHECK_SUMMARY = "Build completed"
    end.env.CHECK_TEXT = result.toString()
    return end.run()
  }).catch( (err) => {
    // In this case, we mark the ending failed.
    end.env.CHECK_CONCLUSION = "failure"
    end.env.CHECK_SUMMARY = "Build failed"
    end.env.CHECK_TEXT = `Error: ${ err }`
    return end.run()
  })
}

Further Examples

See docs/examples for further brigade.js examples exercising different event handling scenarios, including Issue/PR comment handling, (re-)running individual Checks and more.

Parameters available on the check-run container

The following parameters can be specified via environment variables:

  • CHECK_PAYLOAD (REQUIRED): The contents of e.payload. Will be used to parse repo name, commit and branch (if not provided by corresponding env vars below), as well as auth token details
  • CHECK_NAME (default: Brigade): The name of the check. You should set this unless you are only running a single check.
  • CHECK_TITLE (default: "running check"): The title that will be displayed on GitHub
  • CHECK_SUMMARY: A short summary of what the check did.
  • CHECK_TEXT: A long message explaining the results.
  • CHECK_CONCLUSION: One of: "succeeded", "failure", "neutral", "canceled", or "timed_out". The "action_required" conclusion can be set if CHECK_DETAILS_URL is also set.
  • CHECK_STARTED_AT: The time that the check run started (timestamp in ISO 8601 format). This is used to calculate the running time of the check run.
  • CHECK_DETAILS_URL: The URL of an external site that has more information. This is typically used with CHECK_CONCLUSION=action_required.
  • CHECK_EXTERNAL_ID: An ID that correlates this run to another source. For example, it could be set to the Brigade build ID.
  • CHECK_ACTIONS: Custom definition of further check run actions displayed as buttons. See the GitHub documentation on actions
  • GITHUB_BASE_URL: The URL for GitHub Enterprise users.
  • GITHUB_UPLOAD_URL: The upload URL for GitHub Enterprise users.

Annotations and Image attachments are not currently supported.

You can observe these in action on this screenshot:

screenshot

Contributing

This Brigade project accepts contributions via GitHub pull requests. This document outlines the process to help get your contribution accepted.

Prerequisites

  • Docker
  • make

Containerized Development Environment

To ensure a consistent development environment for all contributors, this project relies heavily on Docker containers as sandboxes for all development activities including dependency resolution, executing tests, or running a development server.

make targets seamlessly handle the container orchestration.

If, for whatever reason, you must opt-out of executing development tasks within containers, set the SKIP_DOCKER environment variable to true, but be aware that by doing so, the success or failure of development-related tasks, tests, etc. will be dependent on the state of your system, with no guarantee of the same results in CI.

Developing on Windows

All development-related tasks should "just work" on Linux and Mac OS systems. When developing on Windows, the maintainers strongly recommend utilizing the Windows Subsystem for Linux.

This blog post provides excellent guidance on making the Windows Subsystem for Linux work seamlessly with Docker Desktop (Docker for Windows).

Working with Code

$ make lint          # to run linters
$ make test          # to run tests
$ make build         # to run multi-stage Docker build of binaries and images

Pushing Images

By default, built images are named using the following scheme: <component>:<version>. If you wish to push customized or experimental images you have built from source to a particular org on a particular Docker registry, this can be controlled with environment variables.

The following, for instance, will build images that can be pushed to the krancour org on Dockerhub (the registry that is implied when none is specified).

$ DOCKER_ORG=krancour make build

To build for the krancour org on a different registry, such as quay.io:

$ DOCKER_REGISTRY=quay.io DOCKER_ORG=krancour make build

Images built with names that specify registries and orgs for which you have write access can be pushed using make push. Note that the build target is a dependency for the push target, so the build and push processes can be accomplished together like so:

Note also that you must be logged into the registry in question before attempting this.

$ DOCKER_REGISTRY=quay.io DOCKER_ORG=krancour make push

Signed commits

A DCO sign-off is required for contributions to repos in the brigadecore org. See the documentation in Brigade's Contributing guide for how this is done.

brigade-github-app's People

Contributors

adamreese avatar anjakammer avatar jeremyrickard avatar jsoref avatar karenhchu avatar krancour avatar microsoftopensource avatar msftgits avatar mumoshu avatar radu-matei avatar technosophos avatar vdice avatar

Stargazers

 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  avatar

brigade-github-app's Issues

Inconsistency in events emitted by this gateway

Related to #48

WRT certain Github events like check_run and check_suite, this gateway is emitting Brigade events in the form <github event>:<github event action>, but WRT to other Github events like pull_request or push, this gateway is emitting Brigade events that are simply of the form <github event>.

The consequence of this inconsistency is that in a Brigade.js, WRT certain Github events like check_run and check_suite, one may conveniently attach handlers to Brigade events that represent a Github event:action pair such as check_run:rerequested, but WRT other Github events like pull_request, one cannot do this, and instead, must handle the unqualified pull_request event and parse the payload to find the action and determine if the event is actually actionable.

imho, this inconsistency makes event-handling a bit more idiosyncratic than it probably needs to be and makes the learning curve a bit worse.

Any thoughts on how this could be improved?

Use go-github API for check-run cmd

Currently cmd/check-run/main.go constructs its http request from scratch. We should probably update the code to use the Checks API library from go-github (CreateCheckRun, etc.)

Environment parity with GitHub Actions

GitHub Actions injects the following variables into the environment executing an action.

Ideally, we would inject the same (exception might make GITHUB_TOKEN), so container images can be interchangeably used between Brigade and GitHub Actions.

Below is the full list of injected values:

Environment variable Description
HOME The path to the GitHub home directory used to store user data. Value: /github/home.
GITHUB_WORKFLOW The name of the workflow.
GITHUB_ACTION The name of the action.
GITHUB_ACTOR The name of the person or app that initiated the workflow. For example, octocat.
GITHUB_REPOSITORY The owner and repository name. For example, octocat/Hello-World.
GITHUB_EVENT_NAME The webhook name of the event that triggered the workflow.
GITHUB_EVENT_PATH The path to a file that contains the payload of the event that triggered the workflow. Value: /github/workflow/event.json.
GITHUB_WORKSPACE The GitHub workspace path. Value: /github/workspace. Note: GitHub actions must be run by the default Docker user (root). Ensure your Dockerfile does not set the USER instruction, otherwise you will not be able to access GITHUB_WORKSPACE.
GITHUB_SHA The commit SHA that triggered the workflow.
GITHUB_REF The branch or tag ref that triggered the workflow. For example, refs/heads/feature-branch-1. If neither a branch or tag is available for the event type, the variable will not exist.
GITHUB_TOKEN A GitHub App installation token scoped to the repository containing the workflow file. To access this environment variable from an action, you must add the GITHUB_TOKEN secret to each action that requires access. This variable is not available to an action by default. To learn more about GitHub Action secrets, see "Storing secrets."

Single Brigade project, multiple GitHub repositories

We have a Brigade project that analyzes our GitHub repositories and generates a "scorecard" for each repository - this currently runs every couple of hours on a cron schedule, but we'd really like to leverage this app to run it as a GitHub check.

From the docs, it sounds like this would mean creating a separate Brigade project for each repository though, and we have 100+ repositories.

I'm wondering if it's a hard requirement that there be a project for each repository, or if it's possible the app could be extended somehow to work with a single Brigade project + many GitHub repositories?
(Maybe something analogous to the defaultSharedSecret value, like defaultProject?)

Check Suite on PR: Can Installation ID be derived from webhook(s)?

The ability to trigger Check Suites/Runs on incoming PRs was added in #13.

In order for this to work, both the App ID and Installation ID were added to the Helm chart/deployment as the PR webhook didn't contain at least the former. However, these webhooks appear to contain the latter, Installation ID. Therefore, it is worth investigating if this value can be derived when processing the webhook, eliminating the need for passing this value down through the chart/deployment.

CI via Brigade

Build CI for this repo:

  • run build/test on PRs
  • publish artifacts (images) on master/tag pushes & "release" events
  • use this project for Brigade project's GH gateway, naturally
  • sibling to Azure/brigade, Azure/kashti projects

proposal: make images smaller

Currently, we're basing images on alpine, but other than using its root CAs, I'm not sure why we need it.

It should be pretty easy to build FROM scratch and simply add root CAs.

If / when we transition to multi-stage Dockerfile builds, this is especially easy to do by copying the root CAs over from a previous stage.

Tail flag for Brigade job logs

I'm using VK to schedule Brigade jobs on top of ACI using this gateway for GitHub -- everything is working correctly, apart from how the logs are shown in the GitHub UI -- I'm only seeing the last few lines from the logs.

Is there a way to pass the equivalent of the kubectl logs --tail 1000 flag when sending the logs back to the GitHub UI?

Improve error reporting

This is very similar to brigadecore/brigade#938 but specific to brigade-github-app.

I think brigade-github-app should have an out-of-box way to tell the user what's went wrong when an init-container failed, in a more user-friendly way.

Problem

Let's say you wrote a brigade.js that reacts on issue_comment on PRs. Commenting on a PR with /whatever results in brigade-github-app receiving a GitHub webhook and creating brigade-worker to run your brigade.js.

Now, when the init container failed while cloning the git repo due to permission issue, you have no easy way to debug what went wrong. /whatever doesn't trigger expected github checks, hence no PR statuses updated, no brigade workers run.

You can author your brigade.js to comment-back to the PR but it obviously don't work when the init container was failed - as brigade-worker has failed before running brigade.js.

Possible Solution

How about brigade-github-app comment-back a message like brigade-worker failed: <last N lines of failed (init) container of the brigade worker>, if the triggering webhook is issue_comment on a github pull request, or push to a pull-requested branch?

This way the user can easily get what went wrong when, as soon as they push a new commit to a pull-requested branch, or add a comment on the pr?

proposal: track vendored code

This is increasingly recognized as a good practice, especially when using dep.

A huge benefit to this is that make bootstrap goes away. When you check out a branch / tag / commit, or whatever, you just automatically have all the right dependencies and a build can proceed with no fuss.

It does necessitate validating, as part of CI, that vendored code hasn't willfully or accidentally been modified, but dep check can easily do just that.

[proposal] remove check suite forwarding

Currently, if "check suite forwarding" is enabled, the gateway deals with pull requests by using the GitHub API to request a corresponding check suite to be run.

Per comments in the gateway's own code, this is because GitHub doesn't automatically request a check suite to be run when a PR is opened:

// The Check Suite webhook events are normally only triggered on `push` events. This function acts as an
// adapter to take a PR and trigger a check suite.

This doesn't strike me as an oversight on GitHub's part. As far as I can tell, this was by design. I believe they presume, especially given that this particular API is still in preview, that those wishing to do something in response to a pull request are already subscribed to pull request events and don't need these additional events on top of it.

Additionally, an explicit check suite need not have been pre-requested for any authorized user of the API to use it to update a check suite's constituent check runs. i.e. A check suite automatically gets created by GitHub when a check run for a given commit is created/updated.

Why then do we need check suite forwarding at all? I can only find one explanation, which seems more to be an accident of implementation than a deliberate choice. The gateway wraps check suite request events in another type that also has an installation token field. Downstream, a brigade.js script can be (needs to be 😦 ) aware of that wrapper and can extract the token and later use it to update individual check runs.

This issue is related: #7

Long story short-- if the token needed for updating check runs were more widely available (i.e. in a pull request event) then there wouldn't be any compelling reason for the gateway to implement check suite forwarding, nor would there be frequent incentive for brigade.js scripts to subscribe to check suite forwarding requests where a pull request is what they're actually interested in. i.e. We can "de-complicate" things pretty significantly by dropping the "check suite forwarding" feature and solving, instead, for a more general problem: How can a gateway "staple" credentials (or other information) to an event that permits a brigade.js script to update the event source with build status. This seems like it is (or could be) a general / common / recurring concern rather than one that is github-specific or even PR/check-suite-specific.

Of course, this involves some breaking changes that we probably cannot seriously entertain pre-2.0.

We could take a phased approach to this:

Now:

  1. Solve the general problem
  2. Discourage further use of check suite forwarding

2.0:

  1. Remove the check suite forwarding feature

Does this gateway emit more events than what are documented?

The README.md mentions these events are emitted from this gateway:

  • check_suite:requested: When a new request is opened
  • check_suite:rerequested: When checks are requested again
  • check_suite:completed: When a check suite is completed
  • check_run:created: When an individual test is requested
  • check_run:updated: When an individual test is updated with new status
  • check_run:rerequested: When an individual test is re-requested

But for sure, other events like push and pull_request are also being emitted (and rightfully so), because builds are still being triggered by these events.

Should the rest of the events emitted by this gateway be documented?

proposal: stop continuously publishing images tagged with latest

We publish updated images tagged with latest on every merge to master. Given that the chart that references this brigadecore/brigade-github-app:latest (admittedly, a bad practice; see brigadecore/charts#14) also default to an image pull policy of always, this practice of continuously updating the latest image means we're continuously replacing the rug under people's feet with the latest from master-- which perhaps we don't really want to release into the wild yet and certainly don't want to impose on unsuspecting users.

Cut a new release

I noticed that there are a fair number of commits to this project since the last v0.2.1 tag (all from @krancour so far!! 👏 )

Therefore, proposing we test master and potentially cut a new release soon (probably a minor increment for v0.3.0?)

(Was reminded of this as we're currently in the process of cutting the next v1.3.0 release for Brigade...)

Check Run container errors when env var exceeds size limit

It appears there are cases where the check run utility will fail to run (and thus, fail to update a check run's status) if one or more of the values passed to it via environment variables exceeds the default env var length limit (depending on Unix env). When this occurs, the process then exits with standard_init_linux.go:178: exec user process caused "argument list too long" (Research seems to point to exceeding the env var length limit when searching on this error message.)

I've encountered this behavior when attempting to update a check run with the lengthy output of a test run -- so, text, or CHECK_TEXT is quite large; in fact, too large.

Assuming I'm correct as to the underlying cause of the issue, what might be an improvement we can make to avoid this limitation? Perhaps adding the ability to mount a volume for pulling data of large sizes into this utility/container so it can then successfully make the GH check run api call?

Gateway cannot get secrets / tries to get secret from wrong namespace

The gateway cannot get the project secret when everything is deployed in a different namespace.

Here's a quick setup:

  • Kubernetes 1.10.3, RBAC enabled

  • Brigade + the GitHub gateway + Brigade project deployed in the brigade namespace

  • the Brigade project:

$ brig project list --namespace brigade
NAME                                    ID                                                              REPO
radu-matei/brigade-eventgrid-gateway    brigade-a450e8624578997e2c0cc3cd2abff8bb962acf99e1e4fd7db7b1ec  github.com/radu-matei/brigade-eventgrid-gateway
  • the gateway deployment:
$ kubectl describe deployment github-app-brigade-github-app
Name:                   github-app-brigade-github-app
Namespace:              brigade
CreationTimestamp:      Wed, 11 Jul 2018 22:49:23 +0300
Labels:                 app=github-app-brigade-github-app
                        chart=brigade-github-app-0.1.1
                        heritage=Tiller
                        release=github-app
                        role=gateway
                        type=github-app
Annotations:            deployment.kubernetes.io/revision=1
Selector:               app=github-app-brigade-github-app,release=github-app,role=gateway,type=github-app
Pod Template:
  Labels:           app=github-app-brigade-github-app
                    release=github-app
                    role=gateway
                    type=github-app
  Service Account:  github-app-brigade-github-app
  Containers:
   brigade-github-app:
    Image:  technosophos/brigade-github-app:latest
    Port:   <none>
    Environment:
      GATEWAY_NAMESPACE:   (v1:metadata.namespace)
      GATEWAY_CONFIG:     /etc/brigade-github-app/key.pem
    Mounts:
      /etc/brigade-github-app from github-config (rw)
  • the GATEWAY_NAMESPACE environment variable is set correctly inside the pod:
$ kubectl exec -it github-app-brigade-github-app-58f7d99bb8-f9bks /bin/sh
/ # printenv | grep GATEWAY_NAMESPACE
GATEWAY_NAMESPACE=brigade
  • trying to send events to the gateway from GitHub:
Project "radu-matei/brigade-eventgrid-gateway" not found. No secret loaded. secrets "brigade-a450e8624578997e2c0cc3cd2abff8bb962acf99e1e4fd7db7b1ec" is forbidden: User "system:serviceaccount:brigade:github-app-brigade-github-app" cannot get secrets in the namespace "default"
  • service account used:
$ kubectl describe serviceaccount github-app-brigade-github-app
Name:         github-app-brigade-github-app
Namespace:    brigade
Labels:       app=github-app-brigade-github-app
              chart=brigade-github-app-0.1.1
              heritage=Tiller
              release=github-app
Annotations:  <none>

Mountable secrets:   github-app-brigade-github-app-token-5pzvb

Tokens:              github-app-brigade-github-app-token-5pzvb

Image pull secrets:  <none>

Events:  <none>

It appears to be an RBAC-related issue - however, I don't understand why it tries to get secrets from the default namespace.

Multiple GitHub webhooks create worker pods in cluster

Using this as part of the CI process -- it is mainly used for the pull_request or check_suite:requested events. But as Brigade is executing the check run, and posting information about the build back to GitHub, it gets multiple webhooks -- the following builds are for a single PR:

$ brig build list --namespace brigade
ID                        	TYPE                   	PROVIDER   	PROJECT                                                       	STATUS   	AGE
01d64bmcj8a0df42r0bq87ywfk	check_suite:completed  	github     	brigade-4cf8fe2e2a0fe809cfe9bbbee83dcfbe9ff8d86c274145276d442c	Succeeded	17m
01d64bmcj53rjbqd2ed6fzxrqr	check_run:created      	github     	brigade-4cf8fe2e2a0fe809cfe9bbbee83dcfbe9ff8d86c274145276d442c	Succeeded	17m
01d64bmch5qb9q9evhwbart2h1	check_run:completed    	github     	brigade-4cf8fe2e2a0fe809cfe9bbbee83dcfbe9ff8d86c274145276d442c	Succeeded	17m
01d64bhcw299mhxna867gnndch	check_run:created      	github     	brigade-4cf8fe2e2a0fe809cfe9bbbee83dcfbe9ff8d86c274145276d442c	Succeeded	19m
01d64bgm1hh49yx9s5c37z1np9	check_suite:rerequested	github     	brigade-4cf8fe2e2a0fe809cfe9bbbee83dcfbe9ff8d86c274145276d442c	Succeeded	17m
01d64bgk8c95nfvrkgcz8fnxr0	pull_request           	github     	brigade-4cf8fe2e2a0fe809cfe9bbbee83dcfbe9ff8d86c274145276d442c	Succeeded	19m

This translates in multiple workers being created in my cluster:

$ kubectl get pods
NAME                                                    READY   STATUS      RESTARTS   AGE
brigade-worker-01d64bgk8c95nfvrkgcz8fnxr0               0/1     Completed   0          25m
brigade-worker-01d64bgm1hh49yx9s5c37z1np9               0/1     Completed   0          25m
brigade-worker-01d64bhcw299mhxna867gnndch               0/1     Completed   0          24m
brigade-worker-01d64bmch5qb9q9evhwbart2h1               0/1     Completed   0          23m
brigade-worker-01d64bmcj53rjbqd2ed6fzxrqr               0/1     Completed   0          23m
brigade-worker-01d64bmcj8a0df42r0bq87ywfk               0/1     Completed   0          23m
end-run-01d64bgm1hh49yx9s5c37z1np9                      0/1     Completed   0          23m
rust-build-01d64bgm1hh49yx9s5c37z1np9                   0/1     Completed   0          24m
start-run-01d64bgm1hh49yx9s5c37z1np9                    0/1     Completed   0          24m

And while the actual jobs for my project are only created once, multiple worker pods are created.

I'm curious how other projects handle this, and what are the GitHub webhook settings associated with the installation.

cc @vdice

Simplify instructions for CD pipeline

Please add documentation for the smallest possible CD use case, to speed up the process of vetting this tool for newcomers 🙋‍♂️

Since

The installation for this gateway is multi-part, and not particularly easy at the moment.

Innocent-looking instructions like

Set the Webhook URL to https://YOUR_DOMAIN/events/github

Involve an unknown set of potentially unnecessary steps that cause quite a bit of fatigue, especially after installing yet another cli.

How can a newcomer navigate these waters without getting lost at sea?
Is is absolutely necessary to create a github app?
Is there a way to interact with a cUrl command or github webhook?

Please consider making instructions for the smallest possible CD use-case. Thank you

Revisit naming

Consider revisiting naming of this project (as well as its corresponding chart and associated documentation in Brigade to clarify/emphasize that this is a Github App-based gateway for Brigade.

Proposal: supress certain events from untrusted users until a trusted user approves

There have been a few different discussions in different threads about closing down an attack vector wherein untrusted users can open malicious PRs and Brigade will blindly trigger a build. This could be used, for instance, to steal credentials or abuse project resources.

Some discussion has involved restricting untrusted users from modifying brigade.js, but it's widely agreed upon now that that doesn't go far enough because if we don't also restrict the ability to modify other "executable somethings" (scripts, make targets, etc.) that build jobs rely upon, then the attack vector in question hasn't really been closed off.

After much discussion in brigadecore/brigade#961, a more effective approach has been identified. This issue supercedes that one and moves further discussion of that approach to the appropriate repository.

Current State

When a PR is opened or amended, commented upon, etc., a pull_request (with some action field in the payload further qualifying the event) is sent from Github to the gw. The gw emits these events into Brigade and if enabled, performs "check suite forwarding," which involves an API call to Github itself to prompt Github itself to send a check_suite event with an action of rerequested to the gw. The gateway also emits this into Brigade.

Proposed Future State

Note: To preserve backward compatibility, it is proposed that all of the following be hidden behind a feature flag.

When a PR is opened or amended, commented upon, etc., a pull_request (with some action field in the payload further qualifying the event) is sent from Github to the gw. If the event in question was triggered by a trusted user, everything happens the same as it does today. If the event was triggered by an untrusted user and is one that commonly triggers a build (e.g. pull_request events with an action of closed do not typically trigger builds), then that event is suppressed-- i.e. not emitted into Brigade.

When an issue_comment event is subsequently received from a trusted user and contains /test in its body, this is interpreted as a one-time approval to test the PR in its current state. (i.e. future amendments to the PR require new approvals). This will prompt the "check suite forwarding" process that was previously bypassed.

Caveat

Under this proposal, certain events from untrusted users, e.g. pull_request with action of opened will never make it through the gateway and out into Brigade itself. This means this workflow is only suitable for installations of Brigade (and project brigade.js files) that trigger builds off of check_suite events rather than pull_request events). This is already the common way of doing things, so this caveat doesn't seem damning to me.

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.