Compare commits

...

62 commits
v0.1.0 ... main

Author SHA1 Message Date
Marcel S. Henselin
45a4a7e647 fix: fix linting
Some checks failed
CI / lint (push) Failing after 3m58s
CI / release (push) Successful in 6m30s
2026-04-17 17:27:40 +02:00
Marcel S. Henselin
c1349c7e40 fix: push tag was incorrect
Some checks failed
CI / lint (push) Failing after 2m16s
CI / release (push) Failing after 4m39s
2026-04-17 17:16:22 +02:00
Marcel S. Henselin
bd882b6d3e fix: push tag was incorrect
Some checks failed
CI / lint (push) Failing after 2m52s
CI / release (push) Failing after 4m1s
2026-04-17 17:11:29 +02:00
semantic-release-bot
a2d6cf9305 chore(release): 0.3.1 [skip ci]
## [0.3.1](https://stackit-solutions.git.onstackit.cloud/actions/notify/compare/v0.3.0...v0.3.1) (2026-04-17)

### Bug Fixes

* pipeline fixes ([b195a1d](b195a1dcfd))
2026-04-17 15:03:16 +00:00
Marcel S. Henselin
b195a1dcfd fix: pipeline fixes
Some checks failed
CI / lint (push) Failing after 2m12s
CI / release (push) Failing after 5m5s
2026-04-17 16:58:37 +02:00
Marcel S. Henselin
e12834bc14 chore: subtitle in notification
Some checks failed
CI / lint (push) Failing after 2m49s
CI / release (push) Failing after 4m2s
[skip-ci]
2026-04-17 16:47:33 +02:00
Marcel S. Henselin
6b34a9774b chore: pipeline adjustments
Some checks failed
CI / lint (push) Has been cancelled
CI / release (push) Has been cancelled
2026-04-17 16:44:59 +02:00
semantic-release-bot
eb96639c17 chore(release): 0.3.0 [skip ci]
# [0.3.0](https://stackit-solutions.git.onstackit.cloud/actions/notify/compare/v0.2.0...v0.3.0) (2026-04-17)

### Features

* linting ([68c1f11](68c1f11a5c))
* linting ([16a5f87](16a5f874b3))
2026-04-17 14:36:40 +00:00
Marcel S. Henselin
49fa812459 chore: pipeline adjustments
Some checks failed
CI / lint (push) Failing after 5m16s
CI / release (push) Successful in 7m23s
2026-04-17 16:30:34 +02:00
Marcel S. Henselin
68c1f11a5c feat: linting
Some checks failed
CI / lint (push) Failing after 3m46s
CI / release (push) Successful in 10m14s
2026-04-17 16:25:48 +02:00
Marcel S. Henselin
16a5f874b3 feat: linting
Some checks failed
CI / lint (push) Failing after 3m2s
CI / release (push) Successful in 6m32s
2026-04-17 16:22:05 +02:00
semantic-release-bot
e0072ca3f8 chore(release): 0.2.0 [skip ci]
# [0.2.0](https://stackit-solutions.git.onstackit.cloud/actions/notify/compare/v0.1.2...v0.2.0) (2026-04-17)

### Features

