Skip to content

Commit

Permalink
Add emojis to status updates
Browse files Browse the repository at this point in the history
  • Loading branch information
dflook committed Oct 31, 2021
1 parent 03d7093 commit 505cffe
Show file tree
Hide file tree
Showing 10 changed files with 163 additions and 9 deletions.
15 changes: 15 additions & 0 deletions .github/workflows/test-react.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
name: Test Reaction

on: [issue_comment]

jobs:
issue_comment:
if: ${{ github.event.issue.pull_request && contains(github.event.comment.user.login, 'dflook') }}
runs-on: ubuntu-latest
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
steps:
- name: Plan
uses: ./terraform-version
with:
path: tests/plan/no_changes
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ When using an action you can specify the version as:
- `@v1.18` to use the latest patch release for the specific minor version
- `@v1` to use the latest patch release for the specific major version

## Unreleased

### Changed
- When triggered by `issue_comment` or `pull_request_review_comment` events, the action will first add a :+1: reaction to the comment
- PR comment status messages lead with a single emoji that gives a progress update at a glance

## [1.18.0] - 2021-10-30

### Added
Expand Down
1 change: 1 addition & 0 deletions image/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ COPY tools/convert_version.py /usr/local/bin/convert_version
COPY tools/workspace_exists.py /usr/local/bin/workspace_exists
COPY tools/compact_plan.py /usr/local/bin/compact_plan
COPY tools/format_tf_credentials.py /usr/local/bin/format_tf_credentials
COPY tools/github_comment_react.py /usr/local/bin/github_comment_react

