diff --git a/.woodpecker/.arch.yml b/.woodpecker/.arch.yml new file mode 100644 index 00000000..03f5d29d --- /dev/null +++ b/.woodpecker/.arch.yml @@ -0,0 +1,25 @@ +platform: linux/amd64 +branches: [dev] + +pipeline: + build: + image: 'archlinux:latest' + commands: + # Update packages + - pacman -Syu --needed --noconfirm base-devel + # Create non-root user to perform build & switch to their home + - groupadd -g 1000 builder + - useradd -mg builder builder + - chown -R builder:builder "$PWD" + - "echo 'builder ALL=(ALL) NOPASSWD: ALL' >> /etc/sudoers" + - su builder + # Build the package + - makepkg -s --noconfirm --needed + + publish: + image: 'archlinux:latest' + commands: + # Publish the package + - 'curl -F "file=@$(ls *.pkg*)" -H "X-API-KEY: $VIETER_API_KEY" https://pkgs.rustybever.be/api/publish' + secrets: + - vieter_api_key diff --git a/.woodpecker/.build.yml b/.woodpecker/.build.yml index 66caa8c7..4cddc6ad 100644 --- a/.woodpecker/.build.yml +++ b/.woodpecker/.build.yml @@ -36,18 +36,34 @@ pipeline: when: event: push + cli: + image: 'chewingbever/vlang:latest' + environment: + - LDFLAGS=-static + commands: + - make cli-prod + # Make sure the binary is actually statically built + - readelf -d vieterctl + - du -h vieterctl + - '[ "$(readelf -d vieterctl | grep NEEDED | wc -l)" = 0 ]' + # This removes so much, it's amazing + - strip -s vieterctl + - du -h vieterctl + when: + event: push + upload: image: 'chewingbever/vlang:latest' secrets: [ s3_username, s3_password ] commands: # https://gist.github.com/JustinTimperio/7c7115f87b775618637d67ac911e595f - export URL=s3.rustybever.be - - export OBJ_PATH="/vieter/commits/$CI_COMMIT_SHA/vieter-$(echo '${PLATFORM}' | sed 's:/:-:g')" - export DATE="$(date -R --utc)" - export CONTENT_TYPE='application/zstd' + + - export OBJ_PATH="/vieter/commits/$CI_COMMIT_SHA/vieter-$(echo '${PLATFORM}' | sed 's:/:-:g')" - export SIG_STRING="PUT\n\n$CONTENT_TYPE\n$DATE\n$OBJ_PATH" - export SIGNATURE=`echo -en $SIG_STRING | openssl sha1 -hmac $S3_PASSWORD -binary | base64` - - > curl --silent @@ -58,5 +74,20 @@ pipeline: -H "Content-Type: $CONTENT_TYPE" -H "Authorization: AWS $S3_USERNAME:$SIGNATURE" https://$URL$OBJ_PATH + + # Also update the CLI tool + - export OBJ_PATH="/vieter/commits/$CI_COMMIT_SHA/vieterctl-$(echo '${PLATFORM}' | sed 's:/:-:g')" + - export SIG_STRING="PUT\n\n$CONTENT_TYPE\n$DATE\n$OBJ_PATH" + - export SIGNATURE=`echo -en $SIG_STRING | openssl sha1 -hmac $S3_PASSWORD -binary | base64` + - > + curl + --silent + -XPUT + -T vieterctl + -H "Host: $URL" + -H "Date: $DATE" + -H "Content-Type: $CONTENT_TYPE" + -H "Authorization: AWS $S3_USERNAME:$SIGNATURE" + https://$URL$OBJ_PATH when: event: push diff --git a/CHANGELOG.md b/CHANGELOG.md index edae68bd..9eaf477f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased](https://git.rustybever.be/Chewing_Bever/vieter) +## Changed + +* Better environment variable support + * Each env var can now be provided from a file by appending it with `_FILE` + & passing the path to the file as value + ## Added * Very basic build system @@ -15,10 +21,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * Packages are always rebuilt, even if they haven't changed * Hardcoded planning of builds * Builds are sequential -* Better environment variable support - * Each env var can now be provided from a file by appending it with `_FILE` - & passing the path to the file as value * API for managing Git repositories to build +* CLI to list, add & remove Git repos to build +* Published packages on my Vieter instance ## Fixed diff --git a/Makefile b/Makefile index bd629c93..7b0fb1b1 100644 --- a/Makefile +++ b/Makefile @@ -46,7 +46,7 @@ c: .PHONY: cli cli: dvieterctl dvieterctl: cli.v - $(V_PATH) -showcc -o dvieterctl cli.v + $(V_PATH) -showcc -g -o dvieterctl cli.v .PHONY: cli-prod cli-prod: vieterctl @@ -97,4 +97,4 @@ v/v: make -C v clean: - rm -rf 'data' 'vieter' 'dvieter' 'pvieter' 'vieter.c' + rm -rf 'data' 'vieter' 'dvieter' 'pvieter' 'vieter.c' 'dvieterctl' 'vieterctl' 'pkg' 'src/vieter' diff --git a/PKGBUILD b/PKGBUILD new file mode 100644 index 00000000..8926a635 --- /dev/null +++ b/PKGBUILD @@ -0,0 +1,40 @@ +# Maintainer: Jef Roosens + +pkgbase='vieter' +pkgname=('vieter' 'vieterctl') +pkgver=0.1.0.rc1.r45.g6d3ff8a +pkgrel=1 +depends=('glibc' 'openssl' 'libarchive' 'gc') +arch=('x86_64' 'aarch64' 'armv7') +url='https://git.rustybever.be/Chewing_Bever/vieter' +license=('AGPL3') +source=($pkgname::git+https://git.rustybever.be/Chewing_Bever/vieter#branch=dev) +md5sums=('SKIP') + +pkgver() { + cd "$pkgname" + git describe --long --tags | sed 's/^v//;s/\([^-]*-g\)/r\1/;s/-/./g' +} + +build() { + cd "$pkgname" + + # Build the compiler + CFLAGS= make v + + # Build the server & the CLI tool + make prod + make cli-prod +} + +package_vieter() { + install -dm755 "$pkgdir/usr/bin" + + install -Dm755 "$pkgbase/pvieter" "$pkgdir/usr/bin/vieter" +} + +package_vieterctl() { + install -dm755 "$pkgdir/usr/bin" + + install -Dm755 "$pkgbase/vieterctl" "$pkgdir/usr/bin/vieterctl" +} diff --git a/cli.v b/cli.v new file mode 100644 index 00000000..256b8564 --- /dev/null +++ b/cli.v @@ -0,0 +1,84 @@ +import os +import toml +import net.http + +struct Config { + address string [required] + api_key string [required] +} + +fn list(conf Config) ? { + mut req := http.new_request(http.Method.get, '$conf.address/api/repos', '') ? + req.add_custom_header('X-API-Key', conf.api_key) ? + + res := req.do() ? + + println(res.text) +} + +fn add(conf Config, args []string) ? { + if args.len < 2 { + eprintln('Not enough arguments.') + exit(1) + } + + if args.len > 2 { + eprintln('Too many arguments.') + exit(1) + } + + mut req := http.new_request(http.Method.post, '$conf.address/api/repos?url=${args[0]}&branch=${args[1]}', '') ? + req.add_custom_header('X-API-Key', conf.api_key) ? + + res := req.do() ? + + println(res.text) +} + +fn remove(conf Config, args []string) ? { + if args.len < 2 { + eprintln('Not enough arguments.') + exit(1) + } + + if args.len > 2 { + eprintln('Too many arguments.') + exit(1) + } + + mut req := http.new_request(http.Method.delete, '$conf.address/api/repos?url=${args[0]}&branch=${args[1]}', '') ? + req.add_custom_header('X-API-Key', conf.api_key) ? + + res := req.do() ? + + println(res.text) +} + +fn main() { + conf_path := os.expand_tilde_to_home('~/.vieterrc') + + if !os.is_file(conf_path) { + exit(1) + } + + conf := toml.parse_file(conf_path) ?.reflect() + + args := os.args[1..] + + if args.len == 0 { + eprintln('No action provided.') + exit(1) + } + + action := args[0] + + match action { + 'list' { list(conf) ? } + 'add' { add(conf, args[1..]) ? } + 'remove' { remove(conf, args[1..]) ? } + else { + eprintln("Invalid action '$action'.") + exit(1) + } + } +}