* linting ([9d4e8c9](9d4e8c9a9d))
* linting ([5b93809](5b938091d7))
* pipeline container build ([0414cf6](0414cf6dfb))
2026-04-17 14:20:41 +00:00
Marcel S. Henselin
9d4e8c9a9d feat: linting
Some checks failed
Sample Testing / my_job (push) Failing after 1m6s
CI / lint (push) Failing after 2m21s
CI / release (push) Successful in 6m17s
2026-04-17 16:15:26 +02:00
Marcel S. Henselin
5b938091d7 feat: linting
Some checks failed
Sample Testing / my_job (push) Failing after 48s
CI / lint (push) Failing after 1m49s
CI / release (push) Failing after 2m55s
2026-04-17 16:09:15 +02:00
Marcel S. Henselin
0414cf6dfb feat: pipeline container build
Some checks failed
Sample Testing / my_job (push) Failing after 1m27s
CI / lint (push) Failing after 2m51s
CI / release (push) Failing after 4m2s
2026-04-17 16:03:31 +02:00
Marcel S. Henselin
cceaea7cb7 chore: update image
Some checks failed
Sample Testing / my_job (push) Failing after 1m1s
2026-04-17 15:39:17 +02:00
Marcel S. Henselin
6b7fb1fe82 chore: update image
Some checks failed
Sample Testing / my_job (push) Has been cancelled
2026-04-17 15:37:53 +02:00
Marcel S. Henselin
15d776c790 chore: REDAME
Some checks failed
Sample Testing / my_job (push) Failing after 30s
2026-04-17 15:35:58 +02:00
Marcel S. Henselin
f51f6faf19 chore: cleanup
Some checks failed
Sample Testing / my_job (push) Failing after 38s
2026-04-17 15:30:15 +02:00
Marcel S. Henselin
141b4aba86 chore: cleanup
Some checks failed
Sample Testing / my_job (push) Failing after 1m0s
2026-04-17 15:18:40 +02:00
Marcel S. Henselin
4d0bfa2eb0 chore: cleanup
All checks were successful
Sample Testing / my_job (push) Successful in 38s
2026-04-17 15:16:23 +02:00
Marcel S. Henselin
ffd2cd4716 chore: cleanup
All checks were successful
Sample Testing / my_job (push) Successful in 39s
2026-04-17 15:11:26 +02:00
Marcel S. Henselin
ab184a741a chore: use image instead of build
All checks were successful
Sample Testing / my_job (push) Successful in 40s
2026-04-17 15:02:44 +02:00
Marcel S. Henselin
82f727210d chore: use image instead of build
All checks were successful
Sample Testing / my_job (push) Successful in 59s
2026-04-17 14:57:40 +02:00
Marcel S. Henselin
b375061648 chore: use image instead of build
Some checks failed
Sample Testing / my_job (push) Failing after 1m23s
2026-04-17 14:48:18 +02:00
Marcel S. Henselin
8f1877086c fix: fix params
Some checks failed
Sample Testing / my_job (push) Failing after 2m44s
2026-04-17 14:39:47 +02:00
Marcel S. Henselin
c9f0fc3d86 fix: fix iconslug handling
Some checks failed
Sample Testing / my_job (push) Failing after 1m30s
2026-04-17 14:24:34 +02:00
Marcel S. Henselin
d5b203cb65 fix: fix iconslug handling
All checks were successful
Sample Testing / my_job (push) Successful in 2m9s
2026-04-17 14:05:43 +02:00
Marcel S. Henselin
f4b486b99b fix: fix iconslug handling
All checks were successful
Sample Testing / my_job (push) Successful in 2m58s
2026-04-17 14:04:01 +02:00
Marcel S. Henselin
5417352afc fix: fix event body
All checks were successful
Sample Testing / my_job (push) Successful in 1m24s
2026-04-17 13:56:00 +02:00
Marcel S. Henselin
5d2272dc85 fix: fix event body
Some checks failed
Sample Testing / my_job (push) Failing after 1m47s
2026-04-17 13:52:02 +02:00
Marcel S. Henselin
de5dc0d49c fix: url params
Some checks failed
Sample Testing / my_job (push) Failing after 1m46s
2026-04-17 13:43:17 +02:00
Marcel S. Henselin
c55fad7215 fix: url params
All checks were successful
Sample Testing / my_job (push) Successful in 2m34s
2026-04-17 13:39:22 +02:00
Marcel S. Henselin
f178b6fc09 fix: url params
Some checks failed
Sample Testing / my_job (push) Failing after 1m21s
2026-04-17 13:35:51 +02:00
Marcel S. Henselin
4855b86cc4 fix: url params
Some checks failed
Sample Testing / my_job (push) Failing after 1m28s
2026-04-17 13:07:19 +02:00
Marcel S. Henselin
f9c27b01a8 fix: url params
Some checks failed
Sample Testing / my_job (push) Failing after 1m18s
2026-04-17 13:04:00 +02:00
Marcel S. Henselin
8ff3cc5034 fix: url params
Some checks failed
Sample Testing / my_job (push) Failing after 1m26s
2026-04-17 12:00:59 +02:00
Marcel S. Henselin
5d0d3eb4bd fix: url params
Some checks failed
Sample Testing / my_job (push) Failing after 1m16s
2026-04-17 11:54:43 +02:00
Marcel S. Henselin
73312c28b3 fix: url params
Some checks failed
Sample Testing / my_job (push) Failing after 1m15s
2026-04-17 11:52:27 +02:00
Marcel S. Henselin
e31a184f97 chore: test old
Some checks failed
Sample Testing / my_job (push) Failing after 1m32s
2026-04-16 13:05:21 +02:00
Marcel S. Henselin
f4d7d7c241 chore: test old
Some checks failed
Sample Testing / my_job (push) Failing after 1m50s
2026-04-16 13:01:26 +02:00
Marcel S. Henselin
7bcca643bb chore: test old
Some checks failed
Sample Testing / my_job (push) Failing after 1m45s
2026-04-16 12:23:29 +02:00
Marcel S. Henselin
2a8f2dea76 chore: test old
Some checks failed
Sample Testing / my_job (push) Failing after 1m37s
2026-04-16 12:21:31 +02:00
Marcel S. Henselin
557fde5dff chore: test old
All checks were successful
Sample Testing / my_job (push) Successful in 1m55s
2026-04-16 12:11:24 +02:00
Marcel S. Henselin
ed4f6cb7b0 chore: test old
Some checks failed
Sample Testing / my_job (push) Failing after 1m59s
2026-04-16 12:06:40 +02:00
Marcel S. Henselin
59ff5a81b4 chore: test old
All checks were successful
Sample Testing / my_job (push) Successful in 1m34s
2026-04-16 12:03:53 +02:00
Marcel S. Henselin
3d63ed4790 chore: test old
All checks were successful
Sample Testing / my_job (push) Successful in 1m52s
2026-04-16 11:55:54 +02:00
Marcel S. Henselin
d9828186fd chore: use Dockerfile
Some checks failed
Sample Testing / my_job (push) Failing after 2m31s
2026-04-16 11:34:15 +02:00
Marcel S. Henselin
ae5c8efaa0 chore: use Dockerfile
Some checks failed
Sample Testing / my_job (push) Failing after 2m29s
2026-04-16 11:16:16 +02:00
Marcel S. Henselin
0de0522a0c chore: use Dockerfile
Some checks failed
Sample Testing / my_job (push) Has been cancelled
2026-04-16 11:15:21 +02:00
Marcel S. Henselin
0303b4b9aa chore: use Dockerfile
All checks were successful
Sample Testing / my_job (push) Successful in 1m36s
2026-04-16 11:09:51 +02:00
Marcel S. Henselin
f2566ae21d chore: use Dockerfile
All checks were successful
Sample Testing / my_job (push) Successful in 2m33s
2026-04-16 10:44:30 +02:00
Marcel S. Henselin
c6521c7fcf chore: use Dockerfile
All checks were successful
Sample Testing / my_job (push) Successful in 2m3s
2026-04-16 10:34:45 +02:00
Marcel S. Henselin
eeed1a402d chore: use Dockerfile
All checks were successful
Sample Testing / my_job (push) Successful in 1m43s
2026-04-16 10:25:06 +02:00
Marcel S. Henselin
e6be735f1a chore: use Dockerfile
Some checks failed
Sample Testing / my_job (push) Failing after 1m54s
2026-04-16 10:21:35 +02:00
Marcel S. Henselin
75443b23a5 chore: use Dockerfile
Some checks failed
Sample Testing / my_job (push) Failing after 1m40s
2026-04-16 10:18:48 +02:00
Marcel S. Henselin
0b4fd7b258 chore: use Dockerfile
All checks were successful
Sample Testing / my_job (push) Successful in 45s
2026-04-16 10:15:11 +02:00
Marcel S. Henselin
96fa11f4b9 chore: use Dockerfile
All checks were successful
Sample Testing / my_job (push) Successful in 47s
2026-04-16 10:05:28 +02:00
Marcel S. Henselin
ce1a0ec40b chore: use Dockerfile
All checks were successful
Sample Testing / my_job (push) Successful in 55s
2026-04-16 09:57:33 +02:00
Marcel S. Henselin
f486b95d02 chore: new template
All checks were successful
Sample Testing / my_job (push) Successful in 58s
2026-04-16 09:52:54 +02:00
Marcel S. Henselin
a87686cb73 chore: initial release
All checks were successful
Sample Testing / my_job (push) Successful in 40s
2026-04-16 08:35:55 +02:00
Marcel S. Henselin
e194659ce8 chore: initial release
All checks were successful
Sample Testing / my_job (push) Successful in 44s
2026-04-16 08:32:07 +02:00
17 changed files with 781 additions and 142 deletions

