Browse Source

Add CI/CD (#7)

* Add CI/CD

* Fix Go 1.2.x compatibility
pull/8/head
James Mills 1 year ago
committed by GitHub
parent
commit
679fb960c9
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 22
      .chglog/CHANGELOG.tpl.md
  2. 28
      .chglog/config.yml
  3. 2
      .github/FUNDING.yml
  4. 9
      .github/labeler.yml
  5. 11
      .github/workflows/auto-approve.yml
  6. 11
      .github/workflows/autoassign.yml
  7. 24
      .github/workflows/codecov.yml
  8. 27
      .github/workflows/go.yml
  9. 43
      .github/workflows/greetings.yml
  10. 10
      .github/workflows/label.yml
  11. 33
      .github/workflows/reviewdog.yml
  12. 28
      .github/workflows/stale.yml
  13. 12
      CONTRIBUTING.md
  14. 14
      handlers.go
  15. 167
      tools/functions.sh
  16. 66
      tools/release.sh

22
.chglog/CHANGELOG.tpl.md

@ -0,0 +1,22 @@
{{ range .Versions }}
<a name="{{ .Tag.Name }}"></a>
## {{ if .Tag.Previous }}[{{ .Tag.Name }}]({{ $.Info.RepositoryURL }}/compare/{{ .Tag.Previous.Name }}...{{ .Tag.Name }}){{ else }}{{ .Tag.Name }}{{ end }} ({{ datetime "2006-01-02" .Tag.Date }})
{{ range .CommitGroups -}}
### {{ .Title }}
{{ range .Commits -}}
* {{ .Subject }}
{{ end }}
{{ end -}}
{{- if .NoteGroups -}}
{{ range .NoteGroups -}}
### {{ .Title }}
{{ range .Notes }}
{{ .Body }}
{{ end }}
{{ end -}}
{{ end -}}
{{ end -}}

28
.chglog/config.yml

@ -0,0 +1,28 @@
---
style: Github
template: CHANGELOG.tpl.md
info:
title: CHANGELOG
repository_url: https://github.com/prologic/rss2twtxt
options:
commits:
filters:
Type:
- Add
- Fix
- Update
- Document
commit_groups:
title_maps:
Add: Features
Update: Updates
Fix: Bug Fixes
Document: Documentation
header:
pattern: "^((\\w+)\\s.*)$"
pattern_maps:
- Subject
- Type
notes:
keywords:
- BREAKING CHANGE

2
.github/FUNDING.yml

@ -0,0 +1,2 @@
github: prologic
patreon: prologic

9
.github/labeler.yml

@ -0,0 +1,9 @@
documentation:
- "**/*.md"
tests:
- "**/*_test.go"
dependencies:
- g0.mod
- go.sum

11
.github/workflows/auto-approve.yml

@ -0,0 +1,11 @@
---
name: Auto approve
on: [pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: hmarr/auto-approve-action@v2.0.0
if: github.actor == 'dependabot[bot]' || github.actor == 'dependabot-preview[bot]'
with:
github-token: "${{ secrets.GITHUB_TOKEN }}"

11
.github/workflows/autoassign.yml

@ -0,0 +1,11 @@
---
name: AutoAssigner
on: [pull_request]
jobs:
assignAuthor:
runs-on: ubuntu-latest
steps:
- uses: samspills/assign-pr-to-author@v1.0
if: github.event_name == 'pull_request' && github.event.action == 'opened'
with:
repo-token: '${{ secrets.GITHUB_TOKEN }}'

24
.github/workflows/codecov.yml

@ -0,0 +1,24 @@
---
name: Coverage
on:
push:
branches:
- master
pull_request:
jobs:
test:
name: Test and Report
runs-on: ubuntu-latest
steps:
- name: Setup Go
uses: actions/setup-go@v1
with:
go-version: 1.13.x
- name: Checkout
uses: actions/checkout@v1
- name: Test
run: go test -v -cover -coverprofile=coverage.txt -covermode=atomic -race .
- name: Report
uses: codecov/codecov-action@v1
with:
token: ${{ secrets.CODECOV_TOKEN }}

27
.github/workflows/go.yml

@ -0,0 +1,27 @@
---
name: Go
on:
push:
branches:
- master
pull_request:
jobs:
test:
name: Build and Test
strategy:
matrix:
go-version: [1.12.x, 1.13.x, 1.14.x]
platform: [ubuntu-latest, macos-latest]
runs-on: ${{ matrix.platform }}
steps:
- name: Setup Go ${{ matrix.go-version }}
uses: actions/setup-go@v1
with:
go-version: ${{ matrix.go-version }}
id: go
- name: Checkout
uses: actions/checkout@v1
- name: Build
run: go build -v .
- name: Test
run: go test -v -race .

43
.github/workflows/greetings.yml

@ -0,0 +1,43 @@
---
name: Greetings
on: [pull_request, issues]
jobs:
greeting:
runs-on: ubuntu-latest
steps:
- uses: actions/first-interaction@v1
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
issue-message: |-
Hello!
Welcome to the rss2twtxt project! Someone will respond to your issue pretty quickly,
the author is pretty responsive 😀 In the meantime; please make sure you have read
the [Contributing](https://github.com/prologic/rss2twtxt/blob/master/CONTRIBUTING.md)
and [Code of Conduct](https://github.com/prologic/rss2twtxt/blob/master/CODE_OF_CONDUCT.md)
documents.
if possible please also make sure your Bug Report or Feature Request is clearly defined
with either examples or a reprodicible case (_if a bug_).
Thank you 😃
pr-message: |-
Hello!
Welcome to the rss2twtxt project!
Thank you for your Pull Request and Contribution! We highly value all contributions to this Project!
Your Pull Request will be reviewed shortly! The author is pretty responsive 😀
In the meantime; please make sure you have read
the [Contributing](https://github.com/prologic/rss2twtxt/blob/master/CONTRIBUTING.md)
and [Code of Conduct](https://github.com/prologic/rss2twtxt/blob/master/CODE_OF_CONDUCT.md)
documents.
Please also ensure that your PR passes all the CI/CD tests -- They will appear in your PR
towards the bottom just above the comment box.
Also in addition, if you haven't already; please amend your PR by modifying the
[AUTHORS](https://github.com/prologic/rss2twtxt/blob/master/AUTHORS) file and adding
yourself to it! We like to recognize and peserve in Git history all contributors!
Thank you 😃

10
.github/workflows/label.yml

@ -0,0 +1,10 @@
---
name: Labeler
on: [pull_request]
jobs:
label:
runs-on: ubuntu-latest
steps:
- uses: actions/labeler@v2
with:
repo-token: "${{ secrets.GITHUB_TOKEN }}"

33
.github/workflows/reviewdog.yml

@ -0,0 +1,33 @@
---
name: ReviewDog
on:
push:
branches:
- master
pull_request:
jobs:
golangci-lint:
name: runner / golangci-lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: reviewdog/action-golangci-lint@v1
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
misspell:
name: runner / misspell
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: reviewdog/action-misspell@v1
with:
github_token: ${{ secrets.GItHUB_TOKEN }}
shellcheck:
name: runner / shellcheck
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: reviewdog/action-shellcheck@v1
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
reporter: github-pr-review

28
.github/workflows/stale.yml

@ -0,0 +1,28 @@
---
name: Mark stale issues and pull requests
on:
schedule:
- cron: "0 0 * * *"
jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v1
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
stale-issue-message: |-
This Issue has gone stale and will be closed automatically.
If this is incorrect, please reopen and add the label `on hold`.
Thank you.
stale-pr-message: |-
This Pull Request has gone stale and will be closed automatically.
If this is incorrect, please reopen and add the label `on hold`.
Thank you.
stale-issue-label: 'stale'
exempt-issue-label: 'on hold'
stale-pr-label: 'stale'
exempt-pr-label: 'on hold'

12
CONTRIBUTING.md

@ -0,0 +1,12 @@
# Contributing
No preference. If you know how to use Github and have contributed to open source projects before then:
* File an issue
* Submit a pull request
* File an issue + Submit a pull request
* Use this project somewhere :)
Be sure to add yourself to the [AUTHORS](/AUTHORS) file when you submit your PR(s). Every contribution counts no how big or small!
Thanks for using this project!

14
handlers.go

@ -49,7 +49,7 @@ func (app *App) IndexHandler(w http.ResponseWriter, r *http.Request) {
}
if err := render("index", indexTemplate, ctx, w); err != nil {
fmt.Fprintf(w, fmt.Errorf("error %w", err).Error())
log.WithError(err).Error("error rending index template")
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
}
} else if r.Method == http.MethodPost {
@ -58,7 +58,7 @@ func (app *App) IndexHandler(w http.ResponseWriter, r *http.Request) {
if name == "" {
if err := renderMessage(w, http.StatusBadRequest, "Error", "No name supplied"); err != nil {
fmt.Fprintf(w, fmt.Errorf("error %w", err).Error())
log.WithError(err).Error("error rendering message template")
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
}
return
@ -66,7 +66,7 @@ func (app *App) IndexHandler(w http.ResponseWriter, r *http.Request) {
if url == "" {
if err := renderMessage(w, http.StatusBadRequest, "Error", "No url supplied"); err != nil {
fmt.Fprintf(w, fmt.Errorf("error %w", err).Error())
log.WithError(err).Error("error rendering message template")
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
}
return
@ -76,7 +76,7 @@ func (app *App) IndexHandler(w http.ResponseWriter, r *http.Request) {
if _, ok := app.conf.Feeds[name]; ok {
if err := renderMessage(w, http.StatusConflict, "Error", "Feed alreadyd exists"); err != nil {
fmt.Fprintf(w, fmt.Errorf("error %w", err).Error())
log.WithError(err).Error("error rendering message template")
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
}
return
@ -86,7 +86,7 @@ func (app *App) IndexHandler(w http.ResponseWriter, r *http.Request) {
if err := app.conf.Save(); err != nil {
msg := fmt.Sprintf("Could not save feed: %s", err)
if err := renderMessage(w, http.StatusInternalServerError, "Error", msg); err != nil {
fmt.Fprintf(w, fmt.Errorf("error %w", err).Error())
log.WithError(err).Error("error rendering message template")
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
}
return
@ -94,7 +94,7 @@ func (app *App) IndexHandler(w http.ResponseWriter, r *http.Request) {
msg := fmt.Sprintf("Feed successfully added %s: %s", name, url)
if err := renderMessage(w, http.StatusCreated, "Success", msg); err != nil {
fmt.Fprintf(w, fmt.Errorf("error %w", err).Error())
log.WithError(err).Error("error rendering message template")
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
}
} else {
@ -144,7 +144,7 @@ func (app *App) FeedsHandler(w http.ResponseWriter, r *http.Request) {
}
if err := render("feeds", feedsTemplate, ctx, w); err != nil {
fmt.Fprintf(w, fmt.Errorf("error %w", err).Error())
log.WithError(err).Error("error rendering feeds template")
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
}
}

167
tools/functions.sh

@ -0,0 +1,167 @@
#!/bin/sh
# This file is included by download.sh & build.sh
set -e
color() {
fg="$1"
bg="${2}"
ft="${3:-0}"
printf "\33[%s;%s;%s" "$ft" "$fg" "$bg"
}
color_reset() {
printf "\033[0m"
}
ok() {
if [ -t 1 ]; then
printf "%s[ OK ]%s\n" "$(color 37 42m 1)" "$(color_reset)"
else
printf "%s\n" "[ OK ]"
fi
}
err() {
if [ -t 1 ]; then
printf "%s[ ERR ]%s\n" "$(color 37 41m 1)" "$(color_reset)"
else
printf "%s\n" "[ ERR ]"
fi
}
run() {
retval=0
logfile="$(mktemp -t "run-XXXXXX")"
if "$@" 2> "$logfile"; then
ok
else
retval=$?
err
cat "$logfile" || true
fi
rm -rf "$logfile"
return $retval
}
progress() {
printf "%-40s" "$(printf "%s ... " "$1")"
}
log() {
printf "%s\n" "$1"
}
error() {
log "ERROR: ${1}"
}
fail() {
log "FATAL: ${1}"
exit 1
}
debug() {
log "Dropping into a shell for debugging ..."
exec /bin/sh
}
save_argv() {
for i; do
printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/"
done
echo " "
}
restore_argv() {
eval "set -- $*"
}
fnmatch() {
case "$2" in
"$1")
return 0
;;
*)
return 1
;;
esac
}
parse_version() {
r="${1}"
s="${2}"
if echo "${r}" | grep -q '^v.*'; then
# shellcheck disable=SC2001
# XXX: Need a regex group subsitutation here.
r="$(echo "${r}" | sed -e 's/^v\(.*\)/\1/')"
fi
old="$(save_argv)"
eval "set -- $(echo "${r}" | tr '-' ' ')"
v="$1"
b="$2"
if [ -z "$b" ] || fnmatch '*[!0-9]*' "$b"; then
b=
fi
eval "set -- $(echo "${v}" | tr '.' ' ')"
if [ -n "$b" ]; then
printf "%03d%s%03d%s%03d%s%03d" "$1" "$s" "$2" "$s" "$3" "$s" "$b"
else
printf "%03d%s%03d%s%03d" "$1" "$s" "$2" "$s" "$3"
fi
restore_argv "$old"
}
bump_version() {
v="$1"
n="$2"
old="$(save_argv)"
eval "set -- $(parse_version "$v" " ")"
major="${1#0*}"
minor="${2#0*}"
patch="${3#0*}"
build="${4#0*}"
restore_argv "$old"
case "$n" in
0)
major=$((major + 1))
minor=0
patch=0
[ -n "$build" ] && build=0
;;
1)
minor=$((minor + 1))
patch=0
[ -n "$build" ] && build=0
;;
2)
patch=$((patch + 1))
[ -n "$build" ] && build=0
;;
3)
if [ -n "$build" ]; then
build=$((build + 1))
fi
;;
*)
patch=$((patch + 1))
[ -n "$build" ] && build=0
;;
esac
if [ -n "$build" ]; then
printf "%d.%d.%d-%d" "$major" "$minor" "$patch" "$build"
else
printf "%d.%d.%d" "$major" "$minor" "$patch"
fi
}

66
tools/release.sh

@ -1,25 +1,57 @@
#!/bin/sh
# Get the highest tag number
VERSION="$(git describe --abbrev=0 --tags)"
VERSION=${VERSION:-'0.0.0'}
set -e
# Get number parts
MAJOR="${VERSION%%.*}"; VERSION="${VERSION#*.}"
MINOR="${VERSION%%.*}"; VERSION="${VERSION#*.}"
PATCH="${VERSION%%.*}"; VERSION="${VERSION#*.}"
# shellcheck source=./tools/functions.sh
. ./functions.sh
# Increase version
PATCH=$((PATCH+1))
TAG="${TAG}"
TAG="${1}"
generate_next_tag() {
progress "Generating next tag"
if [ "${TAG}" = "" ]; then
TAG="${MAJOR}.${MINOR}.${PATCH}"
fi
if [ -z "$TAG" ]; then
version="$(git describe --abbrev=0 --tags)"
TAG="$(bump_version "$version")"
fi
}
generate_changelog() {
progress "Generating chnagelog for $TAG"
(
git-chglog --next-tag="${TAG}" --output CHANGELOG.md
git ci -a -m "Release ${TAG}"
git push -q
) >&2
}
create_draft_release() {
progress "Creating draft release for $TAG"
(
github-release release \
-u prologic \
-r rss2twtxt \
-t "${TAG}" \
-n "${TAG}" \
-d "$(git-chglog --next-tag "${TAG}" "${TAG}" | tail -n+5)" \
--draft
) >&2
}
echo "Releasing ${TAG} ..."
steps="generate_next_tag generate_changelog create_draft_release"
git tag -a -s -m "Release ${TAG}" "${TAG}"
git push --tags
goreleaser release --rm-dist
_main() {
for step in $steps; do
if ! run "$step"; then
fail "Release failed"
fi
done
echo "🎉 All Done!"
}
if [ -n "$0" ] && [ x"$0" != x"-bash" ]; then
if ! _main "$@"; then
fail "Release failed"
fi
fi

Loading…
Cancel
Save