Skip to content

Commit

Permalink
Added webhook support
Browse files Browse the repository at this point in the history
  • Loading branch information
rgaudin committed Oct 30, 2021
1 parent 8e0cc39 commit 3f73418
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 2 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
# v7

- now supports adding a `webhook` to call on successful push

# v6

- now supports schedule runs

# v5

- now supports a manual tag override through `manual-tag`.
Expand Down
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
steps:
- uses: actions/checkout@v2
- name: Build and push
uses: openzim/docker-publish-action@v6
uses: openzim/docker-publish-action@v7
with:
image-name: openzim/zimit
DOCKERIO_USERNAME=${{ secrets.DOCKERHUB_USERNAME }}
Expand Down Expand Up @@ -60,7 +60,7 @@ jobs:
steps:
- uses: actions/checkout@v2
- name: Build and push
uses: openzim/docker-publish-action@v6
uses: openzim/docker-publish-action@v7
with:
image-name: openzim/zimit
registries: |
Expand All @@ -79,6 +79,7 @@ jobs:
build-args:
VERSION={tag}
manual-tag: ${{ github.event.inputs.version }}
webhook: https://api.sloppy.io/v1/apps/my-project/services/my-project/apps/my-app/deploy?user=${{ secrets.SLOPPY_USERNAME }}&auth=${{ secrets.SLOPPY_WEBHOOK_TOKEN }}
```
**Note**: th top-part `on` is just a filter on running that workflow. You can omit it but it's safer to not run it on refs that you know won't trigger anything. See [documentation](https://docs.github.com/en/free-pro-team@latest/actions/reference/workflow-syntax-for-github-actions#on).
Expand All @@ -97,6 +98,7 @@ jobs:
| `latest-on-tag` | **Whether to push to docker tag `:latest` on every matched tag** (see `tag-pattern`)<br />Also applies to `manual-tag`.<br />Value must be `true` or `false`. Defaults to `false`. |
| `manual-tag` | **Manual tag override**<br />Replaces `on-master` and `tag-pattern` if not empty.<br />Also triggers `:latest` if `latest-on-tag` is `true`. |
| `restrict-to` | **Don't push if action is run for a different repository**<br />Specify as `{owner}/{repository}`. |
| `webhook` | **URL to POST to after image is pushed**<br />Will receive a JSON POST request somewhat similar to Docker Hub webhook payload. |



Expand Down
10 changes: 10 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ inputs:
restrict-to:
description: repository path to limit this action to (ex. 'openzim/zimfarm') to prevent forks from triggering it.
required: false
webhook:
description: URL to request (POST) to after a sucessful push to registry•ies
required: false
default: ''

runs:
using: composite
Expand All @@ -69,6 +73,7 @@ runs:
MANUAL_TAG: ${{ inputs.manual-tag }}
RESTRICT_TO: ${{ inputs.restrict-to }}
DEFAULT_BRANCH: ${{ github.event.repository.default_branch }}
WEBHOOK_URL: ${{ inputs.webhook }}
DOCKER_BUILDX_VERSION: 0.5.1

- name: find tag
Expand Down Expand Up @@ -96,3 +101,8 @@ runs:
- name: docker logout
run: python3 $GITHUB_ACTION_PATH/docker_logout.py
shell: bash

- name: run webhook
run: python3 $GITHUB_ACTION_PATH/run_webhook.py
shell: bash

1 change: 1 addition & 0 deletions check_inputs.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ def main():
"MANUAL_TAG",
"RESTRICT_TO",
"DOCKER_BUILDX_VERSION",
"WEBHOOK_URL",
]

# fail early if missing this required info
Expand Down
59 changes: 59 additions & 0 deletions run_webhook.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import datetime
import json
import os
import sys
import time
import urllib.error
import urllib.request


def do_run_webhook(payload):
req = urllib.request.Request(os.getenv("WEBHOOK_URL"))
req.add_header("Content-Type", "application/json; charset=utf-8")
json_payload = json.dumps(payload).encode("utf-8")
req.add_header("Content-Length", len(json_payload))
response = urllib.request.urlopen(req, json_payload)
if response.code >= 300:
print("Unexpected HTTP {}/{} response".format(response.code, response.msg))
print(response.read().decode("UTF-8"))
return 1


def run_webhook():
latest = os.getenv("DOCKER_TAG_LATEST", "") == "true"
payload = {
"push_data": {
"pushed_at": int(datetime.datetime.now().timestamp()),
"images": [os.getenv("IMAGE_NAME")],
"tag": "latest" if latest else os.getenv("DOCKER_TAG"),
"pusher": "docker-publish-action",
},
"repository": {"repo_name": os.getenv("IMAGE_NAME")},
}
print("Calling webhook at {}".format(os.getenv("WEBHOOK_URL")))
print("---\n{}\n---".format(json.dumps(payload, indent=4)))

# webhook receiver might be fragile or have difficulties handling
# concurrent requests.
# ex: 2 close-apart requests for different apps in same sloppy project raises 409
attempts = 0
while attempts < 4:
attempts += 1
try:
return do_run_webhook(payload)
except urllib.error.HTTPError as exc:
print("Unexpected {}. {} attempts remaining".format(exc, attempts))
time.sleep(attempts * 30)
continue
print("Exhausted retry attempts")
return 1


if __name__ == "__main__":
if not os.getenv("WEBHOOK_URL"):
sys.exit(0)

if not os.getenv("DOCKER_TAG"):
print("no tag pushed, skipping.")
sys.exit(0)
sys.exit(run_webhook())

0 comments on commit 3f73418

Please sign in to comment.