5
.dockerignore Normal file
View file

@ -0,0 +1,5 @@
.github
.gitignore
action.yml
docker-slimbuild
main_test.go

View file

@ -1,26 +1,41 @@
name: Sample Testing name: Sample Testing
on: [push] on: [workflow_dispatch]
env:
VER: 0.3.1
jobs: jobs:
my_job: my_job:
runs-on: stackit-docker runs-on: stackit-docker
steps: steps:
- name: Checkout - name: First Chat Message
uses: actions/checkout@v6
- name: Get commit hash
if: ${{ always() }} if: ${{ always() }}
run: echo "::set-output name=sha8::$(echo ${FORGEJO_SHA} | cut -c1-8)" uses: https://stackit-solutions.git.onstackit.cloud/actions/notify@v${{ env.VER }}
id: slug
- name: Chat Setup
if: ${{ always() }}
uses: https://stackit-solutions.git.onstackit.cloud/actions/notify@v0
with: with:
project: ${{ forgejo.repository }} title: "[START] sample test (${{ forgejo.run_number }})"
commit: ${{ steps.slug.outputs.sha8 }} author: ${{ forgejo.actor }}
branch: ${{ forgejo.ref }} giturl: ${{ forgejo.server_url }}
iconslug: instacart
# status: ${{ job.status }} # optional
actionid: ${{ forgejo.run_number }}
webhook: "${{ secrets.WEBHOOK_URL }}"
# event_body: "" # optional
# - name: Force failure
# run: |
# echo "This is a force failure"
# exit 1
- name: Second Chat Message as ThreadResponse
if: ${{ always() }}
uses: https://stackit-solutions.git.onstackit.cloud/actions/notify@v0.1.2
with:
title: "[END] sample test (${{ forgejo.run_number }})"
iconslug: bun
author: ${{ forgejo.actor }}
giturl: ${{ forgejo.server_url }}
status: ${{ job.status }} status: ${{ job.status }}
actionid: ${{ forgejo.repository }}/actions/runs/${{ forgejo.run_id }} actionid: ${{ forgejo.run_number }}
webhook: "https://chat.googleapis.com/v1/spaces/AAAAYTX-Vqs/messages?key=AIzaSyDdI0hCZtE6vySjMm-WEfRq3CPzqKqqsHI&token=Iwtvo1dwg36dZgUyrUCREQGGMrO71PkIoQGafOf17Yg%3D&threadKey=git-commit" webhook: "${{ secrets.WEBHOOK_URL }}"
event_body: "this time <b>I</b> provided a body"

