Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add healthcheckretries option #78

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,38 @@ By default, the application will not be rolled back if the healthcheck fails.

Thanks to [FridaTveit](https://github.com/FridaTveit) for adding this feature

### Retry healthcheck

You can set the healthcheckretries option to re-run the healthcheck some number of times before considering it a failure. Retries will be delayed by delay each time, not just initially.

_.github/workflows/main.yml_

```yaml
name: Deploy

on:
push:
branches:
- master # Changing the branch here would also work

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: akhileshns/[email protected] # This is the action
with:
heroku_api_key: ${{secrets.HEROKU_API_KEY}}
heroku_app_name: "YOUR APP's NAME" #Must be unique in Heroku
heroku_email: "YOUR EMAIL"
healthcheck: "https://[YOUR APP's NAME].herokuapp.com/health"
healthcheckretries: 10 # Try 5 times before failing
healthcheckdelay: 30 # 30s delay, the last try (10th) will happen 5 minutes after the first
rollbackonhealthcheckfailed: true
```

By default healthcheck will only try once.

## Environment Variables

Heroku offers a means of passing sensitive information to your app (such as api keys etc) via something it calls **config vars** which you can find in the settings of your heroku app. But sometimes you might want to store sensitive information (api keys etc) in GitHub Secrets instead just to ensure platform independence. If you choose to this, you can then pass those secrets to your heroku app by using the "env" object of the action:-
Expand Down
4 changes: 4 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ inputs:
description: "A URL to which a healthcheck is performed (checks for 200 request)"
required: false
default: ""
healthcheckretries:
description: "Number of times to try the healthcheck"
required: false
default: "1"
checkstring:
description: "Value to check for when conducting healthcheck request"
required: false
Expand Down
30 changes: 23 additions & 7 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ let heroku = {
dockerBuildArgs: core.getInput("docker_build_args"),
appdir: core.getInput("appdir"),
healthcheck: core.getInput("healthcheck"),
healthcheckretries: parseInt(core.getInput("healthcheckretries")),
checkstring: core.getInput("checkstring"),
delay: parseInt(core.getInput("delay")),
procfile: core.getInput("procfile"),
Expand Down Expand Up @@ -233,23 +234,38 @@ if (heroku.dockerBuildArgs) {
}

if (heroku.healthcheck) {
if (typeof heroku.delay === "number" && heroku.delay !== NaN) {
await sleep(heroku.delay * 1000);
}
const maxRetries = typeof heroku.healthcheckretries === "number" && heroku.healthcheckretries !== NaN ?
heroku.healthcheckretries : 1;
let err;
for (let tries = 0; tries < maxRetries; tries++) {
if (err) {
console.log(`Health check failed, trying again (${tries} of ${maxRetries})`);
}

if (typeof heroku.delay === "number" && heroku.delay !== NaN) {
await sleep(heroku.delay * 1000);
}

try {
const res = await p(heroku.healthcheck);
if (res.statusCode !== 200) {
throw new Error(
err = new Error(
"Status code of network request is not 200: Status code - " +
res.statusCode
);
continue;
}
if (heroku.checkstring && heroku.checkstring !== res.body.toString()) {
throw new Error("Failed to match the checkstring");
err = new Error("Failed to match the checkstring");
continue;
}

// Success
err = undefined;
console.log(res.body.toString());
} catch (err) {
break;
}

if (err) {
console.log(err.message);
healthcheckFailed(heroku);
}
Expand Down