Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
220 changes: 219 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
## This was forked from the original [aoldershaw/github-pr-resource](https://github.com/aoldershaw/github-pr-resource)
to add an additional security check when looking at PR approvals.
to add an additional security check when looking at PR approvals.

You can find it on Dockerhub as the `tasruntime/github-pr-instances-resource` image.

Expand Down Expand Up @@ -58,6 +58,33 @@ As noted earlier, this resource can either track a list of PRs to a repository,
or track commits to a single PR. The different modes of operation have
different configuration options.

### Authentication

This resource supports two authentication methods:

1. **Personal Access Token**: The traditional method using a GitHub access token
2. **GitHub App**: Authentication using a GitHub App installation (new feature)

You must choose one authentication method - they cannot be used together.

#### Personal Access Token Authentication

| Parameter | Required | Example | Description |
|----------------|----------|---------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `access_token` | Yes* | | A Github Access Token with repository access. For private repositories, set `repo:full` permissions on the token. For public repositories, `repo:status` is sufficient. *Required unless using GitHub App authentication* |

#### GitHub App Authentication

| Parameter | Required | Example | Description |
|-------------------------------|----------|------------------------|------------------------------------------------------------------------|
| `github_app_id` | Yes* | `12345` | The ID of your GitHub App |
| `github_app_installation_id` | Yes* | `67890` | The installation ID of your GitHub App |
| `github_app_private_key` | Yes** | `-----BEGIN RSA...` | The private key content for your GitHub App |
| `github_app_private_key_path` | Yes** | `/path/to/private.key` | Path to a file containing the private key for your GitHub App |

*Required only when using GitHub App authentication instead of access_token
**Either github_app_private_key OR github_app_private_key_path must be provided

### List of PRs

By omitting the `source.number` parameter, this resource will list PRs in a
Expand Down Expand Up @@ -223,6 +250,8 @@ requires two pipeline templates.
For this example, assume you have a resource named `ci`, a repo which contains
the following pipeline files:

### Example using Personal Access Token

`ci/pipelines/parent.yml`
```yaml
resource_types:
Expand Down Expand Up @@ -315,6 +344,195 @@ resources:
get_params: {skip_download: true}
```

### Example using GitHub App Authentication

`ci/pipelines/parent.yml`
```yaml
resource_types:
- name: pull-request
type: registry-image
source:
repository: tasruntime/github-pr-resource

resources:
- name: pull-requests
type: pull-request
source:
repository: itsdalmo/test-repository
github_app_id: ((github-app-id))
github_app_installation_id: ((github-app-installation-id))
github_app_private_key: ((github-app-private-key))

- name: ci
type: git
source:
uri: https://github.com/concourse/ci

jobs:
- name: update-pr-pipelines
plan:
- get: ci
- get: pull-requests
trigger: true
- load_var: pull_requests
file: pull-requests/prs.json
- across:
- var: pr
values: ((.:pull_requests))
set_pipeline: prs
file: ci/pipelines/child.yml
instance_vars: {number: ((.:pr.number))}
```

`ci/pipelines/child.yml`
```yaml
resource_types:
- name: pull-request
type: registry-image
source:
repository: tasruntime/github-pr-resource

resources:
- name: pull-request
type: pull-request
source:
repository: itsdalmo/test-repository
github_app_id: ((github-app-id))
github_app_installation_id: ((github-app-installation-id))
github_app_private_key: ((github-app-private-key))
number: ((number))

jobs:
- name: test
plan:
- get: pull-request
trigger: true
- put: pull-request-status
resource: pull-request
params:
path: pull-request
status: pending
get_params: {skip_download: true}
# Rest of job definition remains the same
```

### Example using GitHub App Authentication with Submodules

For repositories that contain git submodules, you can enable submodule support by setting `submodules: true` in the `get_params`.

`ci/pipelines/parent.yml` (with GitHub App and Submodules)
```yaml
resource_types:
- name: pull-request
type: registry-image
source:
repository: tasruntime/github-pr-resource

resources:
- name: pull-requests
type: pull-request
source:
repository: itsdalmo/test-repository
github_app_id: ((github-app-id))
github_app_installation_id: ((github-app-installation-id))
github_app_private_key: ((github-app-private-key))

- name: ci
type: git
source:
uri: https://github.com/concourse/ci

jobs:
- name: update-pr-pipelines
plan:
- get: ci
- get: pull-requests
trigger: true
- load_var: pull_requests
file: pull-requests/prs.json
- across:
- var: pr
values: ((.:pull_requests))
set_pipeline: prs
file: ci/pipelines/child.yml
instance_vars: {number: ((.:pr.number))}
```