143
.github/workflows/release.yml vendored Normal file
View file

@ -0,0 +1,143 @@
name: CI
on:
push:
branches:
- '**'
pull_request:
branches:
- '**'
env:
VER: 0.3.1
# If a 403 error occurs, make sure to set content permission to write
# see: https://github.com/go-semantic-release/action/issues/27
permissions:
contents: write
jobs:
lint:
runs-on: stackit-docker
steps:
- name: CI checkout
uses: actions/checkout@v6
- name: Setup GO
uses: actions/setup-go@v6
with:
# go-version: 1.26
go-version-file: 'go.mod'
cache-dependency-path: 'go.sum'
- name: GO Linting
uses: golangci/golangci-lint-action@v9
with:
version: v2.11
# build:
# runs-on: stackit-docker
## strategy:
## fail-fast: true
## matrix:
## node: [10, 12]
# steps:
# - uses: actions/checkout@v6
#
# - uses: actions/setup-node@v1
# with:
# node-version: ${{ matrix.node }}
# - run: npm ci
# - run: npm test
release:
runs-on: stackit-docker
# needs: build
outputs:
tag: ${{ steps.create_release.outputs.tag }}
steps:
- name: "đź–… [START] release workflow"
if: ${{ always() }}
uses: https://stackit-solutions.git.onstackit.cloud/actions/notify@v${{ env.VER }}
with:
title: "[START] release workflow (${{ forgejo.run_number }})"
subtitle: "${{ forgejo.repostitory }}"
author: ${{ forgejo.actor }}
giturl: ${{ forgejo.server_url }}
iconslug: instacart
actionid: ${{ forgejo.run_number }}
webhook: "${{ secrets.WEBHOOK_URL }}"
- name: Checkout code
uses: actions/checkout@v6
# - name: Semantic Release
# uses: go-semantic-release/action@v1
# id: semrel
# with:
# github-token: ${{ env.FORGEJO_TOKEN }}
# allow-initial-development-versions: true
# # update-file: package.json
# changelog-file: CHANGELOG.md
# changelog-generator-opt: "emojis=true"
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Create Release
env:
FORGEJO_TOKEN: ${{ secrets.FORGEJO_TOKEN }}
id: create_release
run: |
npx \
-p semantic-release \
-p semantic-release-replace-plugin \
-p @semantic-release/commit-analyzer \
-p @semantic-release/release-notes-generator \
-p @semantic-release/changelog \
-p @semantic-release/git \
semantic-release
echo "tag=$(git describe --tags --abbrev=0)" >> $FORGEJO_OUTPUT
- name: Login to Docker Hub
if: steps.create_release.outputs.tag != ''
uses: docker/login-action@v4
with:
registry: ${{ forgejo.server_url }}
username: ${{ vars.GIT_USERNAME }}
password: ${{ secrets.GIT_PAT }}
# - name: Set up QEMU
# if: steps.semrel.outputs.version != ''
# uses: docker/setup-qemu-action@v4
- name: Set up Docker Buildx
if: steps.create_release.outputs.tag != ''
uses: docker/setup-buildx-action@v4
- name: Build only
if: steps.create_release.outputs.tag == ''
uses: docker/build-push-action@v7
with:
push: false
tags: actions/notify-slim:dev
- name: Build and push
if: steps.create_release.outputs.tag != ''
uses: docker/build-push-action@v7
with:
push: true
tags: stackit-solutions.git.onstackit.cloud/actions/notify-slim:${{ steps.create_release.outputs.tag }}
- name: "đź–… [END] release workflow"
if: ${{ always() }}
uses: https://stackit-solutions.git.onstackit.cloud/actions/notify@v${{ env.VER }}
with:
title: "[END] release workflow (${{ forgejo.run_number }})"
subtitle: "${{ forgejo.repostitory }}"
author: ${{ forgejo.actor }}
giturl: ${{ forgejo.server_url }}
iconslug: instacart
actionid: ${{ forgejo.run_number }}
webhook: "${{ secrets.WEBHOOK_URL }}"
status: 'completed'

88
.golangci.yaml Normal file
View file

@ -0,0 +1,88 @@
version: "2"
run:
concurrency: 4
output:
formats:
text:
print-linter-name: true
print-issued-lines: true
colors: true
path: stdout
linters:
enable:
- bodyclose
- depguard
- errorlint
- forcetypeassert
- gochecknoinits
- gocritic
- gosec
- misspell
- nakedret
- revive
- sqlclosecheck
- wastedassign
disable:
- noctx
- unparam
settings:
depguard:
rules:
main:
list-mode: original
allow: []
deny:
- pkg: github.com/stretchr/testify
desc: Do not use a testing framework
gocritic:
disabled-checks:
- wrapperFunc
- typeDefFirst
- ifElseChain
- dupImport
- hugeParam
enabled-tags:
- performance
- style
- experimental
gosec:
excludes:
- G104
- G102
- G304
- G307
misspell:
locale: US
nakedret:
max-func-lines: 0
revive:
severity: error
rules:
- name: errorf
- name: context-as-argument
- name: error-return
- name: increment-decrement
- name: indent-error-flow
- name: superfluous-else
- name: unused-parameter
- name: unreachable-code
- name: atomic
- name: empty-lines
- name: early-return
exclusions:
paths: []
generated: lax
warn-unused: true
# Excluding configuration per-path, per-linter, per-text and per-source.
rules:
# Exclude some linters from running on tests files.
- path: _test\.go
linters:
- gochecknoinits
formatters:
enable:
- gofmt
- goimports
# settings:
# goimports:
# local-prefixes:

