Skip to content

Commit b3dc28a

Browse files
authored
Merge pull request #1 from hashicorp/pault/actions-yml
Migrate to new yaml actions
2 parents 537718c + 4f0bfe9 commit b3dc28a

13 files changed

Lines changed: 301 additions & 168 deletions

Dockerfile

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
FROM alpine:3
2+
3+
RUN ["/bin/sh", "-c", "apk add --update --no-cache bash ca-certificates curl git jq openssh"]
4+
5+
COPY ["src", "/src/"]
6+
7+
ENTRYPOINT ["/src/main.sh"]

README.md

Lines changed: 68 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,71 @@
11
# Sentinel GitHub Actions
22

3-
These Sentinel GitHub Actions allow you to run `sentinel test` and `fmt` on your pull requests to help you review and validate Sentinel policy changes.
4-
5-
The recommended workflow for using these actions is in the [Terraform Enterprise Sentinel VCS docs](https://www.terraform.io/docs/enterprise/sentinel/integrate-vcs.html). [tfe-policies-example](https://github.com/hashicorp/tfe-policies-example) includes an example of using these actions in practice.
6-
7-
## Example
8-
9-
```hcl
10-
workflow "Sentinel" {
11-
resolves = ["sentinel-test", "sentinel-fmt"]
12-
on = "pull_request"
13-
}
14-
15-
action "sentinel-test" {
16-
uses = "hashicorp/sentinel-github-actions/test@master"
17-
secrets = ["GITHUB_TOKEN"]
18-
env = {
19-
STL_ACTION_WORKING_DIR = "."
20-
}
21-
}
22-
23-
action "sentinel-fmt" {
24-
uses = "hashicorp/sentinel-github-actions/fmt@v0.1"
25-
secrets = ["GITHUB_TOKEN"]
26-
env = {
27-
TF_ACTION_WORKING_DIR = "."
28-
}
29-
}
3+
Sentinel GitHub Actions allow you to execute Sentinel commands within GitHub Actions.
4+
5+
The output of the actions can be viewed from the Actions tab in the main repository view. If the actions are executed on a pull request event, a comment may be posted on the pull request.
6+
7+
Sentinel GitHub Actions are a single GitHub Action that executes different Sentinel subcommands depending on the content of the GitHub Actions YAML file.
8+
9+
# Success Criteria
10+
11+
An exit code of `0` is considered a successful execution.
12+
13+
## Usage
14+
15+
The most common workflow is to run `sentinel fmt`, `sentinel test` on all of the Sentinel files in the root of the repository when a pull request is opened or updated. A comment will be posted to the pull request depending on the output of the Sentinel subcommand being executed. This workflow can be configured by adding the following content to the GitHub Actions workflow YAML file.
16+
17+
```yaml
18+
name: 'Sentinel GitHub Actions'
19+
on:
20+
- pull_request
21+
jobs:
22+
sentinel:
23+
name: 'Sentinel'
24+
runs-on: ubuntu-latest
25+
steps:
26+
- name: 'Checkout'
27+
uses: actions/checkout@master
28+
- name: 'Sentinel Format'
29+
uses: hashicorp/sentinel-github-actions@master
30+
with:
31+
stl_actions_version: 0.14.2
32+
stl_actions_subcommand: 'fmt'
33+
stl_actions_working_dir: '.'
34+
stl_actions_comment: true
35+
env:
36+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
37+
- name: 'Sentinel Test'
38+
uses: hashicorp/sentinel-github-actions@master
39+
with:
40+
stl_actions_version: 0.14.2
41+
stl_actions_subcommand: 'test'
42+
stl_actions_working_dir: '.'
43+
stl_actions_comment: true
44+
env:
45+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
3046
```
47+
48+
This was a simplified example showing the basic features of these Sentinel GitHub Actions.
49+
50+
## Inputs
51+
52+
Inputs configure Sentinel GitHub Actions to perform different actions.
53+
54+
* `stl_actions_subcommand` - (Required) The Sentinel subcommand to execute. Valid values are `fmt` and `test`.
55+
* `stl_actions_version` - (Required) The Sentinel version to install and execute. If set to `latest`, the latest stable version will be used.
56+
* `stl_actions_comment` - (Optional) Whether or not to comment on GitHub pull requests. Defaults to `true`.
57+
* `stl_actions_working_dir` - (Optional) The working directory to change into before executing Sentinel subcommands. Defaults to `.` which means use the root of the GitHub repository.
58+
59+
## Outputs
60+
61+
Outputs are used to pass information to subsequent GitHub Actions steps.
62+
63+
* `stl_actions_output` - The Sentinel outputs.
64+
65+
## Secrets
66+
67+
Secrets are similar to inputs except that they are encrypted and only used by GitHub Actions. It's a convenient way to keep sensitive data out of the GitHub Actions workflow YAML file.
68+
69+
* `GITHUB_TOKEN` - (Optional) The GitHub API token used to post comments to pull requests. Not required if the `stl_actions_comment` input is set to `false`.
70+
71+
**WARNING:** These secrets could be exposed if the action is executed on a malicious Sentinel file. To avoid this, it is recommended not to use these Sentinel GitHub Actions on repositories where untrusted users can submit pull requests.

actions.yml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
name: "Sentinel GitHub Actions"
2+
description: "Runs Sentinel commands via GitHub Actions."
3+
author: "HashiCorp, Inc. Sentinel Team <Sentinel@hashicorp.com>"
4+
branding:
5+
icon: "terminal"
6+
color: "blue"
7+
inputs:
8+
stl_actions_subcommand:
9+
description: "Sentinel subcommand to execute."
10+
required: true
11+
stl_actions_version:
12+
description: "Sentinel version to install."
13+
required: true
14+
stl_actions_comment:
15+
description: "Whether or not to comment on pull requests."
16+
default: true
17+
stl_actions_working_dir:
18+
description: "Sentinel working directory."
19+
default: "."
20+
outputs:
21+
stl_actions_output:
22+
description: "The Sentinel outputs."
23+
runs:
24+
using: "docker"
25+
image: "./Dockerfile"

fmt/Dockerfile

Lines changed: 0 additions & 15 deletions
This file was deleted.

fmt/README.md

Lines changed: 0 additions & 20 deletions
This file was deleted.

fmt/entrypoint.sh

Lines changed: 0 additions & 41 deletions
This file was deleted.

src/main.sh

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
#!/bin/bash
2+
3+
function stripColors {
4+
echo "${1}" | sed 's/\x1b\[[0-9;]*m//g'
5+
}
6+
7+
function hasPrefix {
8+
case ${2} in
9+
"${1}"*)
10+
true
11+
;;
12+
*)
13+
false
14+
;;
15+
esac
16+
}
17+
18+
function parseInputs {
19+
# Required inputs
20+
if [ "${INPUT_STL_ACTIONS_VERSION}" != "" ]; then
21+
stlVersion=${INPUT_STL_ACTIONS_VERSION}
22+
else
23+
echo "Input sentinel_version cannot be empty"
24+
exit 1
25+
fi
26+
27+
if [ "${INPUT_STL_ACTIONS_SUBCOMMAND}" != "" ]; then
28+
stlSubcommand=${INPUT_STL_ACTIONS_SUBCOMMAND}
29+
else
30+
echo "Input sentinel_subcommand cannot be empty"
31+
exit 1
32+
fi
33+
34+
# Optional inputs
35+
stlWorkingDir="."
36+
if [ "${INPUT_STL_ACTIONS_WORKING_DIR}" != "" ] || [ "${INPUT_STL_ACTIONS_WORKING_DIR}" != "." ]; then
37+
stlWorkingDir=${INPUT_STL_ACTIONS_WORKING_DIR}
38+
fi
39+
40+
stlComment=0
41+
if [ "${INPUT_STL_ACTIONS_COMMENT}" == "1" ] || [ "${INPUT_STL_ACTIONS_COMMENT}" == "true" ]; then
42+
stlComment=1
43+
fi
44+
}
45+
46+
function installSentinel {
47+
if [[ "${stlVersion}" == "latest" ]]; then
48+
echo "Checking the latest version of Sentinel"
49+
stlVersion=$(curl -sL https://releases.hashicorp.com/sentinel/index.json | jq -r '.versions[].version' | grep -v '[-].*' | sort -rV | head -n 1)
50+
51+
if [[ -z "${stlVersion}" ]]; then
52+
echo "Failed to fetch the latest version"
53+
exit 1
54+
fi
55+
fi
56+
57+
url="https://releases.hashicorp.com/sentinel/${stlVersion}/sentinel_${stlVersion}_linux_amd64.zip"
58+
59+
echo "Downloading Sentinel v${stlVersion}"
60+
curl -s -S -L -o /tmp/sentinel_${stlVersion} ${url}
61+
if [ "${?}" -ne 0 ]; then
62+
echo "Failed to download Sentinel v${stlVersion}"
63+
exit 1
64+
fi
65+
echo "Successfully downloaded Sentinel v${stlVersion}"
66+
67+
echo "Unzipping Sentinel v${stlVersion}"
68+
unzip -d /usr/local/bin /tmp/sentinel_${stlVersion} &> /dev/null
69+
if [ "${?}" -ne 0 ]; then
70+
echo "Failed to unzip Sentinel v${stlVersion}"
71+
exit 1
72+
fi
73+
echo "Successfully unzipped Sentinel v${stlVersion}"
74+
}
75+
76+
function main {
77+
# Source the other files to gain access to their functions
78+
scriptDir=$(dirname ${0})
79+
source ${scriptDir}/sentinel_fmt.sh
80+
source ${scriptDir}/sentinel_test.sh
81+
82+
parseInputs
83+
cd ${GITHUB_WORKSPACE}/${stlWorkingDir}
84+
85+
case "${stlSubcommand}" in
86+
fmt)
87+
installSentinel
88+
sentinelFmt ${*}
89+
;;
90+
test)
91+
installSentinel
92+
sentinelTest ${*}
93+
;;
94+
*)
95+
echo "Error: Must provide a valid value for sentinel_subcommand"
96+
exit 1
97+
;;
98+
esac
99+
}
100+
101+
main "${*}"

src/sentinel_fmt.sh

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
#!/bin/bash
2+
3+
function sentinelFmt {
4+
# Gather the output of `sentinel fmt`.
5+
echo "fmt: info: checking if Sentinel files in ${stlWorkingDir} are correctly formatted"
6+
fmtOutput=$(sentinel fmt -check=true -write=false ${*} 2>&1)
7+
fmtExitCode=${?}
8+
9+
# Exit code of 0 indicates success. Print the output and exit.
10+
if [ ${fmtExitCode} -eq 0 ]; then
11+
echo "fmt: info: Sentinel files in ${stlWorkingDir} are correctly formatted"
12+
echo "${fmtOutput}"
13+
echo
14+
exit ${fmtExitCode}
15+
fi
16+
17+
# Exit code of 2 indicates a parse error. Print the output and exit.
18+
if [ ${fmtExitCode} -eq 2 ]; then
19+
echo "fmt: error: failed to parse Sentinel files"
20+
echo "${fmtOutput}"
21+
echo
22+
exit ${fmtExitCode}
23+
fi
24+
25+
# Exit code of !0 and !2 indicates failure.
26+
echo "fmt: error: Sentinel files in ${stlWorkingDir} are incorrectly formatted"
27+
echo "${fmtOutput}"
28+
echo
29+
echo "fmt: error: the following files in ${stlWorkingDir} are incorrectly formatted"
30+
fmtFileList=$(sentinel fmt -check=true -write=false ${stlWorkingDir})
31+
echo "${fmtFileList}"
32+
echo
33+
34+
# Comment on the pull request if necessary.
35+
if [ "$GITHUB_EVENT_NAME" == "pull_request" ] && [ "${stlComment}" == "1" ]; then
36+
fmtComment=""
37+
for file in ${fmtFileList}; do
38+
fmtFileDiff=$(sentinel fmt -write=false "${file}" | sed -n '/@@.*/,//{/@@.*/d;p}')
39+
fmtComment="${fmtComment}
40+
<details><summary><code>${stlWorkingDir}/${file}</code></summary>
41+
\`\`\`diff
42+
${fmtFileDiff}
43+
\`\`\`
44+
</details>"
45+
46+
done
47+
48+
fmtCommentWrapper="#### \`sentinel fmt\` Failed
49+
${fmtComment}
50+
*Workflow: \`${GITHUB_WORKFLOW}\`, Action: \`${GITHUB_ACTION}\`, Working Directory: \`${stlWorkingDir}\`*"
51+
52+
fmtCommentWrapper=$(stripColors "${fmtCommentWrapper}")
53+
echo "fmt: info: creating JSON"
54+
fmtPayload=$(echo "${fmtCommentWrapper}" | jq -R --slurp '{body: .}')
55+
fmtCommentsURL=$(cat ${GITHUB_EVENT_PATH} | jq -r .pull_request.comments_url)
56+
echo "fmt: info: commenting on the pull request"
57+
echo "${fmtPayload}" | curl -s -S -H "Authorization: token ${GITHUB_TOKEN}" --header "Content-Type: application/json" --data @- "${fmtCommentsURL}" > /dev/null
58+
fi
59+
60+
exit ${fmtExitCode}
61+
}

0 commit comments

Comments
 (0)