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

docs: add example with github deployments #7

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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,4 @@ For simplicity, each example is standalone, but may be combined as necessary to
- [Verbose Push Logging](/example-workflows/verbose-logging.yml): Verbose client-side logging may be enabled with this method. Note that this does not enable trace mode on the deploy, and simply tells the `git` client to enable verbose log output
- [Force Pushing](/example-workflows/force-push.yml): If the remote app has been previously pushed manually from a location other than CI, it may be necessary to enable force pushing to avoid git errors.
- [Review Apps](/example-workflows/review-app.yml): Handles creation and deletion of review apps through use of `dokku apps:clone` and `dokku apps:destroy`. Review apps are a great way to allow folks to preview pull request changes before they get merged to production.
- [GitHub Deployments](/example-workflows/github-deployments.yml): Deploys a codebase on push or merge to master using [GitHub Deployments](https://docs.github.com/en/free-pro-team@latest/rest/reference/repos#deployments) to record the state of the deployment.
79 changes: 79 additions & 0 deletions example-workflows/github-deployments.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
---
name: 'deploy'

# yamllint disable-line rule:truthy
on:
push:
branches:
- master

jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Cloning repo
uses: actions/checkout@v2
with:
fetch-depth: 0

- name: Create deployment
id: create_deployment
uses: octokit/request-action@v2.x
with:
route: POST /repos/:repository/deployments
repository: ${{ github.repository }}
ref: ${{ github.sha }}
environment: production
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a way to change the environment based on whether its a PR or not? Might be good to make this whole example something that uses review-apps when not master as well?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll see what I can do 👍

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've setup an example repo to play with the workflow for review apps, see badsyntax/dokku-github-actions-demo#4

The problem with using environments for review apps is you can only have one deployment per environment. So this needs some more thought. I'm still looking into this and I'll update this PR if/when I can find a solution for this.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The docs mention:

Running a workflow that references an environment that does not exist will create an environment with the referenced name.

So this could be the solution, although when i tried this without the environment existing, i was getting 404's, but I could have been missing something.

Copy link
Author

@badsyntax badsyntax Jan 26, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another approach is to use 1 environment (eg review) and set auto_inactive to false to keep existing deploys active. https://docs.github.com/en/rest/reference/repos#inactive-deployments

I like this approach more than creating new environments "on the fly" as it means we can utilise the environment deploy rules.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've made some good progress with this and GitHub Deploys are pretty awesome! We can use GitHub Deploys to request reviews before deployment, which is especially useful for review apps, as we might not want a deploy on every PR (as this open for abuse for public repos).

Capture

I'm getting close to updating this PR.

required_contexts: '[]'
production_environment: true
env:
GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}'

- name: Set deployment status to in progress
uses: octokit/request-action@v2.x
with:
route: POST /repos/:repository/deployments/:deployment/statuses
repository: ${{ github.repository }}
deployment: ${{ fromJson(steps.create_deployment.outputs.data).id }}
environment: production
environment_url: https://example.com
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you turn this into appname.example.com?

log_url: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}
state: in_progress
mediaType: '{"previews": ["flash", "ant-man"]}' # required for setting in_progress state and environment_url
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What are flash and ant-man?

Copy link
Author

@badsyntax badsyntax Jan 23, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's totally weird when you first see it 😆

As GitHub deploys is still in beta/preview these media types are required to set certain properties.

From the docs:

The inactive state and the log_url, environment_url, and auto_inactive parameters are currently available for developers to preview. Please see the blog post for full details.
To access the API during the preview period, you must provide a custom media type in the Accept header:
application/vnd.github.ant-man-preview+json

And:

To access the new environment parameter, the two new values for the state parameter (in_progress and queued), and use auto_inactive on production deployments during the public beta period, you must provide the following custom media type in the Accept header:
application/vnd.github.flash-preview+json

env:
GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}'

- name: Push to dokku
uses: dokku/github-action@master
with:
git_remote_url: 'ssh://dokku@dokku.me:22/appname'
ssh_private_key: ${{ secrets.SSH_PRIVATE_KEY }}

- name: Set deployment status to success
uses: octokit/request-action@v2.x
with:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we add an if: success() here?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Steps will only run when previous steps are successful so no need to specify if: success(), but i'll add it to make it more explicit and easier to read 👍

route: POST /repos/:repository/deployments/:deployment/statuses
repository: ${{ github.repository }}
deployment: ${{ fromJson(steps.create_deployment.outputs.data).id }}
environment: production
environment_url: https://example.com
log_url: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}
mediaType: '{"previews": ["ant-man"]}' # required for environment_url
state: success
env:
GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}'

- name: Set deployment status to failure
uses: octokit/request-action@v2.x
if: failure()
with:
route: POST /repos/:repository/deployments/:deployment/statuses
repository: ${{ github.repository }}
deployment: ${{ fromJson(steps.create_deployment.outputs.data).id }}
environment: production
environment_url: https://example.com
log_url: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}
mediaType: '{"previews": ["ant-man"]}' # required for environment_url
state: failure
env:
GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}'