`ci/pipelines/child.yml` (with GitHub App and Submodules)
```yaml
resource_types:
- name: pull-request
type: registry-image
source:
repository: tasruntime/github-pr-resource

resources:
- name: pull-request
type: pull-request
source:
repository: itsdalmo/test-repository
github_app_id: ((github-app-id))
github_app_installation_id: ((github-app-installation-id))
github_app_private_key: ((github-app-private-key))
number: ((number))

jobs:
- name: test
plan:
- get: pull-request
trigger: true
get_params:
submodules: true # Enable recursive submodule cloning
integration_tool: merge # Optional: merge, rebase, or checkout
- put: pull-request-status
resource: pull-request
params:
path: pull-request
status: pending
get_params: {skip_download: true}
- task: unit-test
config:
platform: linux
image_resource:
type: registry-image
source: {repository: alpine/git, tag: latest}
inputs:
- name: pull-request
run:
path: /bin/sh
args:
- -xce
- |
cd pull-request
# Submodules are now available in subdirectories
ls -la
git log --graph -n 10 --color --pretty=format:"%x1b[31m%h%x09%x1b[32m%d%x1b[0m%x20%s" > log.txt
cat log.txt
on_success:
put: pull-request
params:
path: pull-request
status: success
get_params: {skip_download: true}
on_failure:
put: pull-request
params:
path: pull-request
status: failure
get_params: {skip_download: true}
```

**Notes on Submodule Support:**

* When `submodules: true` is set, the resource will recursively initialize and update all git submodules
* Submodules are supported with both `access_token` and `github_app_*` authentication methods
* The `integration_tool` parameter determines how submodules are updated after merging:
* `merge` (default): Uses `git submodule update --init --recursive --merge`
* `rebase`: Uses `git submodule update --init --recursive --rebase`
* `checkout`: Uses `git submodule update --init --recursive --checkout`
* All submodule repositories are automatically authenticated using the same credentials as the main repository
* Git LFS is supported alongside submodules through the `disable_git_lfs` parameter in the source

## Costs

The Github API(s) have a rate limit of 5000 requests per hour (per user). For the V3 API this essentially
Expand Down
2 changes: 1 addition & 1 deletion Taskfile.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version: '2'
version: '3'

vars:
BUILD_DIR: build
Expand Down
35 changes: 18 additions & 17 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,27 +1,28 @@
module github.com/cloudfoundry-community/github-pr-instances-resource

require (
github.com/google/go-github/v28 v28.1.1
github.com/maxbrunsfeld/counterfeiter/v6 v6.2.3
github.com/shurcooL/githubv4 v0.0.0-20230424031643-6cea62ecd5a9
github.com/stretchr/testify v1.3.0
github.com/telia-oss/github-pr-resource v0.23.0
golang.org/x/oauth2 v0.8.0
github.com/bradleyfalzon/ghinstallation/v2 v2.17.0
github.com/google/go-github/v75 v75.0.0
github.com/maxbrunsfeld/counterfeiter/v6 v6.12.0
github.com/shurcooL/githubv4 v0.0.0-20240727222349-48295856cce7
github.com/stretchr/testify v1.11.1
golang.org/x/oauth2 v0.32.0
)

require (
github.com/davecgh/go-spew v1.1.0 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/golang-jwt/jwt/v4 v4.5.2 // indirect
github.com/google/go-querystring v1.1.0 // indirect
github.com/kr/pretty v0.3.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/shurcooL/graphql v0.0.0-20220606043923-3cf50f8a0a29 // indirect
golang.org/x/crypto v0.9.0 // indirect
golang.org/x/mod v0.2.0 // indirect
golang.org/x/net v0.10.0 // indirect
golang.org/x/tools v0.0.0-20200423205358-59e73619c742 // indirect
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/protobuf v1.30.0 // indirect
github.com/shurcooL/graphql v0.0.0-20230722043721-ed46e5a46466 // indirect
golang.org/x/mod v0.29.0 // indirect
golang.org/x/sync v0.17.0 // indirect
golang.org/x/text v0.30.0 // indirect
golang.org/x/tools v0.37.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

go 1.20
go 1.24.0

tool github.com/maxbrunsfeld/counterfeiter/v6
Loading