Skip to content

Commit

Permalink
Initial version of ESH Template Check
Browse files Browse the repository at this point in the history
  • Loading branch information
RobertDeRose committed Nov 17, 2024
0 parents commit 64f1649
Show file tree
Hide file tree
Showing 10 changed files with 397 additions and 0 deletions.
89 changes: 89 additions & 0 deletions .github/workflows/create_release.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
name: Create Release
run-name: Creating Release

on:
push:
branches:
- main
paths:
- '**.pre-commit-hooks.yaml'

jobs:
create-release:
if: contains(github.event.head_commit.message, 'Release v')
runs-on: ubuntu-latest
outputs:
tag: ${{ steps.create-tag.outputs.TAG }}

steps:
- name: Checkout Code
uses: actions/checkout@v4

- name: Check Commit for Release
id: check_commit
run: |
# Checking Last Commit
COMMIT_MSG=$(git --no-pager log -1 --pretty=%B)
if [[ "${COMMIT_MSG}" =~ Release\ v([0-9]+\.[0-9]+\.[0-9]+) ]]; then
echo "VERSION=${BASH_REMATCH[1]}" >> "${GITHUB_ENV}"
else
echo "Not a release commit."
fi
- name: Create Tag and Release for ${{ env.VERSION }}
id: create-tag
if: ${{ env.VERSION != '' }}
env:
GITHUB_TOKEN: ${{ github.token }}
run: |
TAG="v${VERSION}"
git config user.name "GitHub Actions"
git config user.email "github-actions[bot]@users.noreply.github.com"
gh release create "${TAG}" --generate-notes
echo "TAG=${TAG}" >> "${GITHUB_OUTPUT}"
create-docker-image:
needs: create-release
if: needs.create-release.outputs.tag != ''
name: Pushlish Docker image to Docker Hub
runs-on: ubuntu-latest

steps:
- name: Check out the repo
uses: actions/checkout@v4

- name: Set up QEMU
uses: docker/setup-qemu-action@v3
with:
platforms: 'arm64'

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Log in to Docker Hub
if: github.event_name != 'pull_request'
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_TOKEN }}

- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@v5
with:
images: robertderose/esh-template-check
tags: |
type=raw,value=latest
type=raw,value=${{ needs.create-release.outputs.tag }}
- name: Build and push Docker image
uses: docker/build-push-action@v6
with:
context: .
platforms: linux/amd64,linux/arm64
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
89 changes: 89 additions & 0 deletions .github/workflows/prepare_release.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
name: Prepare Release

on:
create

jobs:
should-run:
if: startsWith(github.ref, 'refs/heads/release/')
runs-on: ubuntu-latest

outputs:
ok: ${{ steps.check_version.outputs.OK }}
version: ${{ steps.check_version.outputs.VERSION }}