78
.releaserc.json Normal file
View file

@ -0,0 +1,78 @@
{
"branches": ["main"],
"tagFormat": "v${version}",
"plugins": [
"@semantic-release/commit-analyzer",
[
"semantic-release-replace-plugin",
{
"replacements": [
{
"files": ["action.yml"],
"from": " image: 'docker://stackit-solutions.git.onstackit.cloud/actions/notify-slim:v.*'",
"to": " image: 'docker://stackit-solutions.git.onstackit.cloud/actions/notify-slim:v${nextRelease.version}'",
"results": [
{
"file": "action.yml",
"hasChanged": true,
"numMatches": 1,
"numReplacements": 1
}
],
"countMatches": true
},
{
"files": ["README.md"],
"from": " uses: https://stackit-solutions.git.onstackit.cloud/actions/notify@v.*",
"to": " uses: https://stackit-solutions.git.onstackit.cloud/actions/notify@v${nextRelease.version}",
"results": [
{
"file": "README.md",
"hasChanged": true,
"numMatches": 1,
"numReplacements": 1
}
],
"countMatches": true
},
{
"files": [".github/workflows/example.yml"],
"from": " VER: .*",
"to": " VER: ${nextRelease.version}",
"results": [
{
"file": ".github/workflows/example.yml",
"hasChanged": true,
"numMatches": 1,
"numReplacements": 1
}
],
"countMatches": true
},
{
"files": [".github/workflows/release.yml"],
"from": " VER: .*",
"to": " VER: ${nextRelease.version}",
"results": [
{
"file": ".github/workflows/release.yml",
"hasChanged": true,
"numMatches": 1,
"numReplacements": 1
}
],
"countMatches": true
}
]
}
],
"@semantic-release/release-notes-generator",
"@semantic-release/changelog",
[
"@semantic-release/git",
{
"assets": ["CHANGELOG.md", "README.md", "action.yml", ".github/workflows/example.yml", ".github/workflows/release.yml"]
}
]
]
}

23
CHANGELOG.md Normal file
View file

