├── .circleci └── config.yml ├── .gitignore ├── .prettierignore ├── .prettierrc ├── .vscode ├── extensions.json └── settings.json ├── CHANGELOG.md ├── Dockerfile ├── LICENSE ├── README.md ├── VISION.md ├── api ├── .babelrc ├── .dockerignore ├── .env.sample ├── Brewfile ├── README.md ├── bin │ └── lambda.zip ├── dangerfile.lite.ts ├── docker-compose.yml ├── now.staging.json ├── package.json ├── public │ └── index.html ├── scripts │ ├── deploy-staging-api.sh │ ├── deploy-staging-layer.sh │ ├── deploy-staging-runner.sh │ └── trim_node_modules.sh ├── source │ ├── ambient.d.ts │ ├── api │ │ ├── _tests │ │ │ └── fixtureAPI.ts │ │ ├── api.ts │ │ ├── auth │ │ │ ├── _tests │ │ │ │ └── _generate.test.ts │ │ │ ├── generate.ts │ │ │ ├── getJWTFromRequest.ts │ │ │ └── github.ts │ │ ├── aws │ │ │ └── lambda.ts │ │ ├── fetch.ts │ │ ├── github.ts │ │ ├── graphql │ │ │ ├── _tests │ │ │ │ └── _graphql.test.ts │ │ │ ├── api.ts │ │ │ ├── aws │ │ │ │ └── getCloudWatchForInstallation.ts │ │ │ ├── github │ │ │ │ ├── api.ts │ │ │ │ ├── createNewRepoForPerilSettings.ts │ │ │ │ ├── getAvailableReposForInstallation.ts │ │ │ │ └── sendPRForPerilSettingsRepo.ts │ │ │ ├── gql.ts │ │ │ ├── index.ts │ │ │ ├── mutations │ │ │ │ ├── _tests │ │ │ │ │ └── _dangerfileFinished.test.ts │ │ │ │ └── mutations.ts │ │ │ └── utils │ │ │ │ ├── auth.ts │ │ │ │ └── installations.ts │ │ ├── integration │ │ │ └── github.ts │ │ └── pr │ │ │ └── dsl.ts │ ├── danger │ │ ├── _tests │ │ │ ├── _danger_run.test.ts │ │ │ ├── _danger_runner.test.ts │ │ │ ├── _danger_runner_paths.test.ts │ │ │ ├── _danger_runner_peril.test.ts │ │ │ ├── _danger_runner_webhook.test.ts │ │ │ ├── _peril_platform.test.ts │ │ │ ├── fixtures │ │ │ │ ├── dangerfile_async_import.ts │ │ │ │ ├── dangerfile_empty.ts │ │ │ │ ├── dangerfile_import_complex_module.ts │ │ │ │ ├── dangerfile_import_module.ts │ │ │ │ ├── dangerfile_insecure.ts │ │ │ │ ├── dangerfile_peril_obj.ts │ │ │ │ └── file_to_import.ts │ │ │ └── sandbox_stub.ts │ │ ├── append_peril.ts │ │ ├── danger_run.ts │ │ ├── danger_runner.ts │ │ ├── peril_ci_source.ts │ │ └── peril_platform.ts │ ├── db │ │ ├── GitHubRepoSettings.ts │ │ ├── __mocks__ │ │ │ └── getDB.ts │ │ ├── _tests │ │ │ ├── __snapshots__ │ │ │ │ └── _json.test.ts.snap │ │ │ ├── _fixtures │ │ │ │ └── example_peril_orta_settings.json │ │ │ ├── _json.test.ts │ │ │ └── _mongo.test.ts │ │ ├── getDB.ts │ │ ├── index.ts │ │ ├── json.ts │ │ ├── mongo.ts │ │ ├── mongo │ │ │ └── installationAnalytics.ts │ │ ├── runtimeEnv.ts │ │ └── types.ts │ ├── github │ │ ├── _tests │ │ │ └── fixtures │ │ │ │ ├── github_comments.json │ │ │ │ ├── github_commits.json │ │ │ │ ├── github_diff.diff │ │ │ │ ├── github_issue.json │ │ │ │ ├── github_pr.json │ │ │ │ ├── github_requested_reviewers.json │ │ │ │ ├── github_reviews.json │ │ │ │ ├── github_static_file.json │ │ │ │ └── github_user.json │ │ ├── events │ │ │ ├── _tests │ │ │ │ ├── _actionForWebhook.test.ts │ │ │ │ ├── _github_runner-prs.test.ts │ │ │ │ ├── _github_runner-runs.test.ts │ │ │ │ ├── _github_runner-setup.test.ts │ │ │ │ ├── _github_runner-validations.test.ts │ │ │ │ └── fixtures │ │ │ │ │ ├── access_token.json │ │ │ │ │ ├── installation.json │ │ │ │ │ ├── integration_installation_added.json │ │ │ │ │ ├── issue_comment_created.json │ │ │ │ │ ├── issues_opened.json │ │ │ │ │ ├── ping.json │ │ │ │ │ ├── pull_request_closed.json │ │ │ │ │ ├── pull_request_labeled.json │ │ │ │ │ ├── pull_request_opened.json │ │ │ │ │ ├── pull_request_updated.json │ │ │ │ │ ├── push.json │ │ │ │ │ └── status_success.json │ │ │ ├── createPRDSL.ts │ │ │ ├── create_installation.ts │ │ │ ├── deleteInstallation.ts │ │ │ ├── github_runner.ts │ │ │ ├── handlers │ │ │ │ ├── _tests │ │ │ │ │ ├── __snapshots__ │ │ │ │ │ │ ├── _events-create-fixture.test.ts.snap │ │ │ │ │ │ ├── _events-sandbox.test.ts.snap │ │ │ │ │ │ └── _pr-create-fixture.test.ts.snap │ │ │ │ │ ├── _events-create-fixture.test.ts │ │ │ │ │ ├── _events-sandbox.test.ts │ │ │ │ │ ├── _events.test.ts │ │ │ │ │ ├── _pr-create-fixture.test.ts │ │ │ │ │ └── fixtures │ │ │ │ │ │ ├── PerilRunnerEventBootStrapExample.json │ │ │ │ │ │ └── PerilRunnerPRBootStrapExample.json │ │ │ │ ├── event.ts │ │ │ │ └── pr.ts │ │ │ ├── ping.ts │ │ │ ├── types │ │ │ │ ├── access_token.types.ts │ │ │ │ ├── installation.types.ts │ │ │ │ ├── integration_installation_added.types.ts │ │ │ │ ├── ping.types.ts │ │ │ │ ├── pull_request_closed.types.ts │ │ │ │ ├── pull_request_opened.types.ts │ │ │ │ └── pull_request_updated.types.ts │ │ │ └── utils │ │ │ │ ├── actions.ts │ │ │ │ ├── commenting.ts │ │ │ │ ├── ignore_repos.ts │ │ │ │ └── repoNameForWebhook.ts │ │ └── lib │ │ │ └── github_helpers.ts │ ├── globals.ts │ ├── index.ts │ ├── infrastructure │ │ ├── _tests │ │ │ └── _installationSlackMessaging.test.ts │ │ └── installationSlackMessaging.ts │ ├── listen.ts │ ├── logger.ts │ ├── peril.ts │ ├── plugins │ │ ├── _tests │ │ │ ├── _installationLifeCycle.test.ts │ │ │ ├── _installationSettingsUpdater.test.ts │ │ │ └── _validatesGithubWebhook.test.ts │ │ ├── installationLifeCycle.ts │ │ ├── installationSettingsUpdater.ts │ │ ├── recordWebhooks.ts │ │ ├── utils │ │ │ ├── recordWebhookWithRequest.ts │ │ │ └── sendWebhookThroughGitHubRunner.ts │ │ └── validatesGithubWebhook.ts │ ├── routing │ │ ├── _tests │ │ │ ├── _router.test.ts │ │ │ └── create-mock-response.ts │ │ └── router.ts │ ├── runner │ │ ├── _tests │ │ │ └── _customGitHubRequire.test.ts │ │ ├── customGitHubRequire.ts │ │ ├── fixtures │ │ │ ├── branch-push.json │ │ │ ├── dangerfile │ │ │ │ └── hello_world.ts │ │ │ ├── debug.json │ │ │ ├── hello-world.json │ │ │ └── pr-closed.json │ │ ├── index.ts │ │ ├── run.ts │ │ ├── runFromExternalHost.ts │ │ ├── runFromSameHost.ts │ │ ├── sandbox │ │ │ └── jwt.ts │ │ └── triggerSandboxRun.ts │ ├── scripts │ │ ├── generate-runner-deps.ts │ │ ├── json-types.ts │ │ └── setup-plugins.ts │ ├── tasks │ │ ├── _tests │ │ │ ├── _scheduleTask-heroku.test.ts │ │ │ ├── _scheduleTask-prod.test.ts │ │ │ └── _startTaskScheduler.test.ts │ │ ├── runTask.ts │ │ ├── scheduleTask.ts │ │ └── startTaskScheduler.ts │ └── testing │ │ ├── installationFactory.ts │ │ └── setupScript.js ├── tsconfig.json ├── tslint.json ├── wallaby.js └── yarn.lock ├── app.json ├── dashboard ├── .env.sample ├── .gitignore ├── LICENSE ├── README.md ├── now.staging.json ├── package.json ├── public │ ├── favicon.ico │ ├── index.html │ └── manifest.json ├── relay_data │ └── schema.graphql ├── scripts │ └── deploy_staging.sh ├── src │ ├── App.css │ ├── App.test.tsx │ ├── App.tsx │ ├── ambient.d.ts │ ├── components │ │ ├── Home.tsx │ │ ├── Installation.tsx │ │ ├── Login.tsx │ │ ├── PartialInstallation.tsx │ │ ├── __generated__ │ │ │ ├── HomeQuery.graphql.ts │ │ │ ├── InstallationQuery.graphql.ts │ │ │ └── PartialInstallationQuery.graphql.ts │ │ ├── installation │ │ │ ├── EnvVars.tsx │ │ │ ├── InstallationRules.tsx │ │ │ ├── Overview.tsx │ │ │ ├── Settings.tsx │ │ │ ├── TaskRunner.tsx │ │ │ ├── Webhooks.tsx │ │ │ ├── WebhooksHeader.tsx │ │ │ ├── Websocket.tsx │ │ │ ├── __generated__ │ │ │ │ ├── EnvVars_installation.graphql.ts │ │ │ │ ├── InstallationRules_installation.graphql.ts │ │ │ │ ├── Overview_installation.graphql.ts │ │ │ │ ├── Settings_installation.graphql.ts │ │ │ │ ├── TaskRunner_installation.graphql.ts │ │ │ │ ├── WebhooksHeader_installation.graphql.ts │ │ │ │ ├── Webhooks_installation.graphql.ts │ │ │ │ └── Websocket_installation.graphql.ts │ │ │ └── mutations │ │ │ │ ├── __generated__ │ │ │ │ ├── editEnvVarMutation.graphql.ts │ │ │ │ ├── editInstallationMutationMutation.graphql.ts │ │ │ │ ├── makeInstallationRecordMutation.graphql.ts │ │ │ │ ├── runTaskMutation.graphql.ts │ │ │ │ └── triggerWebhookMutation.graphql.ts │ │ │ │ ├── editEnvVarMutation.ts │ │ │ │ ├── editInstallationMutation.ts │ │ │ │ ├── makeInstallationRecordMutation.ts │ │ │ │ ├── runTaskMutation.ts │ │ │ │ └── triggerWebhookMutation.ts │ │ ├── layout │ │ │ ├── Layout.tsx │ │ │ └── __generated__ │ │ │ │ └── LayoutQuery.graphql.ts │ │ └── partial │ │ │ ├── SetJSONPathForm.tsx │ │ │ ├── __generated__ │ │ │ └── SetJSONPathForm_installation.graphql.ts │ │ │ └── mutations │ │ │ ├── __generated__ │ │ │ └── updateJSONURLMutation.graphql.ts │ │ │ └── updateJSONURLMutation.tsx │ ├── index.css │ ├── index.tsx │ ├── lib │ │ ├── RelayProvider.ts │ │ ├── createRelayEnvironment.ts │ │ ├── dangerfileReferenceURLs.ts │ │ └── routes.ts │ ├── logo.svg │ ├── react-app-env.d.ts │ └── serviceWorker.ts ├── tsconfig.json └── yarn.lock ├── docs ├── api_architecture.md ├── debugging.md ├── env │ └── staging.md ├── highlights.md ├── images │ ├── events-ex.png │ ├── events.png │ ├── heroku_setup.png │ └── peril-setup.png ├── local_dev.md ├── service_map.md ├── settings_repo_info.md ├── setup_for_org.md ├── terminology.md ├── updating_peril.md └── using_peril_staging.md ├── hooks ├── build └── pre_build ├── now.json ├── peril-settings-json.schema ├── runner ├── .babelrc ├── README.md ├── index.js ├── package.json ├── tsconfig.json └── yarn.lock ├── web ├── .gitignore ├── .travis.yml ├── .vscode │ ├── launch.json │ └── settings.json ├── README.md ├── data │ ├── author.json │ ├── avatars │ │ └── fabien0102.jpg │ └── blog │ │ ├── 2017-04-18--welcoming │ │ ├── index.md │ │ └── pexels-photo-253092.jpeg │ │ ├── 2017-05-02--article-1 │ │ ├── index.md │ │ └── pexels-photo-59628.jpeg │ │ └── 2017-05-02--article-2 │ │ ├── cup-of-coffee-laptop-office-macbook-89786.jpeg │ │ └── index.md ├── gatsby-browser.tsx ├── gatsby-config.js ├── gatsby-node.js ├── gatsby-ssr.tsx ├── package.json ├── src │ ├── components │ │ ├── BlogPagination │ │ │ ├── BlogPagination.stories.tsx │ │ │ ├── BlogPagination.test.tsx │ │ │ ├── BlogPagination.tsx │ │ │ ├── README.md │ │ │ └── __snapshots__ │ │ │ │ └── BlogPagination.test.tsx.snap │ │ ├── BlogTitle.tsx │ │ ├── HeaderMenu │ │ │ ├── HeaderMenu.test.tsx │ │ │ ├── HeaderMenu.tsx │ │ │ └── README.md │ │ ├── Layout.tsx │ │ ├── Menu.ts │ │ ├── SidebarMenu │ │ │ ├── README.md │ │ │ ├── SidebarMenu.test.tsx │ │ │ ├── SidebarMenu.tsx │ │ │ └── __snapshots__ │ │ │ │ └── SidebarMenu.test.tsx.snap │ │ └── TagsCard │ │ │ ├── README.md │ │ │ ├── TagsCard.test.tsx │ │ │ ├── TagsCard.tsx │ │ │ └── __snapshots__ │ │ │ └── TagsCard.test.tsx.snap │ ├── css │ │ ├── fonts │ │ │ ├── horta-webfont.woff │ │ │ └── horta-webfont.woff2 │ │ ├── responsive.css │ │ ├── semantic.min.css │ │ ├── styles.css │ │ └── themes │ │ │ └── default │ │ │ └── assets │ │ │ ├── fonts │ │ │ ├── icons.eot │ │ │ ├── icons.otf │ │ │ ├── icons.svg │ │ │ ├── icons.ttf │ │ │ ├── icons.woff │ │ │ └── icons.woff2 │ │ │ └── images │ │ │ └── flags.png │ ├── declarations.d.ts │ ├── graphql-types.d.ts │ ├── html.tsx │ ├── pages │ │ ├── 404.tsx │ │ ├── about.tsx │ │ ├── blog.tsx │ │ └── index.tsx │ ├── store.ts │ └── templates │ │ ├── blog-page.tsx │ │ ├── blog-post.tsx │ │ └── tags-page.tsx ├── test │ ├── __mocks__ │ │ └── path.js │ ├── __snapshots__ │ │ └── gatsby-node.test.js.snap │ ├── data-integrity.test.js │ └── gatsby-node.test.js ├── tools │ └── update-post-date.js ├── tsconfig.json ├── tslint.json └── yarn.lock └── yarn.lock /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | # Check https://circleci.com/docs/2.0/language-javascript/ for more details 2 | 3 | version: 2.1 4 | 5 | executors: 6 | node: 7 | parameters: 8 | dir: 9 | description: The working directory to use 10 | type: string 11 | docker: 12 | - image: circleci/node:10 13 | working_directory: ~/repo/<< parameters.dir >> 14 | 15 | commands: 16 | yarn-install: 17 | description: A command that handles installing and caching npm packages 18 | parameters: 19 | cache-key: 20 | description: String to differentiate caches 21 | type: string 22 | steps: 23 | - checkout: 24 | path: ~/repo 25 | - restore_cache: 26 | keys: 27 | - v1-<< parameters.cache-key >>-dependencies-{{ checksum "package.json" }} 28 | # fallback to using the latest cache if no exact match is found 29 | - v1-<< parameters.cache-key >>-dependencies- 30 | - run: yarn install 31 | - save_cache: 32 | paths: 33 | - node_modules 34 | key: v1-<< parameters.cache-key >>-dependencies-{{ checksum "package.json" }} 35 | 36 | 37 | jobs: 38 | # The Peril web server 39 | api: 40 | executor: 41 | name: node 42 | dir: api 43 | 44 | steps: 45 | - yarn-install: 46 | cache-key: api 47 | - run: yarn jest --max-workers=2 48 | 49 | # The Peril admin dashboard 50 | dashboard: 51 | executor: 52 | name: node 53 | dir: dashboard 54 | 55 | steps: 56 | - yarn-install: 57 | cache-key: dash 58 | - run: yarn build 59 | 60 | # The Peril public front-end 61 | web: 62 | executor: 63 | name: node 64 | dir: web 65 | 66 | steps: 67 | - yarn-install: 68 | cache-key: web 69 | - run: yarn build 70 | - run: yarn jest --max-workers=2 71 | 72 | deploy: 73 | executor: 74 | name: node 75 | dir: '' 76 | steps: 77 | - run: echo "deploy here..." 78 | 79 | 80 | workflows: 81 | build: 82 | jobs: 83 | - api 84 | - dashboard 85 | - web 86 | - deploy: 87 | filters: 88 | branches: 89 | only: master 90 | requires: 91 | - api 92 | - dashboard 93 | - web 94 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | logs 2 | *.log 3 | pids 4 | node_modules 5 | .npm 6 | *.dat 7 | out 8 | .env 9 | .next 10 | thing.pem 11 | thing.pub 12 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | source/github/events/handlers/_tests/fixtures/PerilRunnerBootStrapExample.json 2 | source/github/events/handlers/_tests/fixtures/PerilRunnerEventBootStrapExample.json 3 | node_modules/ 4 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 120, 3 | "semi": false, 4 | "singleQuote": false, 5 | "trailingComma": "es5", 6 | "bracketSpacing": true, 7 | "proseWrap": "always" 8 | } 9 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | // See http://go.microsoft.com/fwlink/?LinkId=827846 3 | // for the documentation about the extensions.json format 4 | "recommendations": ["eg2.tslint"] 5 | } 6 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.exclude": { 3 | "**/.git": true, 4 | "**/.svn": true, 5 | "**/.hg": true, 6 | "**/.DS_Store": true, 7 | "out/": true 8 | }, 9 | "search.exclude": { 10 | "**/node_modules": true, 11 | "out/": true 12 | }, 13 | "eslint.enable": false, 14 | "editor.rulers": [120], 15 | "tslint.autoFixOnSave": true, 16 | "tslint.run": "onType", 17 | "tslint.exclude": "node_modules/**/*", 18 | "editor.formatOnSave": true, 19 | "editor.renderWhitespace": "boundary", 20 | "cSpell.words": [ 21 | "GHAPI", 22 | "Graphi", 23 | "HEROKU", 24 | "PAPERTRAIL", 25 | "PRDSL", 26 | "PRJSONDSL", 27 | "Schedulable", 28 | "Sidenote", 29 | "dockerhub", 30 | "doggos", 31 | "everys", 32 | "filepaths", 33 | "mockingoose", 34 | "prioritise" 35 | ] 36 | } 37 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:10-slim 2 | 3 | ADD . /app 4 | WORKDIR /app/api 5 | 6 | # This will also trigger the build process 7 | RUN yarn install 8 | 9 | ENV PORT=80 10 | EXPOSE 80 11 | 12 | CMD yarn start 13 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016-2019 Orta Therox 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /VISION.md: -------------------------------------------------------------------------------- 1 | # Why Bother? 2 | 3 | Hosted Danger means being able to think about GitHub's webhook system as something trivial to build upon to make your 4 | own workflows. 5 | 6 | Hosted Danger comes with a few interesting aspects: 7 | 8 | - Installation can literally be a single click on the website. 9 | - Because Peril is not running Danger on CI, Danger can run against any webhook. 10 | - Simpler security model: 11 | 12 | - no need to consider scope for tokens 13 | - no need to ensure bot has access to repo 14 | - no need to ensure token isn't leaked 15 | 16 | I've wanted to do this for a [long, long time](https://github.com/danger/danger/issues/42) and the re-write aspect of 17 | Danger JS means that I could apply the constraints necessary for running hosted from day-1. 18 | 19 | # Minimum Viable Peril 20 | 21 | Peril started in 2016, and hopefully with launch in 2018. I have to eventually make a line in the sand and say, this is 22 | what we ship with. This is effectively the launch checklist. 23 | 24 | ## Runner 25 | 26 | - [x] Runs a Dangerfile with the Danger DSL on a PR event 27 | - [x] Runs a Dangerfile with webhook issue on other events 28 | - [x] Supports running async Dangerfiles easily 29 | - [x] Supports safely evaluating code 30 | 31 | ## Peril 32 | 33 | - [x] Allows regular scheduling of a task 34 | - [x] Allows scheduling of tasks in the future 35 | - [x] Allows deciding what events you're interested in running code from 36 | - [x] Allows storing ENV vars in a non-public way 37 | - [x] Keeps the database representation up-to-date with the repo 38 | 39 | ## Admin 40 | 41 | - [x] Can see orgs I need to set up 42 | - [x] Can see all the settings and keys for any orgs I'm in 43 | - [x] Can trigger a dev mode to record webhooks 44 | - [x] Can see the results of Danger runs inside the dashboard 45 | - [x] Can run any task from the admin to verify 46 | 47 | ## Homepage 48 | 49 | - [ ] Can understand Peril in a single page 50 | - [ ] Can describe pricing 51 | - [ ] Can sign up for Peril 52 | - [ ] Can get to guides 53 | - [ ] Can get to tutorials 54 | - [ ] Can get set up simply 55 | 56 |  57 | -------------------------------------------------------------------------------- /api/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["es2015", "stage-3"], 3 | "plugins": ["transform-flow-strip-types", "syntax-async-functions", "transform-regenerator"] 4 | } 5 | -------------------------------------------------------------------------------- /api/.dockerignore: -------------------------------------------------------------------------------- 1 | out 2 | node_modules 3 | .vscode 4 | config 5 | docs 6 | -------------------------------------------------------------------------------- /api/.env.sample: -------------------------------------------------------------------------------- 1 | DATABASE_JSON_FILE='artsy/peril-settings@peril.settings.json' 2 | PERIL_BOT_USER_ID=27295005 3 | PERIL_INTEGRATION_ID=2045 4 | PERIL_ORG_INSTALLATION_ID=23511 5 | PERIL_WEBHOOK_SECRET=webhook_secret 6 | PRIVATE_GITHUB_SIGNING_KEY="-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAAKCAQEAzfht/a9JH3zU1LHzCDzTi9qPpngV9+xP/OW6vemCeuGzFY3T\nLQDMhC25+au/6nJnwi7PKfzZ0SSRbs9NTDAdMC4DsZEaxx2ONc9L0hd9mamY8rvW\nuXgp0tGpSAsB8ZjBisi39P3Pv0G51coucuM3wo+0/htoatOYRqCLd/u9Y/S8Av7U\nYBhuGBBoQ0vr58x34YA4l7kK4jrFG5Xmg4iEC/+Iq2nqA5FXz7SZMEaY/Oh948lA\nF3d4JKEyEPk1mXf7lHvSSs2a+EpvhGTsh+mMpmAqCUEIBu4ZzYGa3PmhN34wYV3H\nGDAWRsIqkr9ocGPxLdND6S1QcSHX/EEw2uKdwQIDAQABAoIBAFH0gOeJQKJLzG/Z\nYqerdE1YqQIHFE6y89zgGB8K9AUrG1P/O8DTaY1KmI50vYdvAEQu1fWSC6WBVHDw\nAYTIPET4ejXEVBBYfUaB9lxhRnPHHPmwri7cVl/xVtc4sgxMyO4NEc1k1K34XBZq\nPXMvX/eFsPHPPAwNp7CqnvQd8ez8NACIjQypn21rbLWlMNAFfOwVywxUdHrwgq9l\ncgXkjTZ87WeaqdRuERkrWq1cMOf8aeZ3VwtaJw+dl26BeJDpthgoihekexh/itUT\nrDZZ8aSZ21Ay75nhylDoJVIHeX9thU7aXBNHq1pClXDDJNRHItaDo0UUj9H+Ml1T\nBrXKDAUCgYEA+wSgXWDAK4t6s21FEkNvzFWXaeBRuTV7t35NivyA801FAuVFZYvM\nEXYLtjDAR/G/PGoS1uCZpOv1lr0NHXqWdydvEhWbdecvfd0apKetDwg9oz9ZIEjP\nWCUhMVj4Dhv8xCC9NnA82v8rdUGtKUJNNodKt8nmOWF1A/nzvV4Fr8MCgYEA0g7s\nzAVlMq8xAuaZVg1DrSahHzIVK+ybQ4fcSXh0kr9Q9eZDcmJFr9Ua5Ns7cuustSQ2\nlmzMszXMHtYjDzFxOr2BHrmQUpa9KHxQ2vmNkeyE9BJnDtsOmv3AUCCAkrIykx1W\ni4P0EdKjcadqpM/ncGhJ1oTOvlQ6ROZ6I1zQCCsCgYA0WNOkhX+t1QmCj3/+/gc7\ngoHv93Kzf/7L1lAPcvblRjDlGLDvK0ckQQzSMrp2hmiODcTeALqp1PdDNyucASuN\nr7CPAeiInuydf9WFjt4dK2fHOne4rtZmmF+ird4U+yssL3Ol/aQDO4Fxk3+sAgKe\nI3qmdzlGsBc5/A8jZ48iBwKBgQCMw++vsRXl5z0C4qFy5ySpDi//BcLmUoKhuJPI\nsG3+QTLx9kLQjkaA1GBXaQrnskNkiEYEfBiZJ74IFBwefFWStZenjVbH4bgVP2m3\ntHBIj6VxIjvp2qZo+w87IuzGYaA+sfRjPiP7JZrd+QEgPSqtS1Xf6dPZ+/uoXIMQ\n24uVTQKBgFE0+oMv4iwwex8EPtisbnA0IkbsZMt90SA7+/eqGIkxK3YcMZds8vwb\n/pPYUJdw+uLHVm5LQFPoRiuaCDDX7g9HkVDSdZlS9WNQXdFiL0epAh63OwAHSlEz\nMerKqr4JPYFGTv8A2I2X8rXwczpExtBJCrDUHtfQklJvo15OX37z\n-----END RSA PRIVATE KEY-----\n" 7 | PUBLIC_GITHUB_SIGNING_KEY="-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzfht/a9JH3zU1LHzCDzT\ni9qPpngV9+xP/OW6vemCeuGzFY3TLQDMhC25+au/6nJnwi7PKfzZ0SSRbs9NTDAd\nMC4DsZEaxx2ONc9L0hd9mamY8rvWuXgp0tGpSAsB8ZjBisi39P3Pv0G51coucuM3\nwo+0/htoatOYRqCLd/u9Y/S8Av7UYBhuGBBoQ0vr58x34YA4l7kK4jrFG5Xmg4iE\nC/+Iq2nqA5FXz7SZMEaY/Oh948lAF3d4JKEyEPk1mXf7lHvSSs2a+EpvhGTsh+mM\npmAqCUEIBu4ZzYGa3PmhN34wYV3HGDAWRsIqkr9ocGPxLdND6S1QcSHX/EEw2uKd\nwQIDAQAB\n-----END PUBLIC KEY-----" 8 | -------------------------------------------------------------------------------- /api/Brewfile: -------------------------------------------------------------------------------- 1 | brew "awscli" 2 | -------------------------------------------------------------------------------- /api/bin/lambda.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/danger/peril/4c7109895ee956183411a3cb635942825d58bd97/api/bin/lambda.zip -------------------------------------------------------------------------------- /api/dangerfile.lite.ts: -------------------------------------------------------------------------------- 1 | import { danger, warn } from "danger" 2 | import { readFileSync } from "fs" 3 | 4 | const hasChangelog = danger.git.modified_files.includes("CHANGELOG.md") 5 | if (!hasChangelog) { 6 | warn("Please add a changelog entry for your changes. You can find it in `CHANGELOG.md`") 7 | } 8 | 9 | // Ensure the NodeJS versions match everywhere 10 | const nodeVersion = JSON.parse(readFileSync("package.json", "utf8")).engines.node 11 | 12 | if (!readFileSync("../.circleci/config.yml", "utf8").includes("circleci/node:" + nodeVersion)) { 13 | warn("The `.circleci/config.yml` does not have the same version of node in it (" + nodeVersion + ")") 14 | } 15 | 16 | if ( 17 | danger.git.modified_files.includes("source/db/GitHubRepoSettings.ts") && 18 | danger.git.modified_files.includes("source/db/index.ts") 19 | ) { 20 | warn("You may need to run `yarn generate:types:schema`.") 21 | } 22 | -------------------------------------------------------------------------------- /api/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '2' 2 | services: 3 | peril: 4 | build: 5 | context: . 6 | env_file: 7 | - .env.sample 8 | ports: 9 | - 80:80 10 | depends_on: 11 | - peril-db 12 | peril-db: 13 | image: postgres:9.5 14 | ports: 15 | - 5432:5432 16 | ngrok: 17 | image: wernight/ngrok 18 | command: "ngrok http peril:80" 19 | ports: 20 | - 4040:4040 21 | -------------------------------------------------------------------------------- /api/now.staging.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "peril-api", 3 | "alias": ["staging-api.peril.systems"], 4 | "type": "npm", 5 | "public": false, 6 | "env": { 7 | "PERIL_BOT_USER_ID": "@stag_peril_bot_user_id", 8 | "PERIL_INTEGRATION_ID": "@stag_peril_integration_id", 9 | "PERIL_WEBHOOK_SECRET": "@stag_peril_webhook_secret", 10 | 11 | "PRIVATE_GITHUB_SIGNING_KEY": "@stag_private_github_signing_key", 12 | "PUBLIC_GITHUB_SIGNING_KEY": "@stag_public_github_signing_key", 13 | 14 | "MONGODB_URI": "@stag_mongodb_uri", 15 | 16 | "PUBLIC_FACING_API": "true", 17 | "PRODUCTION": "false", 18 | "PUBLIC_API_ROOT_URL": "https://staging-api.peril.systems", 19 | "PUBLIC_WEB_ROOT_URL": "https://staging.peril.systems", 20 | "PUBLIC_GITHUB_APP_URL": "https://github.com/apps/peril-staging", 21 | 22 | "GITHUB_CLIENT_ID": "@stag_github_client_id", 23 | "GITHUB_CLIENT_SECRET": "@stag_github_client_secret", 24 | 25 | "SENTRY_DSN": "@stag_sentry_dsn", 26 | 27 | "AWS_ACCESS_KEY_ID": "@stag_aws_access_key_id", 28 | "AWS_SECRET_ACCESS_KEY": "@stag_aws_secret_access_key", 29 | "AWS_REGION": "us-east-1" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /api/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 |
10 |
11 |
There isn't much to do on here TBH, you're probably better off going to 13 | peril.systems 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /api/scripts/deploy-staging-api.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "Installing Now (if needed)" 4 | command -v now >/dev/null 2>&1 || { npm install -g now; } 5 | 6 | echo "Deploying, and aliasing" 7 | now deploy --local-config now.staging.json --team peril --token $NOW_TOKEN --npm 8 | now alias --local-config now.staging.json --team peril --token $NOW_TOKEN 9 | 10 | echo "Killing old instances" 11 | now rm peril-api --local-config now.staging.json --team peril --token $NOW_TOKEN --safe --yes 12 | -------------------------------------------------------------------------------- /api/scripts/deploy-staging-layer.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "Building with TypeScript" 4 | yarn build 5 | 6 | echo "Generating the Runner package.json" 7 | yarn ts-node source/scripts/generate-runner-deps.ts 8 | 9 | echo "Installing the deps" 10 | cd ../runner 11 | yarn install 12 | 13 | cd ../api 14 | 15 | echo "Copying over the node_modules" 16 | cp -rf ../runner/node_modules out 17 | 18 | echo "Trimming any dts files" 19 | ./scripts/trim_node_modules.sh 20 | 21 | echo "Zipping and uploading" 22 | zip runner.zip -r out 23 | aws lambda publish-layer-version --layer-name peril-staging-runtime --zip-file fileb://runner.zip --profile peril 24 | rm runner.zip 25 | 26 | # Based on https://claudiajs.com/tutorials/aws-cli-tricks.html 27 | 28 | echo Zipping up function 29 | zip bin/lambda.zip ../runner/index.js ../runner/tsconfig.json ../runner/app-module-path.js -j 30 | 31 | # Grab all of the lambdas and scope it to only Peril staging instances 32 | lambdas=$(aws lambda list-functions --profile peril --query 'Functions[?starts_with(FunctionName, `s-`)].FunctionName' --output text) 33 | 34 | # Grab the current runtime ARN ( e.g. arn:aws:lambda:us-east-1:123456:layer:peril-staging-runtime:11 ) 35 | runtime=$(aws lambda list-layers --profile peril --query 'Layers[?starts_with(LayerName, `peril-s`)].LatestMatchingVersion.LayerVersionArn' --output text) 36 | echo Updating all functions to use $runtime 37 | 38 | for lambda in $lambdas; do 39 | echo Updating the layer for $lambda 40 | aws lambda update-function-configuration --function-name $lambda --layers $runtime --profile peril 41 | done 42 | -------------------------------------------------------------------------------- /api/scripts/deploy-staging-runner.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Based on https://claudiajs.com/tutorials/aws-cli-tricks.html 4 | 5 | echo Zipping up function 6 | 7 | # -j = ignore files 8 | # -X = ignore metadata (deterministic-ish builds) 9 | zip bin/lambda.zip ../runner/index.js ../runner/tsconfig.json ../runner/.babelrc -j -X 10 | 11 | # Grab all of the lambdas and scope it to only Peril staging instances 12 | lambdas=$(aws lambda list-functions --profile peril --query 'Functions[?starts_with(FunctionName, `s-`)].FunctionName' --output text) 13 | 14 | # Grab the current runtime ARN ( e.g. arn:aws:lambda:us-east-1:123456:layer:peril-staging-runtime:11 ) 15 | runtime=$(aws lambda list-layers --profile peril --query 'Layers[?starts_with(LayerName, `s-`)].LatestMatchingVersion.LayerVersionArn' --output text) 16 | 17 | for lambda in $lambdas; do 18 | echo Updating the code for $lambda 19 | aws lambda update-function-code --function-name $lambda --zip-file fileb://bin/lambda.zip --profile peril 20 | done 21 | -------------------------------------------------------------------------------- /api/scripts/trim_node_modules.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Remove some of the largest dependencies 4 | rm -rf out/node_modules/@types \ 5 | out/node_modules/prettier \ 6 | out/node_modules/aws-lambda \ 7 | out/node_modules/prettier \ 8 | out/node_modules/rxjs \ 9 | out/node_modules/rx \ 10 | out/node_modules/fsevents \ 11 | out/node_modules/ice-cap \ 12 | out/node_modules/aws-sdk/dist/aws-sdk-react-native.js 13 | 14 | # Kill the types from modules 15 | find ./out -name "*.d.ts" -delete 16 | 17 | 18 | -------------------------------------------------------------------------------- /api/source/api/_tests/fixtureAPI.ts: -------------------------------------------------------------------------------- 1 | import { GitHub, GitHubType } from "danger/distribution/platforms/GitHub" 2 | import { GitHubAPI } from "danger/distribution/platforms/github/GitHubAPI" 3 | 4 | import { readFileSync } from "fs" 5 | 6 | import { resolve } from "path" 7 | 8 | const githubFixtures = resolve(__dirname, "..", "..", "github", "_tests", "fixtures") 9 | 10 | /** Returns JSON from the fixtured dir */ 11 | const requestWithFixturedJSON = (path: string): (() => Promise{JSON.stringify(visibleSettings, null, " ")}33 |
39 | Peril can record webhooks sent from GitHub for a 5 minutes period, then you can re-trigger them at any point. 40 |
41 | {startRecording && ( 42 |Last recorded {relativeDate(new Date(startRecording))}.
43 | )} 44 |Powered with
(WrappedComponent: React.ComponentType
) => 64 | class WithLayout extends React.Component
{
65 | render() {
66 | return (
67 |
18 | This starter was created by @fabien0102.
19 |
21 | For any question, I'm on discord #reactiflux/gatsby
22 |
24 | For any issues, any PR are welcoming
25 | on this repository
26 |
22 | {props.tags.map((tag) => {
23 | const isActive = tag.fieldValue === props.tag;
24 | const activeStyle = {
25 | fontWeight: "700",
26 | };
27 | const tagLink = isActive ? `/blog` : `/blog/tags/${tag.fieldValue}/`;
28 | return (
29 |
40 |