├── .babelrc ├── .eslintrc.js ├── .github └── FUNDING.yml ├── .gitignore ├── .travis.yml ├── CHANGELOG.md ├── LICENSE ├── README.md ├── __test__ ├── combined-status-failed-response.json ├── combined-status-response.json └── index.test.js ├── index.js ├── jest.config.js ├── main.js ├── package.json ├── renovate.json └── yarn.lock /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "test": { 4 | "presets": [ 5 | ["@babel/preset-env", { 6 | "targets": { 7 | "node": "current" 8 | } 9 | }] 10 | ] 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | extends: [ 4 | '@nuxtjs' 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: [manniL] 2 | custom: ['https://www.lichter.io/support-me/'] 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.iml 3 | .idea 4 | *.log* 5 | .nuxt* 6 | .vscode 7 | .DS_STORE 8 | coverage 9 | dist 10 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "10" 4 | - "11" 5 | cache: 6 | yarn: true 7 | directories: 8 | - node_modules 9 | install: 10 | - yarn 11 | script: 12 | - yarn test 13 | after_success: 14 | - yarn coverage 15 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. 4 | 5 | ## [1.2.1](https://github.com/Developmint/wait-for-netlify-preview/compare/v1.2.0...v1.2.1) (2019-04-20) 6 | 7 | 8 | ### Bug Fixes 9 | 10 | * work with all netlify build contexts ([#15](https://github.com/Developmint/wait-for-netlify-preview/issues/15)) ([7b54326](https://github.com/Developmint/wait-for-netlify-preview/commit/7b54326)) 11 | 12 | 13 | 14 | 15 | # [1.2.0](https://github.com/Developmint/wait-for-netlify-preview/compare/v1.1.0...v1.2.0) (2019-02-06) 16 | 17 | 18 | ### Features 19 | 20 | * exit process when the deploy failed ([3f5325a](https://github.com/Developmint/wait-for-netlify-preview/commit/3f5325a)), closes [#7](https://github.com/Developmint/wait-for-netlify-preview/issues/7) 21 | 22 | 23 | 24 | 25 | # [1.1.0](https://github.com/Developmint/wait-for-netlify-preview/compare/v1.0.0...v1.1.0) (2019-01-09) 26 | 27 | 28 | ### Bug Fixes 29 | 30 | * echo the correct link ([a4dab76](https://github.com/Developmint/wait-for-netlify-preview/commit/a4dab76)) 31 | 32 | 33 | ### Features 34 | 35 | * triple check interval ([a629b2c](https://github.com/Developmint/wait-for-netlify-preview/commit/a629b2c)) 36 | 37 | 38 | 39 | 40 | # 1.0.0 (2019-01-09) 41 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Alexander Lichter 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # wait-for-netlify-preview 2 | 3 | > Let your Travis CI wait for the Netlify build preview 4 | 5 | [![npm (scoped with tag)](https://img.shields.io/npm/v/wait-for-netlify-preview/latest.svg?style=flat-square)](https://npmjs.com/package/wait-for-netlify-preview) 6 | [![npm](https://img.shields.io/npm/dt/wait-for-netlify-preview.svg?style=flat-square)](https://npmjs.com/package/wait-for-netlify-preview) 7 | [![Build Status](https://travis-ci.com/Developmint/wait-for-netlify-preview.svg?branch=master)](https://travis-ci.com/Developmint/wait-for-netlify-preview) 8 | [![codecov](https://codecov.io/gh/Developmint/wait-for-netlify-preview/branch/master/graph/badge.svg)](https://codecov.io/gh/Developmint/wait-for-netlify-preview) 9 | [![Dependencies](https://david-dm.org/Developmint/wait-for-netlify-preview/status.svg?style=flat-square)](https://david-dm.org/Developmint/wait-for-netlify-preview) 10 | [![js-standard-style](https://img.shields.io/badge/code_style-standard-brightgreen.svg?style=flat-square)](http://standardjs.com) 11 | [![thanks](https://img.shields.io/badge/thanks-%E2%99%A5-ff69b4.svg)](https://thanks.lichter.io/) 12 | 13 | [📖 **Release Notes**](./CHANGELOG.md) 14 | 15 | ## Setup 16 | 17 | ### Yarn 18 | 19 | ``` 20 | $ yarn add wait-for-netlify-preview 21 | ``` 22 | 23 | ### npm 24 | 25 | ``` 26 | $ npm install --save wait-for-netlify-preview 27 | ``` 28 | 29 | ## Usage 30 | 31 | Requires the following environment variables: 32 | - `GITHUB_API_TOKEN` with `repo_deployment` scope 33 | - `TRAVIS_PULL_REQUEST_SHA` (automatically provided by travis) 34 | - `TRAVIS_REPO_SLUG` (automatically provided by travis) 35 | 36 | ``` 37 | $ wait-for-netlify-preview 38 | ``` 39 | 40 | An example `.travis.yml` can be found here soon! 41 | 42 | ## Development 43 | 44 | - Clone this repository 45 | - Install dependencies using `yarn install` or `npm install` 46 | - Start development server using `npm run dev` 47 | 48 | ## Inspiration 49 | 50 | Inspired by [wait-for-now](https://github.com/wyze/wait-for-now) 51 | 52 | ## License 53 | 54 | [MIT License](./LICENSE) 55 | 56 | Copyright (c) Alexander Lichter 57 | -------------------------------------------------------------------------------- /__test__/combined-status-failed-response.json: -------------------------------------------------------------------------------- 1 | { 2 | "state": "failure", 3 | "statuses": [ 4 | { 5 | "url": "https://api.github.com/repos/Developmint/developmint.de/statuses/be5ead9c3e2f8e5694384230eba8866370a4f07c", 6 | "avatar_url": "https://avatars3.githubusercontent.com/in/13473?v=4", 7 | "id": 6198390575, 8 | "node_id": "MDEzOlN0YXR1c0NvbnRleHQ2MTk4MzkwNTc1", 9 | "state": "failure", 10 | "description": "Deploy preview failed.", 11 | "target_url": "https://app.netlify.com/sites/developmint/deploys/5c59ab760e1c470008a5a296", 12 | "context": "netlify/developmint/deploy-preview", 13 | "created_at": "2019-02-05T15:28:32Z", 14 | "updated_at": "2019-02-05T15:28:32Z" 15 | }, 16 | { 17 | "url": "https://api.github.com/repos/Developmint/developmint.de/statuses/be5ead9c3e2f8e5694384230eba8866370a4f07c", 18 | "avatar_url": "https://avatars2.githubusercontent.com/oa/1508?v=4", 19 | "id": 6198403512, 20 | "node_id": "MDEzOlN0YXR1c0NvbnRleHQ2MTk4NDAzNTEy", 21 | "state": "success", 22 | "description": "The Travis CI build passed", 23 | "target_url": "https://travis-ci.org/Developmint/developmint.de/builds/489096130?utm_source=github_status&utm_medium=notification", 24 | "context": "continuous-integration/travis-ci/push", 25 | "created_at": "2019-02-05T15:30:15Z", 26 | "updated_at": "2019-02-05T15:30:15Z" 27 | }, 28 | { 29 | "url": "https://api.github.com/repos/Developmint/developmint.de/statuses/be5ead9c3e2f8e5694384230eba8866370a4f07c", 30 | "avatar_url": "https://avatars2.githubusercontent.com/oa/1508?v=4", 31 | "id": 6198802558, 32 | "node_id": "MDEzOlN0YXR1c0NvbnRleHQ2MTk4ODAyNTU4", 33 | "state": "error", 34 | "description": "The Travis CI build could not complete due to an error", 35 | "target_url": "https://travis-ci.org/Developmint/developmint.de/builds/489096145?utm_source=github_status&utm_medium=notification", 36 | "context": "continuous-integration/travis-ci/pr", 37 | "created_at": "2019-02-05T16:21:07Z", 38 | "updated_at": "2019-02-05T16:21:07Z" 39 | } 40 | ], 41 | "sha": "be5ead9c3e2f8e5694384230eba8866370a4f07c", 42 | "total_count": 3, 43 | "repository": { 44 | "id": 125930547, 45 | "node_id": "MDEwOlJlcG9zaXRvcnkxMjU5MzA1NDc=", 46 | "name": "developmint.de", 47 | "full_name": "Developmint/developmint.de", 48 | "private": false, 49 | "owner": { 50 | "login": "Developmint", 51 | "id": 29969219, 52 | "node_id": "MDEyOk9yZ2FuaXphdGlvbjI5OTY5MjE5", 53 | "avatar_url": "https://avatars0.githubusercontent.com/u/29969219?v=4", 54 | "gravatar_id": "", 55 | "url": "https://api.github.com/users/Developmint", 56 | "html_url": "https://github.com/Developmint", 57 | "followers_url": "https://api.github.com/users/Developmint/followers", 58 | "following_url": "https://api.github.com/users/Developmint/following{/other_user}", 59 | "gists_url": "https://api.github.com/users/Developmint/gists{/gist_id}", 60 | "starred_url": "https://api.github.com/users/Developmint/starred{/owner}{/repo}", 61 | "subscriptions_url": "https://api.github.com/users/Developmint/subscriptions", 62 | "organizations_url": "https://api.github.com/users/Developmint/orgs", 63 | "repos_url": "https://api.github.com/users/Developmint/repos", 64 | "events_url": "https://api.github.com/users/Developmint/events{/privacy}", 65 | "received_events_url": "https://api.github.com/users/Developmint/received_events", 66 | "type": "Organization", 67 | "site_admin": false 68 | }, 69 | "html_url": "https://github.com/Developmint/developmint.de", 70 | "description": "Open source company page built with Nuxt.js and TailwindCSS", 71 | "fork": false, 72 | "url": "https://api.github.com/repos/Developmint/developmint.de", 73 | "forks_url": "https://api.github.com/repos/Developmint/developmint.de/forks", 74 | "keys_url": "https://api.github.com/repos/Developmint/developmint.de/keys{/key_id}", 75 | "collaborators_url": "https://api.github.com/repos/Developmint/developmint.de/collaborators{/collaborator}", 76 | "teams_url": "https://api.github.com/repos/Developmint/developmint.de/teams", 77 | "hooks_url": "https://api.github.com/repos/Developmint/developmint.de/hooks", 78 | "issue_events_url": "https://api.github.com/repos/Developmint/developmint.de/issues/events{/number}", 79 | "events_url": "https://api.github.com/repos/Developmint/developmint.de/events", 80 | "assignees_url": "https://api.github.com/repos/Developmint/developmint.de/assignees{/user}", 81 | "branches_url": "https://api.github.com/repos/Developmint/developmint.de/branches{/branch}", 82 | "tags_url": "https://api.github.com/repos/Developmint/developmint.de/tags", 83 | "blobs_url": "https://api.github.com/repos/Developmint/developmint.de/git/blobs{/sha}", 84 | "git_tags_url": "https://api.github.com/repos/Developmint/developmint.de/git/tags{/sha}", 85 | "git_refs_url": "https://api.github.com/repos/Developmint/developmint.de/git/refs{/sha}", 86 | "trees_url": "https://api.github.com/repos/Developmint/developmint.de/git/trees{/sha}", 87 | "statuses_url": "https://api.github.com/repos/Developmint/developmint.de/statuses/{sha}", 88 | "languages_url": "https://api.github.com/repos/Developmint/developmint.de/languages", 89 | "stargazers_url": "https://api.github.com/repos/Developmint/developmint.de/stargazers", 90 | "contributors_url": "https://api.github.com/repos/Developmint/developmint.de/contributors", 91 | "subscribers_url": "https://api.github.com/repos/Developmint/developmint.de/subscribers", 92 | "subscription_url": "https://api.github.com/repos/Developmint/developmint.de/subscription", 93 | "commits_url": "https://api.github.com/repos/Developmint/developmint.de/commits{/sha}", 94 | "git_commits_url": "https://api.github.com/repos/Developmint/developmint.de/git/commits{/sha}", 95 | "comments_url": "https://api.github.com/repos/Developmint/developmint.de/comments{/number}", 96 | "issue_comment_url": "https://api.github.com/repos/Developmint/developmint.de/issues/comments{/number}", 97 | "contents_url": "https://api.github.com/repos/Developmint/developmint.de/contents/{+path}", 98 | "compare_url": "https://api.github.com/repos/Developmint/developmint.de/compare/{base}...{head}", 99 | "merges_url": "https://api.github.com/repos/Developmint/developmint.de/merges", 100 | "archive_url": "https://api.github.com/repos/Developmint/developmint.de/{archive_format}{/ref}", 101 | "downloads_url": "https://api.github.com/repos/Developmint/developmint.de/downloads", 102 | "issues_url": "https://api.github.com/repos/Developmint/developmint.de/issues{/number}", 103 | "pulls_url": "https://api.github.com/repos/Developmint/developmint.de/pulls{/number}", 104 | "milestones_url": "https://api.github.com/repos/Developmint/developmint.de/milestones{/number}", 105 | "notifications_url": "https://api.github.com/repos/Developmint/developmint.de/notifications{?since,all,participating}", 106 | "labels_url": "https://api.github.com/repos/Developmint/developmint.de/labels{/name}", 107 | "releases_url": "https://api.github.com/repos/Developmint/developmint.de/releases{/id}", 108 | "deployments_url": "https://api.github.com/repos/Developmint/developmint.de/deployments" 109 | }, 110 | "commit_url": "https://api.github.com/repos/Developmint/developmint.de/commits/be5ead9c3e2f8e5694384230eba8866370a4f07c", 111 | "url": "https://api.github.com/repos/Developmint/developmint.de/commits/be5ead9c3e2f8e5694384230eba8866370a4f07c/status" 112 | } 113 | -------------------------------------------------------------------------------- /__test__/combined-status-response.json: -------------------------------------------------------------------------------- 1 | { 2 | "state": "success", 3 | "statuses": [ 4 | { 5 | "url": "https://api.github.com/repos/manniL/lichter.io/statuses/50ad1b7dccafa9b08ee3fe70b18df5cce3b6c4b0", 6 | "avatar_url": "https://avatars3.githubusercontent.com/in/13473?v=4", 7 | "id": 6027259754, 8 | "node_id": "MDEzOlN0YXR1c0NvbnRleHQ2MDI3MjU5NzU0", 9 | "state": "success", 10 | "description": "Deploy preview ready!", 11 | "target_url": "https://deploy-preview-26--lichterio.netlify.com", 12 | "context": "netlify/lichterio/deploy-preview", 13 | "created_at": "2019-01-04T00:46:53Z", 14 | "updated_at": "2019-01-04T00:46:53Z" 15 | } 16 | ], 17 | "sha": "50ad1b7dccafa9b08ee3fe70b18df5cce3b6c4b0", 18 | "total_count": 1, 19 | "repository": { 20 | "id": 110095223, 21 | "node_id": "MDEwOlJlcG9zaXRvcnkxMTAwOTUyMjM=", 22 | "name": "lichter.io", 23 | "full_name": "manniL/lichter.io", 24 | "private": false, 25 | "html_url": "https://github.com/manniL/lichter.io", 26 | "description": "My own website and CV", 27 | "fork": false, 28 | "url": "https://api.github.com/repos/manniL/lichter.io", 29 | "forks_url": "https://api.github.com/repos/manniL/lichter.io/forks", 30 | "keys_url": "https://api.github.com/repos/manniL/lichter.io/keys{/key_id}", 31 | "collaborators_url": "https://api.github.com/repos/manniL/lichter.io/collaborators{/collaborator}", 32 | "teams_url": "https://api.github.com/repos/manniL/lichter.io/teams", 33 | "hooks_url": "https://api.github.com/repos/manniL/lichter.io/hooks", 34 | "issue_events_url": "https://api.github.com/repos/manniL/lichter.io/issues/events{/number}", 35 | "events_url": "https://api.github.com/repos/manniL/lichter.io/events", 36 | "assignees_url": "https://api.github.com/repos/manniL/lichter.io/assignees{/user}", 37 | "branches_url": "https://api.github.com/repos/manniL/lichter.io/branches{/branch}", 38 | "tags_url": "https://api.github.com/repos/manniL/lichter.io/tags", 39 | "blobs_url": "https://api.github.com/repos/manniL/lichter.io/git/blobs{/sha}", 40 | "git_tags_url": "https://api.github.com/repos/manniL/lichter.io/git/tags{/sha}", 41 | "git_refs_url": "https://api.github.com/repos/manniL/lichter.io/git/refs{/sha}", 42 | "trees_url": "https://api.github.com/repos/manniL/lichter.io/git/trees{/sha}", 43 | "statuses_url": "https://api.github.com/repos/manniL/lichter.io/statuses/{sha}", 44 | "languages_url": "https://api.github.com/repos/manniL/lichter.io/languages", 45 | "stargazers_url": "https://api.github.com/repos/manniL/lichter.io/stargazers", 46 | "contributors_url": "https://api.github.com/repos/manniL/lichter.io/contributors", 47 | "subscribers_url": "https://api.github.com/repos/manniL/lichter.io/subscribers", 48 | "subscription_url": "https://api.github.com/repos/manniL/lichter.io/subscription", 49 | "commits_url": "https://api.github.com/repos/manniL/lichter.io/commits{/sha}", 50 | "git_commits_url": "https://api.github.com/repos/manniL/lichter.io/git/commits{/sha}", 51 | "comments_url": "https://api.github.com/repos/manniL/lichter.io/comments{/number}", 52 | "issue_comment_url": "https://api.github.com/repos/manniL/lichter.io/issues/comments{/number}", 53 | "contents_url": "https://api.github.com/repos/manniL/lichter.io/contents/{+path}", 54 | "compare_url": "https://api.github.com/repos/manniL/lichter.io/compare/{base}...{head}", 55 | "merges_url": "https://api.github.com/repos/manniL/lichter.io/merges", 56 | "archive_url": "https://api.github.com/repos/manniL/lichter.io/{archive_format}{/ref}", 57 | "downloads_url": "https://api.github.com/repos/manniL/lichter.io/downloads", 58 | "issues_url": "https://api.github.com/repos/manniL/lichter.io/issues{/number}", 59 | "pulls_url": "https://api.github.com/repos/manniL/lichter.io/pulls{/number}", 60 | "milestones_url": "https://api.github.com/repos/manniL/lichter.io/milestones{/number}", 61 | "notifications_url": "https://api.github.com/repos/manniL/lichter.io/notifications{?since,all,participating}", 62 | "labels_url": "https://api.github.com/repos/manniL/lichter.io/labels{/name}", 63 | "releases_url": "https://api.github.com/repos/manniL/lichter.io/releases{/id}", 64 | "deployments_url": "https://api.github.com/repos/manniL/lichter.io/deployments" 65 | }, 66 | "commit_url": "https://api.github.com/repos/manniL/lichter.io/commits/50ad1b7dccafa9b08ee3fe70b18df5cce3b6c4b0", 67 | "url": "https://api.github.com/repos/manniL/lichter.io/commits/50ad1b7dccafa9b08ee3fe70b18df5cce3b6c4b0/status" 68 | } 69 | -------------------------------------------------------------------------------- /__test__/index.test.js: -------------------------------------------------------------------------------- 1 | /* eslint import/first: "off" */ 2 | jest.mock('@octokit/rest', () => { 3 | class Octokit { 4 | constructor() { 5 | this.repos = { 6 | getCombinedStatusForRef: Octokit.getCombinedStatusForRef 7 | } 8 | } 9 | } 10 | 11 | Octokit.getCombinedStatusForRef = jest.fn() 12 | 13 | return Octokit 14 | }) 15 | import Octokit from '@octokit/rest' 16 | import pWaitFor from 'p-wait-for' 17 | import consola from 'consola' 18 | import combinedStatusResponse from './combined-status-response' 19 | import combinedStatusFailedResponse from './combined-status-failed-response' 20 | 21 | beforeEach(() => { 22 | Octokit.getCombinedStatusForRef.mockReset() 23 | consola.mockTypes(() => jest.fn()) 24 | 25 | process.env.TRAVIS_REPO_SLUG = 'manniL/lichter.io' 26 | process.env.TRAVIS_PULL_REQUEST_SHA = '50ad1b7dccafa9b08ee3fe70b18df5cce3b6c4b0' 27 | process.env.GITHUB_API_TOKEN = '111' 28 | }) 29 | 30 | const requireMain = () => { 31 | jest.isolateModules(() => { 32 | require('../main') 33 | }) 34 | } 35 | 36 | test('it throws when deploy preview failed', async () => { 37 | const exit = jest.spyOn(process, 'exit').mockImplementation(() => {}) 38 | 39 | Octokit.getCombinedStatusForRef.mockResolvedValue({ 40 | data: combinedStatusFailedResponse 41 | }) 42 | 43 | try { 44 | requireMain() 45 | await pWaitFor(() => consola.errors.mock.calls.length > 0) 46 | } catch (e) {} 47 | 48 | expect(exit).toHaveBeenCalledWith(1) 49 | 50 | // Disable mocks 51 | exit.mockRestore() 52 | }) 53 | 54 | test('it calls console.log with deployed url', async () => { 55 | Octokit.getCombinedStatusForRef.mockResolvedValue({ 56 | data: combinedStatusResponse 57 | }) 58 | 59 | requireMain() 60 | await pWaitFor(() => consola.log.mock.calls.length > 0) 61 | 62 | expect(consola.log).toHaveBeenCalledWith(expect.stringContaining( 63 | combinedStatusResponse.statuses[0].target_url 64 | )) 65 | }) 66 | 67 | test('it works with deploy/netlify status', async () => { 68 | const targetUrl = `https://deploy-preview-26--something-different.netlify.com` 69 | const combinedStatusResponseWithChangedContext = { 70 | ...combinedStatusResponse, 71 | repository: { 72 | ...combinedStatusResponse.repository, 73 | full_name: `dschau/some-repo` 74 | }, 75 | statuses: [ 76 | { 77 | ...combinedStatusResponse.statuses[0], 78 | context: 'deploy/netlify', 79 | target_url: targetUrl 80 | } 81 | ] 82 | } 83 | process.env.TRAVIS_REPO_SLUG = combinedStatusResponseWithChangedContext.repository.full_name 84 | 85 | Octokit.getCombinedStatusForRef.mockResolvedValue({ 86 | data: combinedStatusResponseWithChangedContext 87 | }) 88 | 89 | requireMain() 90 | await pWaitFor(() => consola.log.mock.calls.length > 0) 91 | 92 | expect(consola.log).toHaveBeenCalledWith( 93 | expect.stringContaining(targetUrl) 94 | ) 95 | }) 96 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env node 2 | module.exports = require('esm')(module, { mode: 'all' })('./main.js').default 3 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | testEnvironment: 'node', 3 | collectCoverage: true, 4 | coverageDirectory: './coverage/', 5 | collectCoverageFrom: [ 6 | 'main.js' 7 | ], 8 | moduleFileExtensions: ['js', 'mjs', 'json'], 9 | expand: true, 10 | forceExit: false 11 | } 12 | -------------------------------------------------------------------------------- /main.js: -------------------------------------------------------------------------------- 1 | import Octokit from '@octokit/rest' 2 | import pWaitFor from 'p-wait-for' 3 | import consola from 'consola' 4 | 5 | const SimpleReporter = class { 6 | constructor({ stream } = {}) { 7 | this.stream = stream || process.stdout 8 | } 9 | 10 | log(logObj) { 11 | this.stream.write(`${logObj.args[0]}\n`) 12 | } 13 | } 14 | 15 | consola.setReporters(new SimpleReporter()) 16 | const octokit = new Octokit({ 17 | auth: `token ${process.env.GITHUB_API_TOKEN}` 18 | }) 19 | 20 | const [owner, repo] = process.env.TRAVIS_REPO_SLUG.split('/') 21 | const ref = process.env.TRAVIS_PULL_REQUEST_SHA 22 | 23 | const hasDeployPreview = context => [/^netlify\/.*\/deploy-preview$/, /^deploy\/netlify$/].some(expr => expr.test(context)) 24 | const successPreview = state => state === 'success' 25 | const failedPreview = state => state === 'failure' 26 | 27 | const getSuccessfulDeployment = async () => { 28 | const { data: { statuses } } = await octokit.repos.getCombinedStatusForRef({ owner, ref, repo }) 29 | 30 | if (statuses.find(({ context, state }) => hasDeployPreview(context) && failedPreview(state))) { 31 | consola.error('Deploy preview failed') 32 | // Fail CI 33 | process.exit(1) 34 | } 35 | 36 | return statuses.find(({ context, state }) => hasDeployPreview(context) && successPreview(state)) 37 | } 38 | 39 | const deployed = async () => Boolean(await getSuccessfulDeployment()) 40 | ;(async () => { 41 | await pWaitFor(deployed, { interval: 15000 }) 42 | 43 | const { target_url: targetUrl } = await getSuccessfulDeployment() 44 | consola.log(targetUrl) 45 | return targetUrl 46 | })() 47 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "wait-for-netlify-preview", 3 | "version": "1.2.1", 4 | "description": "Let you Travis CI wait for the Netlify build preview", 5 | "main": "indx.js", 6 | "license": "MIT", 7 | "repository": "Developmint/wait-for-netlify-preview", 8 | "scripts": { 9 | "lint": "eslint index.js __test__", 10 | "pretest": "yarn run lint", 11 | "test": "jest --detectOpenHandles", 12 | "release": "standard-version && git push --follow-tags && npm publish", 13 | "commitlint": "commitlint -E HUSKY_GIT_PARAMS", 14 | "coverage": "codecov" 15 | }, 16 | "keywords": [ 17 | "netlify", 18 | "travisci", 19 | "ci", 20 | "wait", 21 | "preview" 22 | ], 23 | "bugs": { 24 | "url": "https://github.com/Developmint/wait-for-netlify-preview/issues" 25 | }, 26 | "contributors": [ 27 | { 28 | "name": "Alexander Lichter " 29 | } 30 | ], 31 | "files": [ 32 | "index.js", 33 | "main.js" 34 | ], 35 | "bin": "index.js", 36 | "dependencies": { 37 | "@octokit/rest": "^16.25.4", 38 | "consola": "^2.6.1", 39 | "esm": "^3.2.22", 40 | "p-wait-for": "^3.1.0" 41 | }, 42 | "devDependencies": { 43 | "@babel/core": "^7.4.4", 44 | "@babel/preset-env": "^7.4.4", 45 | "@nuxtjs/eslint-config": "^0.0.1", 46 | "babel-core": "^7.0.0-bridge.0", 47 | "babel-jest": "^24.8.0", 48 | "bili": "^4.7.4", 49 | "codecov": "^3.4.0", 50 | "eslint": "^5.16.0", 51 | "eslint-config-standard": "^12.0.0", 52 | "eslint-plugin-import": "^2.17.2", 53 | "eslint-plugin-jest": "^22.5.1", 54 | "eslint-plugin-node": "^8.0.1", 55 | "eslint-plugin-promise": "^4.1.1", 56 | "eslint-plugin-standard": "^4.0.0", 57 | "eslint-plugin-vue": "^5.2.2", 58 | "jest": "^24.8.0", 59 | "standard-version": "^5.0.2" 60 | }, 61 | "husky": { 62 | "hooks": { 63 | "pre-commit": "yarn lint", 64 | "commit-msg": "yarn commitlint" 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "@nuxtjs" 4 | ] 5 | } 6 | --------------------------------------------------------------------------------