diff --git a/go.mod b/go.mod index bb09955..aa941ba 100644 --- a/go.mod +++ b/go.mod @@ -13,6 +13,7 @@ require ( github.com/cloudevents/sdk-go/v2 v2.15.2 github.com/coreos/go-oidc/v3 v3.11.0 github.com/golang-jwt/jwt/v4 v4.5.0 + github.com/google/go-cmp v0.6.0 github.com/google/go-github/v61 v61.0.0 github.com/hashicorp/go-multierror v1.1.1 github.com/hashicorp/golang-lru/v2 v2.0.7 diff --git a/pkg/webhook/testdata/api/v3/repos/foo/bar/compare/1234...5678 b/pkg/webhook/testdata/api/v3/repos/foo/bar/compare/1234...5678 new file mode 100644 index 0000000..2113f59 --- /dev/null +++ b/pkg/webhook/testdata/api/v3/repos/foo/bar/compare/1234...5678 @@ -0,0 +1,422 @@ +{ + "url": "https://api.github.com/repos/chainguard-dev/wlynch-test/compare/main...77d49996a5b88ff14fa57eb9094a0316d23b7537", + "html_url": "https://github.com/chainguard-dev/wlynch-test/compare/main...77d49996a5b88ff14fa57eb9094a0316d23b7537", + "permalink_url": "https://github.com/chainguard-dev/wlynch-test/compare/chainguard-dev:306e576...chainguard-dev:77d4999", + "diff_url": "https://github.com/chainguard-dev/wlynch-test/compare/main...77d49996a5b88ff14fa57eb9094a0316d23b7537.diff", + "patch_url": "https://github.com/chainguard-dev/wlynch-test/compare/main...77d49996a5b88ff14fa57eb9094a0316d23b7537.patch", + "base_commit": { + "sha": "306e576f9026d6afb4baa812df3dd538c35c006d", + "node_id": "C_kwDOHUbyj9oAKDMwNmU1NzZmOTAyNmQ2YWZiNGJhYTgxMmRmM2RkNTM4YzM1YzAwNmQ", + "commit": { + "author": { + "name": "Billy Lynch", + "email": "1844673+wlynch@users.noreply.github.com", + "date": "2024-09-03T18:26:21Z" + }, + "committer": { + "name": "GitHub", + "email": "noreply@github.com", + "date": "2024-09-03T18:26:21Z" + }, + "message": "Create test.sts.yaml\n\nSigned-off-by: Billy Lynch <1844673+wlynch@users.noreply.github.com>", + "tree": { + "sha": "51c2ca22e725d908da339f40c38a78ab10c69b7e", + "url": "https://api.github.com/repos/chainguard-dev/wlynch-test/git/trees/51c2ca22e725d908da339f40c38a78ab10c69b7e" + }, + "url": "https://api.github.com/repos/chainguard-dev/wlynch-test/git/commits/306e576f9026d6afb4baa812df3dd538c35c006d", + "comment_count": 0, + "verification": { + "verified": true, + "reason": "valid", + "signature": "-----BEGIN PGP SIGNATURE-----\n\nwsFcBAABCAAQBQJm11TNCRC1aQ7uu5UhlAAAvjIQAAYWvoNzlNBOftmCWDdlRD7/\nFpbzoLMAXpuVVh/pPJvfN04ywtmwbDRHDD+Tu7qHHDHe4dyYrqmCT94e5/4kJAtg\ngrhsXhSJQQNOsZTDXV28E7mMKTXUGa1ewB8d6mmhTAWQTuMpCVzWXlUa3qauMP1F\niih49n1YxVLSUFz+U1C/NeacWJC2pGcsLs3lZSmeTQ0kF2i6iFkQyYSVv4uDhUCt\n4iktN3nZY9WhQQ3ucWMQhqk4iNkg9Cusw8pXYMd5V09DQJhNInkjiril55kk8dow\nCfaF5zdPdbWKEPJNvq3Jp7cBuEbGz74TQPkK9OBE4P+GRZu0C0u/fSv63ifXL9W0\nQKh2NXUljmsZ4kmrDla4wWEU4Hdr+r6nmpxRWCUGzOhAgqIQWLE+xW/NF6XodXBK\nfUWh1jfRszbsesC6OdBjsqiqsznCSLhPXZ7XBdJvpf4NzDxBtqn2O0ajfzM8OZRA\n7n+DhC7RiFUKIONapiTFicrz7ZQBRxTJQkcm+ics6hykpvdaN3f6sz2y6apw5OD1\ng55rjcN3lm+36KUI/hE0CGMrYcTAq59KIdYwUE2Sq8NuE2PBv94zOd1Xdud8ryuk\nJVxUG/sOaRP33zYD/VHxR1VN5PDzgSqWqFNPlv8T3cJ0bh/q2WJHoqyMNubZdS/8\nL8t06DSWGSSjZdNuUVdW\n=QFtw\n-----END PGP SIGNATURE-----\n", + "payload": "tree 51c2ca22e725d908da339f40c38a78ab10c69b7e\nparent a3d5fd86ce35211a5312a60bc5bdd44ecc426bfa\nauthor Billy Lynch <1844673+wlynch@users.noreply.github.com> 1725387981 -0400\ncommitter GitHub 1725387981 -0400\n\nCreate test.sts.yaml\n\nSigned-off-by: Billy Lynch <1844673+wlynch@users.noreply.github.com>" + } + }, + "url": "https://api.github.com/repos/chainguard-dev/wlynch-test/commits/306e576f9026d6afb4baa812df3dd538c35c006d", + "html_url": "https://github.com/chainguard-dev/wlynch-test/commit/306e576f9026d6afb4baa812df3dd538c35c006d", + "comments_url": "https://api.github.com/repos/chainguard-dev/wlynch-test/commits/306e576f9026d6afb4baa812df3dd538c35c006d/comments", + "author": { + "login": "wlynch", + "id": 1844673, + "node_id": "MDQ6VXNlcjE4NDQ2NzM=", + "avatar_url": "https://avatars.githubusercontent.com/u/1844673?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/wlynch", + "html_url": "https://github.com/wlynch", + "followers_url": "https://api.github.com/users/wlynch/followers", + "following_url": "https://api.github.com/users/wlynch/following{/other_user}", + "gists_url": "https://api.github.com/users/wlynch/gists{/gist_id}", + "starred_url": "https://api.github.com/users/wlynch/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/wlynch/subscriptions", + "organizations_url": "https://api.github.com/users/wlynch/orgs", + "repos_url": "https://api.github.com/users/wlynch/repos", + "events_url": "https://api.github.com/users/wlynch/events{/privacy}", + "received_events_url": "https://api.github.com/users/wlynch/received_events", + "type": "User", + "site_admin": false + }, + "committer": { + "login": "web-flow", + "id": 19864447, + "node_id": "MDQ6VXNlcjE5ODY0NDQ3", + "avatar_url": "https://avatars.githubusercontent.com/u/19864447?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/web-flow", + "html_url": "https://github.com/web-flow", + "followers_url": "https://api.github.com/users/web-flow/followers", + "following_url": "https://api.github.com/users/web-flow/following{/other_user}", + "gists_url": "https://api.github.com/users/web-flow/gists{/gist_id}", + "starred_url": "https://api.github.com/users/web-flow/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/web-flow/subscriptions", + "organizations_url": "https://api.github.com/users/web-flow/orgs", + "repos_url": "https://api.github.com/users/web-flow/repos", + "events_url": "https://api.github.com/users/web-flow/events{/privacy}", + "received_events_url": "https://api.github.com/users/web-flow/received_events", + "type": "User", + "site_admin": false + }, + "parents": [ + { + "sha": "a3d5fd86ce35211a5312a60bc5bdd44ecc426bfa", + "url": "https://api.github.com/repos/chainguard-dev/wlynch-test/commits/a3d5fd86ce35211a5312a60bc5bdd44ecc426bfa", + "html_url": "https://github.com/chainguard-dev/wlynch-test/commit/a3d5fd86ce35211a5312a60bc5bdd44ecc426bfa" + } + ] + }, + "merge_base_commit": { + "sha": "306e576f9026d6afb4baa812df3dd538c35c006d", + "node_id": "C_kwDOHUbyj9oAKDMwNmU1NzZmOTAyNmQ2YWZiNGJhYTgxMmRmM2RkNTM4YzM1YzAwNmQ", + "commit": { + "author": { + "name": "Billy Lynch", + "email": "1844673+wlynch@users.noreply.github.com", + "date": "2024-09-03T18:26:21Z" + }, + "committer": { + "name": "GitHub", + "email": "noreply@github.com", + "date": "2024-09-03T18:26:21Z" + }, + "message": "Create test.sts.yaml\n\nSigned-off-by: Billy Lynch <1844673+wlynch@users.noreply.github.com>", + "tree": { + "sha": "51c2ca22e725d908da339f40c38a78ab10c69b7e", + "url": "https://api.github.com/repos/chainguard-dev/wlynch-test/git/trees/51c2ca22e725d908da339f40c38a78ab10c69b7e" + }, + "url": "https://api.github.com/repos/chainguard-dev/wlynch-test/git/commits/306e576f9026d6afb4baa812df3dd538c35c006d", + "comment_count": 0, + "verification": { + "verified": true, + "reason": "valid", + "signature": "-----BEGIN PGP SIGNATURE-----\n\nwsFcBAABCAAQBQJm11TNCRC1aQ7uu5UhlAAAvjIQAAYWvoNzlNBOftmCWDdlRD7/\nFpbzoLMAXpuVVh/pPJvfN04ywtmwbDRHDD+Tu7qHHDHe4dyYrqmCT94e5/4kJAtg\ngrhsXhSJQQNOsZTDXV28E7mMKTXUGa1ewB8d6mmhTAWQTuMpCVzWXlUa3qauMP1F\niih49n1YxVLSUFz+U1C/NeacWJC2pGcsLs3lZSmeTQ0kF2i6iFkQyYSVv4uDhUCt\n4iktN3nZY9WhQQ3ucWMQhqk4iNkg9Cusw8pXYMd5V09DQJhNInkjiril55kk8dow\nCfaF5zdPdbWKEPJNvq3Jp7cBuEbGz74TQPkK9OBE4P+GRZu0C0u/fSv63ifXL9W0\nQKh2NXUljmsZ4kmrDla4wWEU4Hdr+r6nmpxRWCUGzOhAgqIQWLE+xW/NF6XodXBK\nfUWh1jfRszbsesC6OdBjsqiqsznCSLhPXZ7XBdJvpf4NzDxBtqn2O0ajfzM8OZRA\n7n+DhC7RiFUKIONapiTFicrz7ZQBRxTJQkcm+ics6hykpvdaN3f6sz2y6apw5OD1\ng55rjcN3lm+36KUI/hE0CGMrYcTAq59KIdYwUE2Sq8NuE2PBv94zOd1Xdud8ryuk\nJVxUG/sOaRP33zYD/VHxR1VN5PDzgSqWqFNPlv8T3cJ0bh/q2WJHoqyMNubZdS/8\nL8t06DSWGSSjZdNuUVdW\n=QFtw\n-----END PGP SIGNATURE-----\n", + "payload": "tree 51c2ca22e725d908da339f40c38a78ab10c69b7e\nparent a3d5fd86ce35211a5312a60bc5bdd44ecc426bfa\nauthor Billy Lynch <1844673+wlynch@users.noreply.github.com> 1725387981 -0400\ncommitter GitHub 1725387981 -0400\n\nCreate test.sts.yaml\n\nSigned-off-by: Billy Lynch <1844673+wlynch@users.noreply.github.com>" + } + }, + "url": "https://api.github.com/repos/chainguard-dev/wlynch-test/commits/306e576f9026d6afb4baa812df3dd538c35c006d", + "html_url": "https://github.com/chainguard-dev/wlynch-test/commit/306e576f9026d6afb4baa812df3dd538c35c006d", + "comments_url": "https://api.github.com/repos/chainguard-dev/wlynch-test/commits/306e576f9026d6afb4baa812df3dd538c35c006d/comments", + "author": { + "login": "wlynch", + "id": 1844673, + "node_id": "MDQ6VXNlcjE4NDQ2NzM=", + "avatar_url": "https://avatars.githubusercontent.com/u/1844673?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/wlynch", + "html_url": "https://github.com/wlynch", + "followers_url": "https://api.github.com/users/wlynch/followers", + "following_url": "https://api.github.com/users/wlynch/following{/other_user}", + "gists_url": "https://api.github.com/users/wlynch/gists{/gist_id}", + "starred_url": "https://api.github.com/users/wlynch/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/wlynch/subscriptions", + "organizations_url": "https://api.github.com/users/wlynch/orgs", + "repos_url": "https://api.github.com/users/wlynch/repos", + "events_url": "https://api.github.com/users/wlynch/events{/privacy}", + "received_events_url": "https://api.github.com/users/wlynch/received_events", + "type": "User", + "site_admin": false + }, + "committer": { + "login": "web-flow", + "id": 19864447, + "node_id": "MDQ6VXNlcjE5ODY0NDQ3", + "avatar_url": "https://avatars.githubusercontent.com/u/19864447?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/web-flow", + "html_url": "https://github.com/web-flow", + "followers_url": "https://api.github.com/users/web-flow/followers", + "following_url": "https://api.github.com/users/web-flow/following{/other_user}", + "gists_url": "https://api.github.com/users/web-flow/gists{/gist_id}", + "starred_url": "https://api.github.com/users/web-flow/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/web-flow/subscriptions", + "organizations_url": "https://api.github.com/users/web-flow/orgs", + "repos_url": "https://api.github.com/users/web-flow/repos", + "events_url": "https://api.github.com/users/web-flow/events{/privacy}", + "received_events_url": "https://api.github.com/users/web-flow/received_events", + "type": "User", + "site_admin": false + }, + "parents": [ + { + "sha": "a3d5fd86ce35211a5312a60bc5bdd44ecc426bfa", + "url": "https://api.github.com/repos/chainguard-dev/wlynch-test/commits/a3d5fd86ce35211a5312a60bc5bdd44ecc426bfa", + "html_url": "https://github.com/chainguard-dev/wlynch-test/commit/a3d5fd86ce35211a5312a60bc5bdd44ecc426bfa" + } + ] + }, + "status": "ahead", + "ahead_by": 3, + "behind_by": 0, + "total_commits": 3, + "commits": [ + { + "sha": "ec5f20ca49dddf140fec315b97eb1e00cec2510c", + "node_id": "C_kwDOHUbyj9oAKGVjNWYyMGNhNDlkZGRmMTQwZmVjMzE1Yjk3ZWIxZTAwY2VjMjUxMGM", + "commit": { + "author": { + "name": "Billy Lynch", + "email": "1844673+wlynch@users.noreply.github.com", + "date": "2024-09-03T18:36:30Z" + }, + "committer": { + "name": "GitHub", + "email": "noreply@github.com", + "date": "2024-09-03T18:36:30Z" + }, + "message": "Update test.sts.yaml\n\nSigned-off-by: Billy Lynch <1844673+wlynch@users.noreply.github.com>", + "tree": { + "sha": "695af171c215d1a82afa7e045d3589ad5fee39a6", + "url": "https://api.github.com/repos/chainguard-dev/wlynch-test/git/trees/695af171c215d1a82afa7e045d3589ad5fee39a6" + }, + "url": "https://api.github.com/repos/chainguard-dev/wlynch-test/git/commits/ec5f20ca49dddf140fec315b97eb1e00cec2510c", + "comment_count": 0, + "verification": { + "verified": true, + "reason": "valid", + "signature": "-----BEGIN PGP SIGNATURE-----\n\nwsFcBAABCAAQBQJm11cuCRC1aQ7uu5UhlAAAEF4QALEIzqZg5sd2aV5ihQiNyph5\npHvm0PDdyMiZUjJt3dC/abIkcWcUFoCVPRvhmIs6/PPAtxOGNhobjzSCb6LTADNM\nXwaTbDFuB8C+p27u1q++gEHxCc476ZZ8MA/YRUndPYznZcUHiRdS3MkW+E5Wuv3a\nLCh8k5/JO/q3n/UtlyPyBa1Ogq/DWIn5wyOEERXfsAmOp7vZOM8E2C4743qrhzbI\nqdgDcGAVP88/ujP49HlQHQnCub3WkY683WOb45LjjvpoZgWkJkf0n+xZ08eCwp38\nwuUm3XHXRNT4IuuPJbc0BKwCvLJTuSIg8w8jdgdu5ix9UcrSOgHK8tNg9bGPd/PF\nz0OoEizaHdIWtBe09ag7WUmVzOLR370sjdADkEoTyUwd/Ad50XO3Vh5EWaEMiSrq\nT04tt5tFbv5rwH5Dl8RaDOag5zmkGFqQD4BhfXykNLW4Vbu3+518cjyEyzj3xpyu\nIL/xpzPPT8DtqoFdMFsgB5JOLkjB3LH43eVWhGcCaaMBdzUs+qoramOL1NSQC442\nRs8MCz0AGWPQQ5Ucc+JsAPwmf8/YuDDSX+gah4CpzPBH0KsEpAOAICmcogXfNG/k\n9DlBTiC1E1NRjtFlASdgt4P5TzQoZoqvmary2sphcoqs6o+sENc/zIrY/4gFj+KG\nM3AAIQrdvzXBP/KgvFVv\n=3hqu\n-----END PGP SIGNATURE-----\n", + "payload": "tree 695af171c215d1a82afa7e045d3589ad5fee39a6\nparent 306e576f9026d6afb4baa812df3dd538c35c006d\nauthor Billy Lynch <1844673+wlynch@users.noreply.github.com> 1725388590 -0400\ncommitter GitHub 1725388590 -0400\n\nUpdate test.sts.yaml\n\nSigned-off-by: Billy Lynch <1844673+wlynch@users.noreply.github.com>" + } + }, + "url": "https://api.github.com/repos/chainguard-dev/wlynch-test/commits/ec5f20ca49dddf140fec315b97eb1e00cec2510c", + "html_url": "https://github.com/chainguard-dev/wlynch-test/commit/ec5f20ca49dddf140fec315b97eb1e00cec2510c", + "comments_url": "https://api.github.com/repos/chainguard-dev/wlynch-test/commits/ec5f20ca49dddf140fec315b97eb1e00cec2510c/comments", + "author": { + "login": "wlynch", + "id": 1844673, + "node_id": "MDQ6VXNlcjE4NDQ2NzM=", + "avatar_url": "https://avatars.githubusercontent.com/u/1844673?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/wlynch", + "html_url": "https://github.com/wlynch", + "followers_url": "https://api.github.com/users/wlynch/followers", + "following_url": "https://api.github.com/users/wlynch/following{/other_user}", + "gists_url": "https://api.github.com/users/wlynch/gists{/gist_id}", + "starred_url": "https://api.github.com/users/wlynch/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/wlynch/subscriptions", + "organizations_url": "https://api.github.com/users/wlynch/orgs", + "repos_url": "https://api.github.com/users/wlynch/repos", + "events_url": "https://api.github.com/users/wlynch/events{/privacy}", + "received_events_url": "https://api.github.com/users/wlynch/received_events", + "type": "User", + "site_admin": false + }, + "committer": { + "login": "web-flow", + "id": 19864447, + "node_id": "MDQ6VXNlcjE5ODY0NDQ3", + "avatar_url": "https://avatars.githubusercontent.com/u/19864447?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/web-flow", + "html_url": "https://github.com/web-flow", + "followers_url": "https://api.github.com/users/web-flow/followers", + "following_url": "https://api.github.com/users/web-flow/following{/other_user}", + "gists_url": "https://api.github.com/users/web-flow/gists{/gist_id}", + "starred_url": "https://api.github.com/users/web-flow/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/web-flow/subscriptions", + "organizations_url": "https://api.github.com/users/web-flow/orgs", + "repos_url": "https://api.github.com/users/web-flow/repos", + "events_url": "https://api.github.com/users/web-flow/events{/privacy}", + "received_events_url": "https://api.github.com/users/web-flow/received_events", + "type": "User", + "site_admin": false + }, + "parents": [ + { + "sha": "306e576f9026d6afb4baa812df3dd538c35c006d", + "url": "https://api.github.com/repos/chainguard-dev/wlynch-test/commits/306e576f9026d6afb4baa812df3dd538c35c006d", + "html_url": "https://github.com/chainguard-dev/wlynch-test/commit/306e576f9026d6afb4baa812df3dd538c35c006d" + } + ] + }, + { + "sha": "875521ccd705857d0223213c464cab39d5c5431f", + "node_id": "C_kwDOHUbyj9oAKDg3NTUyMWNjZDcwNTg1N2QwMjIzMjEzYzQ2NGNhYjM5ZDVjNTQzMWY", + "commit": { + "author": { + "name": "Billy Lynch", + "email": "1844673+wlynch@users.noreply.github.com", + "date": "2024-09-03T19:23:21Z" + }, + "committer": { + "name": "GitHub", + "email": "noreply@github.com", + "date": "2024-09-03T19:23:21Z" + }, + "message": "Update test.sts.yaml\n\nSigned-off-by: Billy Lynch <1844673+wlynch@users.noreply.github.com>", + "tree": { + "sha": "13f2829a9d0a2348abddadcc9460492d03d637a6", + "url": "https://api.github.com/repos/chainguard-dev/wlynch-test/git/trees/13f2829a9d0a2348abddadcc9460492d03d637a6" + }, + "url": "https://api.github.com/repos/chainguard-dev/wlynch-test/git/commits/875521ccd705857d0223213c464cab39d5c5431f", + "comment_count": 0, + "verification": { + "verified": true, + "reason": "valid", + "signature": "-----BEGIN PGP SIGNATURE-----\n\nwsFcBAABCAAQBQJm12IpCRC1aQ7uu5UhlAAALB8QAEDlJ1+3K0QJlpQyQgXA7qlH\netd7xrjOdigvGtq6z6H86eTyMYO7QTApTAAKh6U6H0yLTylQglu2AUaLeE+1Nri+\neOkqkn2bVxqZFzRxdkMFLTEgLbMkQM1LFfKEaB3OVRfFbE9Tsec4rpB9SX/segfv\ns+CVFYz6S+xATwXEf59FZnJ24xHihMGp4eQBighf6H0uReroDgVb4IBnTt8b31iX\nNPDI6ZYilZYVc+BCmMbDHOZvHfoRbassCdYkAzGZVbC2pYZr7elWXJx98XRPiJrB\ncFgmCiUQ0Wv7q2G/0zrADcKe6k72JWPiG5R3JUK0hK5dRmAx+mLvMn0huy3YMTxW\nGA7uPzGFs7J98cjcgRoihW3mqYXt9EfOEjhQpv+3mO38JHsMuxgouf4djE5sF8OL\nlsT4V5UdF6TEX1tQMKuaN4rx4KOa5T0T5CYQ9IjZR7fjRnboG3uUBKRMvvmnIL1z\nbT8c1vsW55C2E8/rDfowlIsfMOmD2Y6/VS9RINpjebSNLRz5M2w4kR8JcF5wP1Wd\nNiuRIDghX7JqCr3EDrNZQl2j6LJskcFJ6NcEVpyAw5Q6yGJIKyApKq2F0S0idTyr\nnqa//MP9yJ+1yFJlFrTRM80jazTd8yQws2WvhS3lE109r6NSMdklWXKFL9SYfOGj\nmqoq2H2ia201ri/DwPjm\n=8xs5\n-----END PGP SIGNATURE-----\n", + "payload": "tree 13f2829a9d0a2348abddadcc9460492d03d637a6\nparent ec5f20ca49dddf140fec315b97eb1e00cec2510c\nauthor Billy Lynch <1844673+wlynch@users.noreply.github.com> 1725391401 -0400\ncommitter GitHub 1725391401 -0400\n\nUpdate test.sts.yaml\n\nSigned-off-by: Billy Lynch <1844673+wlynch@users.noreply.github.com>" + } + }, + "url": "https://api.github.com/repos/chainguard-dev/wlynch-test/commits/875521ccd705857d0223213c464cab39d5c5431f", + "html_url": "https://github.com/chainguard-dev/wlynch-test/commit/875521ccd705857d0223213c464cab39d5c5431f", + "comments_url": "https://api.github.com/repos/chainguard-dev/wlynch-test/commits/875521ccd705857d0223213c464cab39d5c5431f/comments", + "author": { + "login": "wlynch", + "id": 1844673, + "node_id": "MDQ6VXNlcjE4NDQ2NzM=", + "avatar_url": "https://avatars.githubusercontent.com/u/1844673?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/wlynch", + "html_url": "https://github.com/wlynch", + "followers_url": "https://api.github.com/users/wlynch/followers", + "following_url": "https://api.github.com/users/wlynch/following{/other_user}", + "gists_url": "https://api.github.com/users/wlynch/gists{/gist_id}", + "starred_url": "https://api.github.com/users/wlynch/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/wlynch/subscriptions", + "organizations_url": "https://api.github.com/users/wlynch/orgs", + "repos_url": "https://api.github.com/users/wlynch/repos", + "events_url": "https://api.github.com/users/wlynch/events{/privacy}", + "received_events_url": "https://api.github.com/users/wlynch/received_events", + "type": "User", + "site_admin": false + }, + "committer": { + "login": "web-flow", + "id": 19864447, + "node_id": "MDQ6VXNlcjE5ODY0NDQ3", + "avatar_url": "https://avatars.githubusercontent.com/u/19864447?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/web-flow", + "html_url": "https://github.com/web-flow", + "followers_url": "https://api.github.com/users/web-flow/followers", + "following_url": "https://api.github.com/users/web-flow/following{/other_user}", + "gists_url": "https://api.github.com/users/web-flow/gists{/gist_id}", + "starred_url": "https://api.github.com/users/web-flow/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/web-flow/subscriptions", + "organizations_url": "https://api.github.com/users/web-flow/orgs", + "repos_url": "https://api.github.com/users/web-flow/repos", + "events_url": "https://api.github.com/users/web-flow/events{/privacy}", + "received_events_url": "https://api.github.com/users/web-flow/received_events", + "type": "User", + "site_admin": false + }, + "parents": [ + { + "sha": "ec5f20ca49dddf140fec315b97eb1e00cec2510c", + "url": "https://api.github.com/repos/chainguard-dev/wlynch-test/commits/ec5f20ca49dddf140fec315b97eb1e00cec2510c", + "html_url": "https://github.com/chainguard-dev/wlynch-test/commit/ec5f20ca49dddf140fec315b97eb1e00cec2510c" + } + ] + }, + { + "sha": "77d49996a5b88ff14fa57eb9094a0316d23b7537", + "node_id": "C_kwDOHUbyj9oAKDc3ZDQ5OTk2YTViODhmZjE0ZmE1N2ViOTA5NGEwMzE2ZDIzYjc1Mzc", + "commit": { + "author": { + "name": "Billy Lynch", + "email": "1844673+wlynch@users.noreply.github.com", + "date": "2024-09-03T21:11:04Z" + }, + "committer": { + "name": "GitHub", + "email": "noreply@github.com", + "date": "2024-09-03T21:11:04Z" + }, + "message": "Update test.sts.yaml\n\nSigned-off-by: Billy Lynch <1844673+wlynch@users.noreply.github.com>", + "tree": { + "sha": "733d1ebc10535291c48eda45872f65c73b9e019a", + "url": "https://api.github.com/repos/chainguard-dev/wlynch-test/git/trees/733d1ebc10535291c48eda45872f65c73b9e019a" + }, + "url": "https://api.github.com/repos/chainguard-dev/wlynch-test/git/commits/77d49996a5b88ff14fa57eb9094a0316d23b7537", + "comment_count": 0, + "verification": { + "verified": true, + "reason": "valid", + "signature": "-----BEGIN PGP SIGNATURE-----\n\nwsFcBAABCAAQBQJm13tpCRC1aQ7uu5UhlAAAKQYQACiAsy3C36c7kwZA0corgWa4\n+F9EQviJ/ZUunwzWpkE/Yj/n3TinyZbrXRnAah1i1EErhfoJ4G0g+Nir4GcEekOs\nonq+y8Me9ZxSxrefi1aOclqx0BPyYuhplhKt0T3i1jUvvCWWsCVraCy3AF/bUMyv\nv8oDl5k6lmNE+ZMxMSiSpx9un9iscmKy8schSXzLQDvuBodhdlWTfTlOmTBZOMtn\nbekPTV4Y3Wg0YoXeEbnf2s3QGTaXCm7Df593SlmEul/tX7i8BteBx66idFhMZ9Jg\n4QYOownYTIhT1gnoRmkIMiE7Uxc+DG0Wtj0sCKSIR4YLcj33EH57DAaC45LHlZzU\nc3sxQb0dy81DAawdCh6EgioeKFJFJoBc+BKPeGI2qWywRea9rzMiz27Aft691DYi\nQU6DIG8RvUU8lqC38zBry9NvnTeT0IrpxQhZ7GNKIlbWNty0WOz8vudHBBkrwhgR\nMtv7GvE+nducvmRdDPBVxFbWvZEH8ZYlzN7GWdUgiV/SzEJt02kuuOdhKVRgHZ38\n0AUs1A3YnSVhOL/284Ns11uHi/55PMJqywWxjEtrGQbI2F4yrZ1BlI1UoiXEp3yY\nuio4Bli8glvCkkVQ5AF1dgSVNloQh6tMHiz8sLn3/FSJTY9wqHnS0FxBLEMcyLzl\nW1dePrhYnNUz+npJJmW6\n=WWdO\n-----END PGP SIGNATURE-----\n", + "payload": "tree 733d1ebc10535291c48eda45872f65c73b9e019a\nparent 875521ccd705857d0223213c464cab39d5c5431f\nauthor Billy Lynch <1844673+wlynch@users.noreply.github.com> 1725397864 -0400\ncommitter GitHub 1725397864 -0400\n\nUpdate test.sts.yaml\n\nSigned-off-by: Billy Lynch <1844673+wlynch@users.noreply.github.com>" + } + }, + "url": "https://api.github.com/repos/chainguard-dev/wlynch-test/commits/77d49996a5b88ff14fa57eb9094a0316d23b7537", + "html_url": "https://github.com/chainguard-dev/wlynch-test/commit/77d49996a5b88ff14fa57eb9094a0316d23b7537", + "comments_url": "https://api.github.com/repos/chainguard-dev/wlynch-test/commits/77d49996a5b88ff14fa57eb9094a0316d23b7537/comments", + "author": { + "login": "wlynch", + "id": 1844673, + "node_id": "MDQ6VXNlcjE4NDQ2NzM=", + "avatar_url": "https://avatars.githubusercontent.com/u/1844673?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/wlynch", + "html_url": "https://github.com/wlynch", + "followers_url": "https://api.github.com/users/wlynch/followers", + "following_url": "https://api.github.com/users/wlynch/following{/other_user}", + "gists_url": "https://api.github.com/users/wlynch/gists{/gist_id}", + "starred_url": "https://api.github.com/users/wlynch/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/wlynch/subscriptions", + "organizations_url": "https://api.github.com/users/wlynch/orgs", + "repos_url": "https://api.github.com/users/wlynch/repos", + "events_url": "https://api.github.com/users/wlynch/events{/privacy}", + "received_events_url": "https://api.github.com/users/wlynch/received_events", + "type": "User", + "site_admin": false + }, + "committer": { + "login": "web-flow", + "id": 19864447, + "node_id": "MDQ6VXNlcjE5ODY0NDQ3", + "avatar_url": "https://avatars.githubusercontent.com/u/19864447?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/web-flow", + "html_url": "https://github.com/web-flow", + "followers_url": "https://api.github.com/users/web-flow/followers", + "following_url": "https://api.github.com/users/web-flow/following{/other_user}", + "gists_url": "https://api.github.com/users/web-flow/gists{/gist_id}", + "starred_url": "https://api.github.com/users/web-flow/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/web-flow/subscriptions", + "organizations_url": "https://api.github.com/users/web-flow/orgs", + "repos_url": "https://api.github.com/users/web-flow/repos", + "events_url": "https://api.github.com/users/web-flow/events{/privacy}", + "received_events_url": "https://api.github.com/users/web-flow/received_events", + "type": "User", + "site_admin": false + }, + "parents": [ + { + "sha": "875521ccd705857d0223213c464cab39d5c5431f", + "url": "https://api.github.com/repos/chainguard-dev/wlynch-test/commits/875521ccd705857d0223213c464cab39d5c5431f", + "html_url": "https://github.com/chainguard-dev/wlynch-test/commit/875521ccd705857d0223213c464cab39d5c5431f" + } + ] + } + ], + "files": [ + { + "sha": "8a5b8bd985920c84d8fbcf3e04366b679e412b06", + "filename": ".github/chainguard/test.sts.yaml", + "status": "modified", + "additions": 1, + "deletions": 0, + "changes": 1, + "blob_url": "https://github.com/chainguard-dev/wlynch-test/blob/77d49996a5b88ff14fa57eb9094a0316d23b7537/.github%2Fchainguard%2Ftest.sts.yaml", + "raw_url": "https://github.com/chainguard-dev/wlynch-test/raw/77d49996a5b88ff14fa57eb9094a0316d23b7537/.github%2Fchainguard%2Ftest.sts.yaml", + "contents_url": "https://api.github.com/repos/chainguard-dev/wlynch-test/contents/.github%2Fchainguard%2Ftest.sts.yaml?ref=77d49996a5b88ff14fa57eb9094a0316d23b7537", + "patch": "@@ -1,3 +1,4 @@\n+# asdf asdfas\n issuer: https://accounts.google.com\n subject_pattern: '[0-9]+'\n claim_pattern:" + } + ] +} diff --git a/pkg/webhook/testdata/api/v3/repos/foo/bar/contents/policy.json b/pkg/webhook/testdata/api/v3/repos/foo/bar/contents/.github/chainguard/test.sts.yaml similarity index 100% rename from pkg/webhook/testdata/api/v3/repos/foo/bar/contents/policy.json rename to pkg/webhook/testdata/api/v3/repos/foo/bar/contents/.github/chainguard/test.sts.yaml diff --git a/pkg/webhook/testdata/app/installations/1111/access_tokens b/pkg/webhook/testdata/app/installations/1111/access_tokens new file mode 100644 index 0000000..f2b71d4 --- /dev/null +++ b/pkg/webhook/testdata/app/installations/1111/access_tokens @@ -0,0 +1,71 @@ +{ + "id": 1, + "url": "https://api.github.com/authorizations/1", + "scopes": [], + "token": "ghu_16C7e42F292c6912E7710c838347Ae178B4a", + "token_last_eight": "Ae178B4a", + "hashed_token": "25f94a2a5c7fbaf499c665bc73d67c1c87e496da8985131633ee0a95819db2e8", + "app": { + "url": "http://my-github-app.com", + "name": "my github app", + "client_id": "Iv1.8a61f9b3a7aba766" + }, + "note": "optional note", + "note_url": "http://optional/note/url", + "updated_at": "2011-09-06T20:39:23Z", + "created_at": "2011-09-06T17:26:27Z", + "fingerprint": "jklmnop12345678", + "expires_at": "2011-09-08T17:26:27Z", + "user": { + "login": "octocat", + "id": 1, + "node_id": "MDQ6VXNlcjE=", + "avatar_url": "https://github.com/images/error/octocat_happy.gif", + "gravatar_id": "", + "url": "https://api.github.com/users/octocat", + "html_url": "https://github.com/octocat", + "followers_url": "https://api.github.com/users/octocat/followers", + "following_url": "https://api.github.com/users/octocat/following{/other_user}", + "gists_url": "https://api.github.com/users/octocat/gists{/gist_id}", + "starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/octocat/subscriptions", + "organizations_url": "https://api.github.com/users/octocat/orgs", + "repos_url": "https://api.github.com/users/octocat/repos", + "events_url": "https://api.github.com/users/octocat/events{/privacy}", + "received_events_url": "https://api.github.com/users/octocat/received_events", + "type": "User", + "site_admin": false + }, + "installation": { + "permissions": { + "metadata": "read", + "issues": "write", + "contents": "read" + }, + "repository_selection": "selected", + "single_file_name": ".github/workflow.yml", + "repositories_url": "https://api.github.com/user/repos", + "account": { + "login": "octocat", + "id": 1, + "node_id": "MDQ6VXNlcjE=", + "avatar_url": "https://github.com/images/error/octocat_happy.gif", + "gravatar_id": "", + "url": "https://api.github.com/users/octocat", + "html_url": "https://github.com/octocat", + "followers_url": "https://api.github.com/users/octocat/followers", + "following_url": "https://api.github.com/users/octocat/following{/other_user}", + "gists_url": "https://api.github.com/users/octocat/gists{/gist_id}", + "starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/octocat/subscriptions", + "organizations_url": "https://api.github.com/users/octocat/orgs", + "repos_url": "https://api.github.com/users/octocat/repos", + "events_url": "https://api.github.com/users/octocat/events{/privacy}", + "received_events_url": "https://api.github.com/users/octocat/received_events", + "type": "User", + "site_admin": false + }, + "has_multiple_single_files": false, + "single_file_paths": [] + } +} diff --git a/pkg/webhook/webhook.go b/pkg/webhook/webhook.go index 83f7028..00d36bf 100644 --- a/pkg/webhook/webhook.go +++ b/pkg/webhook/webhook.go @@ -136,13 +136,14 @@ func (e *Validator) handleSHA(ctx context.Context, client *github.Client, owner, // Whether or not the commit is verified, we still create a CheckRun. // The only difference is whether it shows up to the user as success or // failure. - var conclusion, title string + var conclusion, title, summary string if err == nil { conclusion = "success" title = "Valid trust policy." } else { conclusion = "failure" title = "Invalid trust policy." + summary = "Failed to validate trust policy.\n\n" + err.Error() } opts := github.CreateCheckRunOptions{ @@ -155,7 +156,7 @@ func (e *Validator) handleSHA(ctx context.Context, client *github.Client, owner, CompletedAt: &github.Timestamp{Time: time.Now()}, Output: &github.CheckRunOutput{ Title: github.String(title), - Summary: github.String(err.Error()), + Summary: github.String(summary), }, } @@ -229,6 +230,13 @@ func (e *Validator) handlePush(ctx context.Context, event *github.PushEvent) (*g client := github.NewClient(&http.Client{ Transport: ghinstallation.NewFromAppsTransport(e.Transport, installationID), }) + if e.Transport.BaseURL != "" { + var err error + client, err = client.WithEnterpriseURLs(e.Transport.BaseURL, e.Transport.BaseURL) + if err != nil { + return nil, err + } + } // Check diff // TODO: Pagination? @@ -236,6 +244,7 @@ func (e *Validator) handlePush(ctx context.Context, event *github.PushEvent) (*g if err != nil { return nil, err } + log.Infof("%+v\n%+v", resp, resp.Files) var files []string for _, file := range resp.Files { if ok, err := filepath.Match(".github/chainguard/*.sts.yaml", file.GetFilename()); err == nil && ok { @@ -274,6 +283,13 @@ func (e *Validator) handlePullRequest(ctx context.Context, pr *github.PullReques client := github.NewClient(&http.Client{ Transport: ghinstallation.NewFromAppsTransport(e.Transport, installationID), }) + if e.Transport.BaseURL != "" { + var err error + client, err = client.WithEnterpriseURLs(e.Transport.BaseURL, e.Transport.BaseURL) + if err != nil { + return nil, err + } + } // Check diff var files []string @@ -327,6 +343,13 @@ func (e *Validator) handleCheckSuite(ctx context.Context, cs checkSuite) (*githu client := github.NewClient(&http.Client{ Transport: ghinstallation.NewFromAppsTransport(e.Transport, installationID), }) + if e.Transport.BaseURL != "" { + var err error + client, err = client.WithEnterpriseURLs(e.Transport.BaseURL, e.Transport.BaseURL) + if err != nil { + return nil, err + } + } var files []string if cs.GetCheckSuite().GetBeforeSHA() == zeroHash { diff --git a/pkg/webhook/webhook_test.go b/pkg/webhook/webhook_test.go index bfb14e0..c76aed5 100644 --- a/pkg/webhook/webhook_test.go +++ b/pkg/webhook/webhook_test.go @@ -21,7 +21,9 @@ import ( "testing" "github.com/bradleyfalzon/ghinstallation/v2" + "github.com/chainguard-dev/clog" "github.com/chainguard-dev/clog/slogtest" + "github.com/google/go-cmp/cmp" "github.com/google/go-github/v61/github" ) @@ -47,7 +49,7 @@ func TestValidatePolicy(t *testing.T) { t.Fatal(err) } ctx := slogtest.TestContextWithLogger(t) - if err := validatePolicies(ctx, gh, "foo", "bar", "deadbeef", []string{"policy.json"}); err != nil { + if err := validatePolicies(ctx, gh, "foo", "bar", "deadbeef", []string{".github/chainguard/test.sts.yaml"}); err != nil { t.Fatal(err) } } @@ -74,7 +76,6 @@ func TestOrgFilter(t *testing.T) { WebhookSecret: [][]byte{secret}, Organizations: []string{"foo"}, } - srv := httptest.NewServer(v) defer srv.Close() @@ -127,3 +128,109 @@ func signature(secret, body []byte) string { return fmt.Sprintf("sha256=%s", hex.EncodeToString(b)) } + +func TestWebhookOK(t *testing.T) { + // CheckRuns will be collected here. + got := []*github.CreateCheckRunOptions{} + + mux := http.NewServeMux() + mux.HandleFunc("POST /api/v3/repos/foo/bar/check-runs", func(w http.ResponseWriter, r *http.Request) { + opt := new(github.CreateCheckRunOptions) + if err := json.NewDecoder(r.Body).Decode(opt); err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + got = append(got, opt) + }) + mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + path := filepath.Join("testdata", r.URL.Path) + f, err := os.Open(path) + if err != nil { + clog.FromContext(r.Context()).Errorf("%s not found", path) + http.Error(w, err.Error(), http.StatusNotFound) + return + } + defer f.Close() + if _, err := io.Copy(w, f); err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + }) + gh := httptest.NewServer(mux) + defer gh.Close() + + key, err := rsa.GenerateKey(rand.Reader, 2048) + if err != nil { + t.Fatal(err) + } + tr := ghinstallation.NewAppsTransportFromPrivateKey(gh.Client().Transport, 1234, key) + if err != nil { + t.Fatal(err) + } + tr.BaseURL = gh.URL + + secret := []byte("hunter2") + v := &Validator{ + Transport: tr, + WebhookSecret: [][]byte{secret}, + } + srv := httptest.NewServer(v) + defer srv.Close() + + body, err := json.Marshal(github.PushEvent{ + Installation: &github.Installation{ + ID: github.Int64(1111), + }, + Organization: &github.Organization{ + Login: github.String("foo"), + }, + Repo: &github.PushEventRepository{ + Owner: &github.User{ + Login: github.String("foo"), + }, + Name: github.String("bar"), + }, + Before: github.String("1234"), + After: github.String("5678"), + }) + if err != nil { + t.Fatal(err) + } + req, err := http.NewRequest(http.MethodPost, srv.URL, bytes.NewBuffer(body)) + if err != nil { + t.Fatal(err) + } + req.Header.Set("X-Hub-Signature", signature(secret, body)) + req.Header.Set("X-GitHub-Event", "push") + req.Header.Set("Content-Type", "application/json") + resp, err := srv.Client().Do(req.WithContext(slogtest.TestContextWithLogger(t))) + if err != nil { + t.Fatal(err) + } + if resp.StatusCode != 200 { + out, _ := httputil.DumpResponse(resp, true) + t.Fatalf("expected %d, got\n%s", 200, string(out)) + } + + if len(got) != 1 { + t.Fatalf("expected 1 check run, got %d", len(got)) + } + + want := []*github.CreateCheckRunOptions{{ + Name: "Trust Policy Validation", + HeadSHA: "5678", + ExternalID: github.String("5678"), + Status: github.String("completed"), + Conclusion: github.String("success"), + // Use time from the response to ignore it. + StartedAt: &github.Timestamp{Time: got[0].StartedAt.Time}, + CompletedAt: &github.Timestamp{Time: got[0].CompletedAt.Time}, + Output: &github.CheckRunOutput{ + Title: github.String("Valid trust policy."), + Summary: github.String(""), + }, + }} + if diff := cmp.Diff(want, got); diff != "" { + t.Fatalf("unexpected check run (-want +got):\n%s", diff) + } +}