RUN echo "StrictHostKeyChecking no" >> /etc/ssh/ssh_config \
&& echo "IdentityFile /.ssh/id_rsa" >> /etc/ssh/ssh_config \
Expand Down
13 changes: 13 additions & 0 deletions image/actions.sh
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,10 @@ function setup() {
exit 1
fi

if ! github_comment_react +1 2>"$STEP_TMP_DIR/github_comment_react.stderr"; then
debug_file "$STEP_TMP_DIR/github_comment_react.stderr"
fi

local TERRAFORM_BIN_DIR
TERRAFORM_BIN_DIR="$JOB_TMP_DIR/terraform-bin-dir"
# tfswitch guesses the wrong home directory...
Expand Down Expand Up @@ -185,13 +189,22 @@ function init-backend() {
}

function select-workspace() {
local WORKSPACE_EXIT

set +e
(cd "$INPUT_PATH" && terraform workspace select "$INPUT_WORKSPACE") >"$STEP_TMP_DIR/workspace_select" 2>&1
WORKSPACE_EXIT=$?
set -e

if [[ -s "$STEP_TMP_DIR/workspace_select" ]]; then
start_group "Selecting workspace"
cat "$STEP_TMP_DIR/workspace_select"
end_group
fi

if [[ $WORKSPACE_EXIT -ne 0 ]]; then
exit $WORKSPACE_EXIT
fi
}

function set-common-plan-args() {
Expand Down
10 changes: 5 additions & 5 deletions image/entrypoints/apply.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ set-plan-args
PLAN_OUT="$STEP_TMP_DIR/plan.out"

if [[ -v GITHUB_TOKEN ]]; then
update_status "Applying plan in $(job_markdown_ref)"
update_status ":orange_circle: Applying plan in $(job_markdown_ref)"
fi

exec 3>&1
Expand Down Expand Up @@ -40,10 +40,10 @@ function apply() {
set -e

if [[ $APPLY_EXIT -eq 0 ]]; then
update_status "Plan applied in $(job_markdown_ref)"
update_status ":white_check_mark: Plan applied in $(job_markdown_ref)"
else
set_output failure-reason apply-failed
update_status "Error applying plan in $(job_markdown_ref)"
update_status ":x: Error applying plan in $(job_markdown_ref)"
exit 1
fi
}
Expand All @@ -69,7 +69,7 @@ fi
if [[ $PLAN_EXIT -eq 1 ]]; then
cat >&2 "$STEP_TMP_DIR/terraform_plan.stderr"

update_status "Error applying plan in $(job_markdown_ref)"
update_status ":x: Error applying plan in $(job_markdown_ref)"
exit 1
fi

Expand Down Expand Up @@ -110,7 +110,7 @@ else
else
echo "Not applying the plan - it has changed from the plan on the PR"
echo "The plan on the PR must be up to date. Alternatively, set the auto_approve input to 'true' to apply outdated plans"
update_status "Plan not applied in $(job_markdown_ref) (Plan has changed)"
update_status ":x: Plan not applied in $(job_markdown_ref) (Plan has changed)"

echo "Plan changes:"
debug_log diff "$STEP_TMP_DIR/plan.txt" "$STEP_TMP_DIR/approved-plan.txt"
Expand Down
1 change: 1 addition & 0 deletions image/entrypoints/destroy-workspace.sh
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,5 @@ workspace=$INPUT_WORKSPACE
INPUT_WORKSPACE=default
init-backend

debug_log terraform workspace delete -no-color -lock-timeout=300s "$workspace"
(cd "$INPUT_PATH" && terraform workspace delete -no-color -lock-timeout=300s "$workspace")
4 changes: 2 additions & 2 deletions image/entrypoints/plan.sh
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ if [[ "$GITHUB_EVENT_NAME" == "pull_request" || "$GITHUB_EVENT_NAME" == "issue_c
fi

if [[ $PLAN_EXIT -eq 1 ]]; then
if ! STATUS="Failed to generate plan in $(job_markdown_ref)" github_pr_comment plan <"$STEP_TMP_DIR/terraform_plan.stderr" 2>"$STEP_TMP_DIR/github_pr_comment.stderr"; then
if ! STATUS=":x: Failed to generate plan in $(job_markdown_ref)" github_pr_comment plan <"$STEP_TMP_DIR/terraform_plan.stderr" 2>"$STEP_TMP_DIR/github_pr_comment.stderr"; then
debug_file "$STEP_TMP_DIR/github_pr_comment.stderr"
exit 1
else
Expand All @@ -54,7 +54,7 @@ if [[ "$GITHUB_EVENT_NAME" == "pull_request" || "$GITHUB_EVENT_NAME" == "issue_c
TF_CHANGES=true
fi

if ! TF_CHANGES=$TF_CHANGES STATUS="Plan generated in $(job_markdown_ref)" github_pr_comment plan <"$STEP_TMP_DIR/plan.txt" 2>"$STEP_TMP_DIR/github_pr_comment.stderr"; then
if ! TF_CHANGES=$TF_CHANGES STATUS=":memo: Plan generated in $(job_markdown_ref)" github_pr_comment plan <"$STEP_TMP_DIR/plan.txt" 2>"$STEP_TMP_DIR/github_pr_comment.stderr"; then
debug_file "$STEP_TMP_DIR/github_pr_comment.stderr"
exit 1
else
Expand Down
7 changes: 5 additions & 2 deletions image/tools/convert_output.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,15 @@ def convert_to_github(outputs: Dict) -> Iterable[str]:
yield f'::set-output name={name}::{value}'

if __name__ == '__main__':

input_string = sys.stdin.read()
try:
outputs = json.load(sys.stdin)
outputs = json.loads(input_string)
if not isinstance(outputs, dict):
raise Exception('Unable to parse outputs')
except:
exit(1)
sys.stderr.write(input_string)
raise

for line in convert_to_github(outputs):
print(line)
Expand Down
109 changes: 109 additions & 0 deletions image/tools/github_comment_react.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
#!/usr/bin/python3

import datetime
import json
import os
import sys
from typing import Optional, cast, NewType, TypedDict

import requests

GitHubUrl = NewType('GitHubUrl', str)
CommentReactionUrl = NewType('CommentReactionUrl', GitHubUrl)


class GitHubActionsEnv(TypedDict):
"""
Environment variables that are set by the actions runner
"""
GITHUB_API_URL: str
GITHUB_TOKEN: str
GITHUB_EVENT_PATH: str
GITHUB_EVENT_NAME: str
GITHUB_REPOSITORY: str
GITHUB_SHA: str


job_tmp_dir = os.environ.get('JOB_TMP_DIR', '.')
step_tmp_dir = os.environ.get('STEP_TMP_DIR', '.')

env = cast(GitHubActionsEnv, os.environ)


def github_session(github_env: GitHubActionsEnv) -> requests.Session:
"""
A request session that is configured for the github API
"""
session = requests.Session()
session.headers['authorization'] = f'token {github_env["GITHUB_TOKEN"]}'
session.headers['user-agent'] = 'terraform-github-actions'
session.headers['accept'] = 'application/vnd.github.v3+json'
return session


def github_api_request(method: str, *args, **kwargs) -> requests.Response:
response = github.request(method, *args, **kwargs)

if 400 <= response.status_code < 500:
debug(str(response.headers))

try:
message = response.json()['message']

if response.headers['X-RateLimit-Remaining'] == '0':
limit_reset = datetime.datetime.fromtimestamp(int(response.headers['X-RateLimit-Reset']))
sys.stdout.write(message)
sys.stdout.write(f' Try again when the rate limit resets at {limit_reset} UTC.\n')
exit(1)

if message != 'Resource not accessible by integration':
sys.stdout.write(message)
sys.stdout.write('\n')
debug(response.content.decode())

except Exception:
sys.stdout.write(response.content.decode())
sys.stdout.write('\n')
raise

return response


def debug(msg: str) -> None:
sys.stderr.write(msg)
sys.stderr.write('\n')


def find_reaction_url(actions_env: GitHubActionsEnv) -> Optional[CommentReactionUrl]:
event_type = actions_env['GITHUB_EVENT_NAME']

if event_type not in ['issue_comment', 'pull_request_review_comment']:
return None

with open(actions_env['GITHUB_EVENT_PATH']) as f:
event = json.load(f)

return event['comment']['reactions']['url']


def react(comment_reaction_url: CommentReactionUrl, reaction_type: str) -> None:
github_api_request('post', comment_reaction_url, json={'content': reaction_type})


def main() -> None:
if len(sys.argv) < 2:
print(f'''Usage:
{sys.argv[0]} <reaction type>''')

debug(repr(sys.argv))

reaction_url = find_reaction_url(env)
if reaction_url is not None:
react(reaction_url, sys.argv[1])


if __name__ == '__main__':
if 'GITHUB_TOKEN' not in env:
exit(0)
github = github_session(env)
main()
6 changes: 6 additions & 0 deletions tests/target/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,18 @@ resource "random_string" "count" {
count = 1

length = var.length

special = false
min_special = 0
}

resource "random_string" "foreach" {
for_each = toset(["hello"])

length = var.length

special = false
min_special = 0
}

variable "length" {
Expand Down

0 comments on commit 505cffe

Please sign in to comment.