@ -0,0 +1,23 @@
## [0.3.1](https://stackit-solutions.git.onstackit.cloud/actions/notify/compare/v0.3.0...v0.3.1) (2026-04-17)
### Bug Fixes
* pipeline fixes ([b195a1d](https://stackit-solutions.git.onstackit.cloud/actions/notify/commit/b195a1dcfdd7bf98eaaeb976d08260a2457da317))
# [0.3.0](https://stackit-solutions.git.onstackit.cloud/actions/notify/compare/v0.2.0...v0.3.0) (2026-04-17)
### Features
* linting ([68c1f11](https://stackit-solutions.git.onstackit.cloud/actions/notify/commit/68c1f11a5cc02918166ca05e4af79712a5c0964b))
* linting ([16a5f87](https://stackit-solutions.git.onstackit.cloud/actions/notify/commit/16a5f874b341a6d4776dbe5e46be391f1d6576d8))
# [0.2.0](https://stackit-solutions.git.onstackit.cloud/actions/notify/compare/v0.1.2...v0.2.0) (2026-04-17)
### Features
* linting ([9d4e8c9](https://stackit-solutions.git.onstackit.cloud/actions/notify/commit/9d4e8c9a9dc3fcc133299e978fed191ad6052aac))
* linting ([5b93809](https://stackit-solutions.git.onstackit.cloud/actions/notify/commit/5b938091d705e01f6467cdd6be9144e491c66502))
* pipeline container build ([0414cf6](https://stackit-solutions.git.onstackit.cloud/actions/notify/commit/0414cf6dfb9956c85bb48f5217806841f5819716))

View file

@ -1,8 +1,29 @@
FROM golang:1.13 FROM golang:1.26 AS builder
WORKDIR /src RUN apt-get update && apt-get -y install upx
WORKDIR /app
ENV CGO_ENABLED=0
COPY . . COPY . .
RUN go get -u github.com/sethvargo/go-githubactions/... && go build -o /bin/google-chat-action RUN go mod tidy && go build \
-a \
-trimpath \
-ldflags "-s -w -extldflags '-static'" \
-installsuffix cgo \
-tags netgo \
-o /bin/google-chat-action \
.
RUN strip /bin/google-chat-action
RUN upx -q -9 /bin/google-chat-action
FROM scratch
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
COPY --from=builder /bin/google-chat-action /bin/google-chat-action
ENTRYPOINT ["/bin/google-chat-action"] ENTRYPOINT ["/bin/google-chat-action"]

10
Dockerfile.big Normal file
View file

@ -0,0 +1,10 @@
FROM golang:1.26
WORKDIR /src
COPY . .
RUN go get -u github.com/sethvargo/go-githubactions/... \
&& go mod tidy \
&& go build -o /bin/google-chat-action
ENTRYPOINT ["/bin/google-chat-action"]

View file

@ -13,23 +13,20 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout # ... all your steps
uses: actions/checkout@v6 - name: Sample Chat Message
if: ${{ always() }} # runs als after fails
- name: Get commit hash uses: https://stackit-solutions.git.onstackit.cloud/actions/notify@v0.3.1
if: ${{ always() }} with:
run: echo "::set-output name=sha8::$(echo ${GITHUB_SHA} | cut -c1-8)" title: "[START] sample test (${{ forgejo.run_number }})"
id: slug author: ${{ forgejo.actor }}
giturl: ${{ forgejo.server_url }}
- name: Chat Setup iconslug: instacart # optional
if: ${{ always() }} # status: ${{ job.status }} # optional
uses: https://stackit-solutions.git.onstackit.cloud/actions/notify@v0 actionid: ${{ forgejo.run_number }}
with: webhook: "${{ secrets.WEBHOOK_URL }}"
project: ${{ github.repository }} event_body: "This is a sample <b>TEXT</b><br>with a new line" # optional
commit: ${{ steps.slug.outputs.sha8 }}
branch: ${{ github.ref }}
status: ${{ job.status }}
actionid: ${{ github.repository }}/runs/${{ github.run_id }}
webhook: "https://chat.googleapis.com/v1/spaces/AAAAzPcAy4s/messages?key=AIzaSyDdI0hCZtE6vySjMm-WEfRq3CPzqKqqsHI&token=MmdzluicdrdkyUAV_QwB6BzlLcIhbfrwNzxVrEllaec%3D&threadKey=git-commit"
``` ```
TODO - icon_slug

View file

@ -1,21 +1,18 @@
name: 'Google Chat Action' name: 'Google Chat Action'
author: 'D Ther Htun' author: 'D Ther Htun/ Marcel S. Henselin'
description: 'Github actions for google chat Room Bot' description: 'Github actions for google chat Room Bot'
branding: branding:
icon: 'at-sign' icon: 'at-sign'
color: 'green' color: 'green'
inputs: inputs:
project: autor:
description: 'Github Project Name' description: 'Git Action Author'
required: true required: true
commit: giturl:
description: 'Github Commit ID' description: 'Git Server URL'
required: true
branch:
description: 'Github Branch'
required: true required: true
status: status:
description: 'Github Action Build Status' description: 'Git Action Build Status'
required: true required: true
actionid: actionid:
description: 'Current Running Action ID' description: 'Current Running Action ID'
@ -23,10 +20,14 @@ inputs:
webhook: webhook:
description: 'Google Chat Webhook URL' description: 'Google Chat Webhook URL'
required: true required: true
event_body:
description: 'Google Chat Event Body'
required: true
runs: runs:
using: 'docker' using: 'docker'
image: 'docker://dther/google-chat-action:v0.8' image: 'docker://stackit-solutions.git.onstackit.cloud/actions/notify-slim:v0.1.2'
# image: 'Dockerfile'
args: args:
- ${{ inputs.project }} - ${{ inputs.project }}
- ${{ inputs.commit }} - ${{ inputs.commit }}

View file

@ -1,30 +0,0 @@
FROM golang:1.13 AS builder
RUN apt-get update && apt-get -y install upx
#RUN mkdir -p $GOPATH/src/github.com/DTherHtun/google-chat-action
#ADD . $GOPATH/src/github.com/DTherHtun/google-chat-action
RUN go get -u github.com/sethvargo/go-githubactions/...
ENV CGO_ENABLED=0
COPY . .
RUN go build \
-a \
-trimpath \
-ldflags "-s -w -extldflags '-static'" \
-installsuffix cgo \
-tags netgo \
-o /bin/google-chat-action \
.
RUN strip /bin/google-chat-action
RUN upx -q -9 /bin/google-chat-action
FROM scratch
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
COPY --from=builder /bin/google-chat-action /bin/google-chat-action
ENTRYPOINT ["/bin/google-chat-action"]

7
go.mod
View file

@ -2,4 +2,9 @@ module google-chat-action
go 1.26.2 go 1.26.2
require github.com/sethvargo/go-githubactions v1.3.2 require (
github.com/google/go-cmp v0.7.0
github.com/sethvargo/go-githubactions v1.3.2
)
require github.com/google/uuid v1.6.0

6
go.sum Normal file
View file

@ -0,0 +1,6 @@
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/sethvargo/go-githubactions v1.3.2 h1:gkibLr/QjosgNWoCf1V58rTMRZw7xZtSB7dY4atbl1Y=
github.com/sethvargo/go-githubactions v1.3.2/go.mod h1:7/4WeHgYfSz9U5vwuToCK9KPnELVHAhGtRwLREOQV80=

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 51 KiB

Before After
Before After

230
main.go
View file

@ -2,89 +2,191 @@ package main
import ( import (
"bytes" "bytes"
_ "embed"
"fmt" "fmt"
"net/http" "net/http"
"os"
"text/template"
"github.com/google/uuid"
"github.com/sethvargo/go-githubactions" "github.com/sethvargo/go-githubactions"
) )
const (
defaultColor = "483d8b/6495ed"
successColor = "006400/228b22"
failedColor = "8b0000/dc143c"
)
//go:embed message.tpl
var message string
type templateData struct {
CardID string
IconSlug string
Title string
SubTitle string
Author string
IconUrl string
Status string
ActionID string
GitURL string
Project string
Color string
Add string
EventBody string
}
func main() { func main() {
project := githubactions.GetInput("project") data := templateData{}
if project == "" { data.CardID = uuid.NewString()
githubactions.Fatalf("Missing input 'project'") data.Add = ""
}
commit := githubactions.GetInput("commit") getData(&data)
if commit == "" {
githubactions.Fatalf("Missing input 'commit'")
}
branch := githubactions.GetInput("branch")
if branch == "" {
githubactions.Fatalf("Missing input 'branch'")
}
status := githubactions.GetInput("status")
if status == "" {
githubactions.Fatalf("Missing input 'status'")
}
actionid := githubactions.GetInput("actionid")
if actionid == "" {
githubactions.Fatalf("Missing input 'actionid'")
}
webhook := githubactions.GetInput("webhook") webhook := githubactions.GetInput("webhook")
if webhook == "" { if webhook == "" {
githubactions.Fatalf("Missing input 'webshook'") githubactions.Fatalf("Missing input 'webhook'")
os.Exit(1)
} }
joburl := githubactions.GetInput("joburl") webhook = fmt.Sprintf("%s&threadKey=notify%s&messageReplyOption=REPLY_MESSAGE_FALLBACK_TO_NEW_THREAD", webhook, data.ActionID)
if webhook == "" {
githubactions.Fatalf("Missing input 'joburl'") giturl := githubactions.GetInput("giturl")
if giturl == "" {
githubactions.Fatalf("Missing input 'giturl'")
os.Exit(1)
}
data.GitURL = giturl
body := githubactions.GetInput("event_body")
data.EventBody = body
githubactions.Infof("using URL: %s", webhook)
jsonStr, err := card(data)
if err != nil {
githubactions.Fatalf("err %s", err.Error())
os.Exit(1)
} }
fmt.Println("URL:> ", webhook)
data := `{
"cards": [
{
"header": {
"title": "GitHub Action",
"subtitle": "Build Job",
"imageUrl": "https://github.githubassets.com/images/modules/logos_page/Octocat.png",
"imageStyle": "IMAGE"
},
"sections": [
{
"widgets": [
{
"textParagraph": {
"text": "<b>Project:</b> %s<br><b>Commit-id:</b> <font color=\"#FF0000\">%s</font><br><b>Branch:</b> <font color=\"#00FF00f\">%s</font><br><b>Build Status:</b> <font color=\"#0000ff\">%s</font>"
},
"buttons": [
{
"textButton": {
"text": "Job Details",
"onClick": {
"openLink": {
"url": "https://github.com/%s"
}
}
}
}
]
}
]
}
]
}
]
}`
var jsonStr = []byte(fmt.Sprintf(data, project, commit, branch, status, actionid))
req, err := http.NewRequest("POST", webhook, bytes.NewBuffer(jsonStr)) req, err := http.NewRequest("POST", webhook, bytes.NewBuffer(jsonStr))
if err != nil { if err != nil {
panic(err) githubactions.Fatalf("error %s", err.Error())
os.Exit(1)
} }
req.Header.Set("Content-Type", "application/json; charset=UTF-8") req.Header.Set("Content-Type", "application/json; charset=UTF-8")
client := &http.Client{} client := &http.Client{}
resp, err := client.Do(req) resp, err := client.Do(req)
if err != nil { if err != nil {
panic(err) githubactions.Fatalf("error %s", err.Error())
os.Exit(1)
} }
defer resp.Body.Close() defer resp.Body.Close() //nolint:gocritic
fmt.Println("response Status:", resp.Status) fmt.Println("response Status:", resp.Status)
if resp.StatusCode != http.StatusOK {
githubactions.Infof("json: %s", jsonStr)
githubactions.Fatalf("response: %+v\n", resp)
os.Exit(1)
}
}
func getData(data *templateData) {
prj, ok := os.LookupEnv("FORGEJO_REPOSITORY")
if ok {
data.Project = prj
}
author := githubactions.GetInput("author")
if author == "" {
githubactions.Infof("[INFO] Missing input 'author', using default")
author = "STACKIT git action"
}
data.Author = author
icon := githubactions.GetInput("iconslug")
if icon == "" {
githubactions.Infof("[INFO] Missing input 'iconslug', using default")
icon = "git"
}
data.IconSlug = icon
title := githubactions.GetInput("title")
if title == "" {
githubactions.Infof("[INFO] Missing input 'title', using default")
title = "STACKIT git action"
}
data.Title = title
status := githubactions.GetInput("status")
if status == "" {
githubactions.Infof("[INFO] Missing input 'status', trying default")
var ok bool
if status, ok = os.LookupEnv("JOB_STATUS"); ok {
githubactions.Infof("[INFO] found job status")
}
}
data.Status = status
actionid := githubactions.GetInput("actionid")
if actionid == "" {
githubactions.Fatalf("Missing input 'actionid'")
os.Exit(1)
}
data.ActionID = actionid
}
func card(d templateData) ([]byte, error) {
switch d.Status {
case "success":
d.Color = successColor
case "failure":
d.Color = failedColor
default:
d.Color = defaultColor
}
if d.IconUrl == "" {
d.IconUrl = fmt.Sprintf(
"https://cdn.simpleicons.org/%s/%s",
d.IconSlug,
d.Color,
)
}
if d.EventBody == "" {
bdy := ""
if d.Project != "" {
bdy += fmt.Sprintf("<b>Project:</b> %s<br>", d.Project)
}
sha, ok := os.LookupEnv("FORGEJO_SHA")
if ok {
bdy += fmt.Sprintf("<b>Commit-id:</b> <font color='#FF0000'> %.*s</font><br>", 8, sha)
}
ref, ok := os.LookupEnv("FORGEJO_REF")
if ok {
bdy += fmt.Sprintf("<b>Branch:</b> <font color='#00FF00f'>%s</font><br>", ref)
}
if d.Status != "" {
bdy += fmt.Sprintf("<b>Build Status:</b> <font color='#0000ff'>%s</font>", d.Status)
}
d.EventBody = bdy
}
tmpl, err := template.New("message").Parse(message)
if err != nil {
return nil, err
}
buf := new(bytes.Buffer)
err = tmpl.Execute(buf, d)
if err != nil {
return nil, err
}
return buf.Bytes(), nil
} }

121
main_test.go Normal file
View file

@ -0,0 +1,121 @@
package main
import (
"encoding/json"
"testing"
"github.com/google/go-cmp/cmp"
)
func Test_card(t *testing.T) {
type args struct {
d templateData
}
tests := []struct {
name string
args args
want []byte
wantErr bool
}{
{
name: "test one",
args: args{
d: templateData{
CardID: "aed17996-84fc-45d5-9061-2c51535ae267",
Title: "test",
SubTitle: "first test",
Author: "gotest",
IconUrl: "https://github.githubassets.com/images/modules/logos_page/Octocat.png",
Project: "proj",
Status: "success",
ActionID: "123",
GitURL: "https://test.url",
Color: "c0c0c0",
EventBody: "no body",
},
},
want: []byte(`
{
"cardsV2": [
{
"cardId": "notify-aed17996-84fc-45d5-9061-2c51535ae267",
"card": {
"header": {
"title": "test",
"subtitle": "first test",
"imageUrl": "https://github.githubassets.com/images/modules/logos_page/Octocat.png",
"imageAltText": "message avatar image",
"imageType": "SQUARE"
},
"sections": [
{
"header": "test",
"collapsible": true,
"uncollapsibleWidgetsCount": 2,
"widgets": [
{
"decoratedText": {
"startIcon": {
"knownIcon": "PERSON"
},
"text": "<b>gotest</b>"
}
},
{
"textParagraph": {
"text": "no body",
"maxLines": 2
}
},
{
"buttonList": {
"buttons": [
{
"text": "View Source Event",
"type": "FILLED",
"onClick": {
"openLink": {
"url": "https://test.url/proj/actions/runs/123"
}
}
}
]
}
}
]
}
]
}
}
]
}
`),
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := card(tt.args.d)
if (err != nil) != tt.wantErr {
t.Errorf("card() error = %v, wantErr %v", err, tt.wantErr)
return
}
var gotJson any
err = json.Unmarshal(got, &gotJson)
if err != nil {
t.Fatal(err)
}
var wantJson any
err = json.Unmarshal(tt.want, &wantJson)
if err != nil {
t.Fatalf("error: %v\nsrc: %s", err, tt.want)
}
if diff := cmp.Diff(wantJson, gotJson); diff != "" {
t.Errorf("MakeGatewayInfo() mismatch (-want +got):\n%s", diff)
}
})
}
}

54
message.tpl Normal file
View file

@ -0,0 +1,54 @@
{
"cardsV2": [
{
"cardId": "notify-{{ .CardID }}",
"card": {
"header": {
"title": "{{ .Title }}",
"subtitle": "{{ .SubTitle }}",
"imageUrl": "{{ .IconUrl }}",
"imageType": "SQUARE",
"imageAltText": "message avatar image"
},
"sections": [
{
"header": "{{ .Title }}",
"collapsible": false,
"uncollapsibleWidgetsCount": 2,
"widgets": [
{
"decoratedText": {
"startIcon": {
"knownIcon": "PERSON"
},
"text": "<b>{{ .Author }}</b>"
}
},
{
"textParagraph": {
"text": "{{ .EventBody }}",
"maxLines": 5
}
},
{
"buttonList": {
"buttons": [
{
"text": "View Source Event",
"type": "FILLED",
"onClick": {
"openLink": {
"url": "{{ .GitURL }}/{{ .Project }}/actions/runs/{{ .ActionID }}"
}
}
}
]
}
}
]
}
]
}
}
]
}