Skip to content

Commit

Permalink
ADD: Github Action support
Browse files Browse the repository at this point in the history
  • Loading branch information
fileformat committed Mar 21, 2024
1 parent 8b01336 commit b917757
Show file tree
Hide file tree
Showing 6 changed files with 228 additions and 39 deletions.
25 changes: 25 additions & 0 deletions .github/action.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: go-render-template-action
description: "Greta (Go REnder Template Action) renders golang templates"
author: fileformat

branding:
icon: file-plus
color: green

inputs:
template:
description: Path to template file.
required: true
input:
description: Path to input file or `-` for stdin. Defaults to stdin.
required: false
output:
description: Path to output file. Output to stdout if not specified.
required: false
mode:
description: '`text` or `html` to select which golang template package to use. Defaults to `html`.'
required: false

runs:
using: docker
image: docker://ghcr.io/fileformat/greta:latest
50 changes: 50 additions & 0 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
name: build

on:
push:
branches:
- main

workflow_dispatch:

jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write

steps:
- name: Checkout
uses: actions/checkout@v1

- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Set some env vars for the build
run: |
TIMESTAMP=$(date -u +%Y-%m-%dT%H:%M:%SZ)
echo "COMMIT=${GITHUB_SHA:0:7}" >> $GITHUB_ENV
echo "LASTMOD=${TIMESTAMP}" >> $GITHUB_ENV
echo "VERSION=${GITHUB_SHA:0:7}" >> $GITHUB_ENV
echo "BUILTBY=GithubActions" >> $GITHUB_ENV
echo "IMAGE_NAME=fileformat/greta" >> $GITHUB_ENV
- name: Build and push
uses: docker/build-push-action@v5
with:
context: .
file: ./Dockerfile
push: true
tags: |
ghcr.io/${{ env.IMAGE_NAME }}:${{ env.VERSION }}
ghcr.io/${{ env.IMAGE_NAME }}:latest
build-args: |
COMMIT=${{ env.COMMIT }}
LASTMOD=${{ env.LASTMOD }}
VERSION=${{ env.VERSION }}
BUILTBY=${{ env.BUILTBY }}
30 changes: 30 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
FROM golang:1.22-alpine AS builder

RUN apk add --no-cache upx

RUN mkdir /build
ADD . /build/
WORKDIR /build
ARG COMMIT
ARG LASTMOD
ARG VERSION
ARG BUILTBY
RUN echo "INFO: building for $COMMIT on $LASTMOD"

ENV GO111MODULE=on \
CGO_ENABLED=0 \
GOOS=linux \
GOARCH=amd64

RUN go build \
-a \
-ldflags "-s -w -X main.commit=$COMMIT -X main.date=$LASTMOD -X main.version=$VERSION -X main.builtBy=$BUILTBY -extldflags '-static'" \
-o greta \
./greta.go \
&& upx greta

FROM scratch
COPY --from=builder /build/greta /bin/greta
WORKDIR /bin
ENTRYPOINT ["./greta"]

64 changes: 39 additions & 25 deletions greta.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ import (
)

