Initial commit

This commit is contained in:
Přemysl Eric Janouch 2024-03-29 14:08:15 +01:00
commit fd6959fff8
Signed by: p
GPG Key ID: A0420B94F92B9493
9 changed files with 1378 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
/acid
/acid.1

12
LICENSE Normal file
View File

@ -0,0 +1,12 @@
Copyright (c) 2024, Přemysl Eric Janouch <p@janouch.name>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

13
Makefile Normal file
View File

@ -0,0 +1,13 @@
.POSIX:
.SUFFIXES:
version = dev
outputs = acid acid.1
all: $(outputs)
acid: acid.go
go build -ldflags "-X 'main.projectVersion=$(version)'" -o $@
acid.1: acid.adoc
asciidoctor -b manpage -a release-version=$(version) -o $@ acid.adoc
clean:
rm -f $(outputs)

27
README.adoc Normal file
View File

@ -0,0 +1,27 @@
acid
====
'acid' is A Continuous Integration Daemon.
The aim of this project is to provide a trivial CI daemon for Gitea.
I find most alternatives way too complex to set up and run in a local setting,
while the gist of it is actually very simple--run some stuff on new git commits.
'acid' provides a simple web frontend, as well as a webhook endpoint
for notifications about new commits. The daemon is supposed to be "firewalled"
by a normal HTTP server, and it will not provide TLS support to secure
communications.
'acid' runs tasks over SSH, which should be universal enough.
It can tell you the build results via any method you can put in a shell script.
Getting it to work
------------------
# apt install git golang asciidoctor
$ git clone https://git.janouch.name/p/acid.git
$ cd acid
$ make
$ man -l acid.1
You will need to write your own runner scripts, which may be nontrivial.
The author suggests using __cloud-init__-enabled virtual machines with QEMU.

80
acid.adoc Normal file
View File

@ -0,0 +1,80 @@
acid(1)
=======
:doctype: manpage
:manmanual: acid Manual
:mansource: acid {release-version}
Name
----
acid - A Continuous Integration Daemon
Synopsis
--------
*acid* [_OPTION_]... acid.yaml [_COMMAND_...]
Description
-----------
*acid* run without command arguments will start an HTTP server that creates
and executes tasks upon receiving push notifications from a Gitea instance,
according to the passed configuration file.
When a command is passed, *acid* will relay it to that running instance
as an RPC call.
Options
-------
*-version*::
Output version information and exit.
Commands
--------
*restart* _ID_...::
Schedule tasks with the given IDs to be rerun.
Configuration
-------------
For help with creating the configuration file, consult the _acid.yaml.example_
file present in the distribution.
All paths are currently relative to the directory you launch *acid* from.
The *notify*, *setup*, and *build* scripts are processed using Go's
_text/template_ package, and take an object describing the task,
which has the following fields:
*ID*::
Unique integer ID for each task.
*Owner*::
Gitea user owning the repository.
*Repo*::
Name of the repository.
*FullName*::
Full name of the repository, including the owner.
*Hash*::
Commit hash pertaining to the task.
*Runner*::
Runner ID.
*RunnerName*::
Descriptive name of the runner.
*URL*::
*acid* link to the task, where its log output can be seen.
*RepoURL*::
Gitea link to the repository.
*CommitURL*::
Gitea link to the commit.
*CloneURL*::
Gitea link for cloning the repository over HTTP.
Runners
-------
Runners receive the following additional environment variables:
*ACID_ROOT*:: The same as the base directory for configuration.
*ACID_RUNNER*:: The same as *Runner* in script templates.
Reporting bugs
--------------
Use https://git.janouch.name/p/acid to report bugs, request features,
or submit pull requests.

1157
acid.go Normal file

File diff suppressed because it is too large Load Diff

64
acid.yaml.example Normal file
View File

@ -0,0 +1,64 @@
---
# Path to an SQLite database file, which will be automatically created.
db: acid.db
# Address to listen on.
listen: :http
# Externally visible base URL that Gitea, its users, and RPC can connect to.
# The root/push endpoint accepts Gitea push notifications.
root: http://acid
# Arbitrary secret that Gitea and RPC will sign their requests with.
secret: 0123456789abcde
# Base URL of the Gitea instance.
gitea: http://gitea
# Gitea access token used for writing commit statuses back to repositories.
token: 0123456789abcdefghijklmnopqrstuvwxyzABCD
# Arbitrary sh script to notify about the results of finished tasks.
notify: |
xN irc://acid@/acid?skipjoin&usenotice <<END
{{.FullName}} {{.Hash}}: {{.RunnerName}} {{.State}} {{.URL}}
END
# List of all available runners for projects, keyed by an ID (.Runner).
runners:
arch:
# Descriptive name of the runner (.RunnerName).
name: Arch Linux
# Executable to make the runner present.
# It may spawn a container, run a virtual machine, or even just sleep.
# If it exits prematurely, the task fails.
run: runners/arch.sh
# SSH configuration for connecting to the runner.
ssh:
# Username to connect as.
user: ci
# Adress of the SSH server.
address: arch:22
# Path to an SSH private key file, which may be used for public key auth.
identity: data/id_rsa
# Arbitrary shell script to prepare the stage for project scripts.
setup: |
set -ex
sudo pacman -Syu --noconfirm git
git clone --recursive '{{.CloneURL}}' '{{.Repo}}'
cd '{{.Repo}}'
git -c advice.detachedHead=false checkout '{{.Hash}}'
# Configuration for individual Gitea repositories.
projects:
# Full repository name (.FullName, .Owner/.Repo).
owner/repo:
runners:
arch:
# Project setup script, meant to install dependencies.
setup: |
sudo pacman -S --noconfirm findutils coreutils
# Project build script.
build: |
echo Computing line count...
find . -not -path '*/.*' -type f -print0 | xargs -0 cat | wc -l

11
go.mod Normal file
View File

@ -0,0 +1,11 @@
module janouch.name/acid
go 1.22.0
require (
github.com/mattn/go-sqlite3 v1.14.22
golang.org/x/crypto v0.21.0
gopkg.in/yaml.v3 v3.0.1
)
require golang.org/x/sys v0.18.0 // indirect

12
go.sum Normal file
View File

@ -0,0 +1,12 @@
github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8=
golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=