steps:
- name: Checking if Should Run
id: check_version
run: |
VERSION="${GITHUB_REF_NAME#release/}"
OK=falae
[[ "${VERSION}" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] && OK=true
echo -e "OK=${OK}\nVERSION=${VERSION}" >> "${GITHUB_OUTPUT}"
prepare-release:
needs: should-run

if: ${{ needs.should-run.outputs.ok == 'true' }}
runs-on: ubuntu-latest

env:
VERSION: ${{ needs.should-run.outputs.version }}

steps:

- name: Checkout Code
uses: actions/checkout@v4

- name: Install Latest Version of ESH
run: |
mkdir -p ~/.local/bin
curl https://api.github.com/repos/jirutka/esh/tags 2>/dev/null| jq -r '.[0].tarball_url' \
| xargs curl -sSL \
| tar zxvf - -C ~/.local/bin --wildcards '*/esh' --strip-components=1 >/dev/null
sed -i 's/VERSION/ESH_VERSION/g' ~/.local/bin/esh
echo "~/.local/bin" >> "${GITHUB_PATH}"
- name: Updating Files with Tag
run: |
export TAG="v${VERSION}"
function process_templates() {
find .templates -name '*.esh' -exec realpath '{}' ';'| while read -r template; do
cd "$(dirname ${template})" || exit 1
file="${template//\/.templates/}"
file="${file%.*}"
echo "Processing ${file}"
esh -s /bin/bash -o "${file}" "${template}" || {
echo "The template '${template}' has errors"
exit 1
}
chmod --reference="${template}" "${file}"
git add "${file}"
cd - &>/dev/null || exit 1
done
}
git checkout "${GITHUB_REF_NAME}"
git config user.name "GitHub Actions"
git config user.email "github-actions[bot]@users.noreply.github.com"
process_templates
git commit -F <(printf 'Release %s\n\nCreated by %s\n' "${TAG}" "${GITHUB_ACTOR}")
git push origin "${GITHUB_REF_NAME}"
- name: Create Pull Request
env:
GITHUB_TOKEN: ${{ github.token }}
run: |
gh pr create \
--base main \
--title "Release v${VERSION}" \
--body "Release ${VERSION} was prepared by ${GITHUB_ACTOR}"
2 changes: 2 additions & 0 deletions .markdownlint.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
MD013:
line_length: 120
24 changes: 24 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0
hooks:
- id: check-executables-have-shebangs
- id: check-shebang-scripts-are-executable
- id: check-yaml
- id: end-of-file-fixer
- id: mixed-line-ending
- id: trailing-whitespace
- id: no-commit-to-branch
args: ["-branch", "-p", "main"]

- repo: https://github.com/codespell-project/codespell
rev: v2.3.0
hooks:
- id: codespell
args: ["-w"]

- repo: https://github.com/igorshubovych/markdownlint-cli
rev: v0.42.0
hooks:
- id: markdownlint
args: ["--fix"]
6 changes: 6 additions & 0 deletions .templates/.pre-commit-hooks.yaml.esh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
- id: esh-template-check
name: ESH Template Check
description: Pre-processes ESH templates, renders them with test cases, and runs optional shellcheck.
language: docker_image
entry: docker.io/robertderose/esh-template-check:<%= "${TAG}" %>
files: \.esh$
49 changes: 49 additions & 0 deletions .templates/README.md.esh
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# ESH Template Check Pre-Commit Hook

This pre-commit hook processes [`esh`](https://github.com/jirutka/esh) templates, renders them with test cases specified
in `YAML` front matter, and optionally runs [`shellcheck`](https://github.com/koalaman/shellcheck) on the generated
files.

## Features

- Parses YAML front matter to extract test cases and `shellcheck` arguments.
- Preprocesses ESH templates for each test case.
- Runs `shellcheck` with specified arguments, if provided.

## Setup

To use this hook in your repository:

1. Add this repo to your `.pre-commit-config.yaml`:

```yaml
- repo: https://github.com/RobertDeRose/esh-template-check
rev: <%= "${TAG}" %>
hooks:
- id: esh-template-check
```

### Supported Arguments

- **-k**
- Keep the generated output after running. Stores generated output in `esh_template_output`
- If you enable keeping the output, it is recommended add the above directory to your `.gitignore` file
- **-v**
- Enable verbose output when an error occurs
- **-s=SHELL**
- Override the Shell that ESH will use, by default uses Bash

### Supported Front Matter

- **check_args**
- This should be a string that will be passed in as the arguments to shellcheck
- **test_cases**
- This is an array of key/value pairs to be set as variables for the **template**

## Example Template

```bash
<% if [[ -e "_example" ]]; then -%>
<% cat _example -%>
<% fi -%>
```
23 changes: 23 additions & 0 deletions .templates/_example
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/bin/bash
<%# --- -%>
<%# check_args: -s bash -%>
<%# test_cases: -%>
<%# - VAR1: one -%>
<%# VAR2: two -%>
<%# - VAR1: a -%>
<%# VAR2: b -%>
<%# - VAR1: 1 -%>
<%# VAR2: 2 -%>
<%# --- -%>

<% if [[ "${VAR1}" =~ ^(one|a)$ ]]; then -%>
<%= "# Generating script for ${VAR2}" %>
hello_world() {
local name
<% if [[ "${VAR1}" == "one" ]]; then %>
name="Rob"
<% elif [[ "${VAR1}" == "a" ]]; then %>
name="Bob"
<% fi %>
echo "Hello ${name} you got ${VAR2}"
}
9 changes: 9 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
FROM alpine:latest

RUN apk add --no-cache esh shellcheck bash yq

COPY check.sh /usr/local/bin/check.sh

RUN chmod +x /usr/local/bin/check.sh

ENTRYPOINT ["/usr/local/bin/check.sh"]
28 changes: 28 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
BSD 3-Clause License

Copyright (c) 2024, Robert DeRose

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.

3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Loading

0 comments on commit 64f1649

Please sign in to comment.