var (
templateFile *string
inputFile *string
outputFile *string
mode *string
showVersion *bool
templateFile string
inputFile string
outputFile string
mode string
showVersion bool
version string
commit string
date string
Expand Down Expand Up @@ -61,51 +61,65 @@ func getData(inputFile string) (interface{}, error) {
}

func Main() int {
templateFile = flag.StringP("template", "t", "", "template file (required)")
inputFile = flag.StringP("input", "i", "-", "input file or '-' for stdin")
outputFile = flag.StringP("output", "o", "", "output file (or leave blank for stdout)")
mode = flag.StringP("mode", "m", "html", "mode: text or html")
showVersion = flag.BoolP("version", "v", false, "show version")

flag.Parse()
if os.Getenv("GITHUB_ACTIONS") == "true" {
templateFile = os.Getenv("INPUT_TEMPLATE")
inputFile = os.Getenv("INPUT_INPUT")
if inputFile == "" {
inputFile = "-"
}
outputFile = os.Getenv("INPUT_OUTPUT")
mode = os.Getenv("INPUT_MODE")
if mode == "" {
mode = "html"
}
} else {
flag.StringVarP(&templateFile, "template", "t", "", "template file (required)")
flag.StringVarP(&inputFile, "input", "i", "-", "input file or '-' for stdin")
flag.StringVarP(&outputFile, "output", "o", "", "output file (or leave blank for stdout)")
flag.StringVarP(&mode, "mode", "m", "html", "mode: text or html")
flag.BoolVarP(&showVersion, "version", "v", false, "show version")

if *showVersion {
fmt.Fprintf(os.Stdout, "greta v%s (from %s on %s by %s)\n", version, commit, date, builtBy)
return 0
flag.Parse()

if showVersion {
fmt.Fprintf(os.Stdout, "greta v%s (from %s on %s by %s)\n", version, commit, date, builtBy)
return 0
}
}

if *templateFile == "" {
flag.PrintDefaults()
return 0
if templateFile == "" {
fmt.Fprintf(os.Stderr, "ERROR: template is required")
return 1
}

templateFn, templateErr := getTemplateRunner(*mode, *templateFile)
templateFn, templateErr := getTemplateRunner(mode, templateFile)
if templateErr != nil {
fmt.Fprintf(os.Stderr, "ERROR: unable to parse template '%s': %s", *templateFile, templateErr)
fmt.Fprintf(os.Stderr, "ERROR: unable to parse template '%s': %s", templateFile, templateErr)
return 1
}

data, dataErr := getData(*inputFile)
data, dataErr := getData(inputFile)
if dataErr != nil {
fmt.Fprintf(os.Stderr, "ERROR: unable to read input file '%s': %s", *inputFile, dataErr)
fmt.Fprintf(os.Stderr, "ERROR: unable to read input file '%s': %s", inputFile, dataErr)
return 2
}

var output io.Writer
if *outputFile == "" {
if outputFile == "" {
output = os.Stdout
} else {
f, createErr := os.Create(*outputFile)
f, createErr := os.Create(outputFile)
if createErr != nil {
fmt.Fprintf(os.Stderr, "ERROR: unable to create output file '%s': %s", *outputFile, createErr)
fmt.Fprintf(os.Stderr, "ERROR: unable to create output file '%s': %s", outputFile, createErr)
return 3
}
defer f.Close()
output = f
}
runErr := templateFn(output, data)
if runErr != nil {
fmt.Fprintf(os.Stderr, "ERROR: unable to run template '%s': %s", *templateFile, runErr)
fmt.Fprintf(os.Stderr, "ERROR: unable to run template '%s': %s", templateFile, runErr)
return 4
}

Expand Down
67 changes: 67 additions & 0 deletions testdata/action_args.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
env GITHUB_ACTIONS=true


# all good
env INPUT_INPUT=good_input.json
env INPUT_TEMPLATE=good_template.tmpl
exec greta

# bad template
env INPUT_INPUT=good_input.json
env INPUT_TEMPLATE=bad_template.tmpl
! exec greta

# bad input
env INPUT_INPUT=bad_input.json
env INPUT_TEMPLATE=good_template.tmpl
! exec greta

# both bad
env INPUT_INPUT=bad_input.json
env INPUT_TEMPLATE=bad_template.tmpl
! exec greta

# template file does not exist
env INPUT_INPUT=good_input.json
env INPUT_TEMPLATE=bogus.tmpl
! exec greta

# data file does not exist
env INPUT_INPUT=bogus.json
env INPUT_TEMPLATE=good_template.tmpl
! exec greta


# text mode
env INPUT_INPUT=good_input.json
env INPUT_TEMPLATE=good_template.tmpl
env INPUT_MODE=text
exec greta

# html mode
env INPUT_MODE=html
exec greta

# bad mode
env INPUT_MODE=other
! exec greta

# output file
env INPUT_MODE=text
env INPUT_OUTPUT=results.txt
exec greta
exists results.txt



-- good_input.json --
{ "data": "good" }

-- bad_input.json --
this is not { json }

-- good_template.tmpl --
Value is {{.}}

-- bad_template.tmpl --
Value is {{.
31 changes: 17 additions & 14 deletions testdata/basic_args.txt
Original file line number Diff line number Diff line change
@@ -1,44 +1,47 @@
# all good
exec greta --input good_input.json --template good_template.template
exec greta --input good_input.json --template good_template.tmpl

# all good, but via stdin
stdin good_input.json
exec greta --template good_template.template
exec greta --template good_template.tmpl

# no template
! exec greta --input good_input.json

# bad template
! exec greta --input good_input.json --template bad_template.template
! exec greta --input good_input.json --template bad_template.tmpl

# bad input
! exec greta --input bad_input.json --template good_template.template
! exec greta --input bad_input.json --template good_template.tmpl

# both bad
! exec greta --input bad_input.json --template bad_template.template
! exec greta --input bad_input.json --template bad_template.tmpl

# template file does not exist
! exec greta --input good_input.json --template bogus.template
! exec greta --input good_input.json --template bogus.tmpl

# data file does not exist
! exec greta --input bogus.json --template good_template.template
! exec greta --input bogus.json --template good_template.tmpl

# version
exec greta --version
stdout '^greta v'

# text mode
exec greta --input good_input.json --template good_template.template --mode text
exec greta --input good_input.json --template good_template.tmpl --mode text

# html mode
exec greta --input good_input.json --template good_template.template --mode html
exec greta --input good_input.json --template good_template.tmpl --mode html

# bad mode
! exec greta --input good_input.json --template good_template.template --mode other
! exec greta --input good_input.json --template good_template.tmpl --mode other

# output file
exec greta --input good_input.json --template good_template.template -o results.txt
exec greta --input good_input.json --template good_template.tmpl -o results.txt
exists results.txt

# output file cannot be written
! exec greta --input good_input.json --template good_template.template -o /tmp/bogus/bogus/bogus.txt
! exec greta --input good_input.json --template good_template.tmpl -o /tmp/bogus/bogus/bogus.txt



Expand All @@ -48,8 +51,8 @@ exists results.txt
-- bad_input.json --
this is not { json }

-- good_template.template --
-- good_template.tmpl --
Value is {{.}}

-- bad_template.template --
-- bad_template.tmpl --
Value is {{.

0 comments on commit b917757

Please sign in to comment.