Compare commits

..

No commits in common. "449656eb97a016fdf5fc115414fc58d3c4445012" and "10ad8297fb1c866f6059e97c472f6f93556b612e" have entirely different histories.

15 changed files with 48 additions and 195 deletions

View File

@ -10,18 +10,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added ### Added
* Server port can now be configured * Server port can now be configured
* Targets now have a 'kind' field describing whether it's a Git repository or a
URL to a PKGBUILD
* Targets with kind 'url' can provide a direct URL to a PKGBUILD instead of
providing a Git repository
### Changed ### Changed
* Moved all API routes under `/v1` namespace * Moved all API routes under `/v1` namespace
* Renamed `vieter repos` to `vieter targets` * Renamed `vieter repos` to `vieter targets`
* Renamed `/api/v1/repos` namespace to `/api/v1/targets` * Renamed `/api/v1/repos` namespace to `/api/v1/targets`
* Branch name for 'git' targets is now optional; if not provided, the
repository will be cloned with the default branch
### Removed ### Removed

View File

@ -24,7 +24,6 @@ curl \
"data": [ "data": [
{ {
"id": 1, "id": 1,
"kind": "git",
"url": "https://aur.archlinux.org/discord-ptb.git", "url": "https://aur.archlinux.org/discord-ptb.git",
"branch": "master", "branch": "master",
"repo": "bur", "repo": "bur",
@ -70,7 +69,6 @@ curl \
"message": "", "message": "",
"data": { "data": {
"id": 1, "id": 1,
"kind": "git",
"url": "https://aur.archlinux.org/discord-ptb.git", "url": "https://aur.archlinux.org/discord-ptb.git",
"branch": "master", "branch": "master",
"repo": "bur", "repo": "bur",
@ -110,7 +108,6 @@ Create a new target with the given data.
Parameter | Description Parameter | Description
--------- | ----------- --------- | -----------
kind | Kind of target to add; one of 'git', 'url'.
url | URL of the Git repository. url | URL of the Git repository.
branch | Branch of the Git repository. branch | Branch of the Git repository.
repo | Vieter repository to publish built packages to. repo | Vieter repository to publish built packages to.
@ -135,7 +132,6 @@ id | id of target to modify
Parameter | Description Parameter | Description
--------- | ----------- --------- | -----------
kind | Kind of target; one of 'git', 'url'.
url | URL of the Git repository. url | URL of the Git repository.
branch | Branch of the Git repository. branch | Branch of the Git repository.
repo | Vieter repository to publish built packages to. repo | Vieter repository to publish built packages to.

View File

@ -20,24 +20,24 @@ pages](https://rustybever.be/man/vieter/vieter-targets.1.html) describe this in
greater detail, but the basic usage is as follows: greater detail, but the basic usage is as follows:
``` ```
vieter targets add some-url some-repository vieter targets add some-url some-branch some-repository
``` ```
Here, `some-url` is the URL of the Git repository containing the PKGBUILD. This Here, `some-url` is the URL of the Git repository containing the PKGBUILD. This
URL is passed to `git clone`, meaning the repository should be public. Vieter URL is passed to `git clone`, meaning the repository should be public. Vieter
expects the same format as an AUR Git repository, so you can directly use AUR expects the same format as an AUR Git repository, so you can directly use AUR
URLs here. Alternatively, you can also provide the URL to a PKGBUILD file URLs here.
instead. See
[vieter-targets-add(1)](https://rustybever.be/man/vieter/vieter-targets-add.1.html)
for more information.
`some-repo` is the repository to which the built package archives should be `some-branch` is the branch of the Git repository the build should check out.
published. If you're using an AUR package, this should be `master`.
Finally, `some-repo` is the repository to which the built package archives
should be published.
The above command intentionally leaves out a few parameters to make the CLI The above command intentionally leaves out a few parameters to make the CLI
more useable. For information on how to modify all parameters using the CLI, more useable. For information on how to modify all parameters using the CLI,
see see
[vieter-targets(1)](https://rustybever.be/man/vieter/vieter-targets.1.html). [vieter-targets-edit(1)](https://rustybever.be/man/vieter/vieter-targets-edit.1.html).
## Reading logs ## Reading logs

View File

@ -4,8 +4,8 @@ echo -e '+ pacman -Syu --needed --noconfirm'
pacman -Syu --needed --noconfirm pacman -Syu --needed --noconfirm
echo -e '+ su builder' echo -e '+ su builder'
su builder su builder
echo -e '+ git clone --single-branch --depth 1 '\''https://examplerepo.com'\'' repo' echo -e '+ git clone --single-branch --depth 1 --branch main https://examplerepo.com repo'
git clone --single-branch --depth 1 'https://examplerepo.com' repo git clone --single-branch --depth 1 --branch main https://examplerepo.com repo
echo -e '+ cd repo' echo -e '+ cd repo'
cd repo cd repo
echo -e '+ makepkg --nobuild --syncdeps --needed --noconfirm' echo -e '+ makepkg --nobuild --syncdeps --needed --noconfirm'

View File

@ -1,20 +0,0 @@
echo -e '+ echo -e '\''[vieter]\\nServer = https://example.com/$repo/$arch\\nSigLevel = Optional'\'' >> /etc/pacman.conf'
echo -e '[vieter]\nServer = https://example.com/$repo/$arch\nSigLevel = Optional' >> /etc/pacman.conf
echo -e '+ pacman -Syu --needed --noconfirm'
pacman -Syu --needed --noconfirm
echo -e '+ su builder'
su builder
echo -e '+ git clone --single-branch --depth 1 --branch main '\''https://examplerepo.com'\'' repo'
git clone --single-branch --depth 1 --branch main 'https://examplerepo.com' repo
echo -e '+ cd repo'
cd repo
echo -e '+ makepkg --nobuild --syncdeps --needed --noconfirm'
makepkg --nobuild --syncdeps --needed --noconfirm
echo -e '+ source PKGBUILD'
source PKGBUILD
echo -e '+ curl -s --head --fail https://example.com/vieter/x86_64/$pkgname-$pkgver-$pkgrel && exit 0'
curl -s --head --fail https://example.com/vieter/x86_64/$pkgname-$pkgver-$pkgrel && exit 0
echo -e '+ [ "$(id -u)" == 0 ] && exit 0'
[ "$(id -u)" == 0 ] && exit 0
echo -e '+ MAKEFLAGS="-j$(nproc)" makepkg -s --noconfirm --needed && for pkg in $(ls -1 *.pkg*); do curl -XPOST -T "$pkg" -H "X-API-KEY: $API_KEY" https://example.com/vieter/publish; done'
MAKEFLAGS="-j$(nproc)" makepkg -s --noconfirm --needed && for pkg in $(ls -1 *.pkg*); do curl -XPOST -T "$pkg" -H "X-API-KEY: $API_KEY" https://example.com/vieter/publish; done

View File

@ -1,22 +0,0 @@
echo -e '+ echo -e '\''[vieter]\\nServer = https://example.com/$repo/$arch\\nSigLevel = Optional'\'' >> /etc/pacman.conf'
echo -e '[vieter]\nServer = https://example.com/$repo/$arch\nSigLevel = Optional' >> /etc/pacman.conf
echo -e '+ pacman -Syu --needed --noconfirm'
pacman -Syu --needed --noconfirm
echo -e '+ su builder'
su builder
echo -e '+ mkdir repo'
mkdir repo
echo -e '+ curl -o repo/PKGBUILD -L '\''https://examplerepo.com'\'''
curl -o repo/PKGBUILD -L 'https://examplerepo.com'
echo -e '+ cd repo'
cd repo
echo -e '+ makepkg --nobuild --syncdeps --needed --noconfirm'
makepkg --nobuild --syncdeps --needed --noconfirm
echo -e '+ source PKGBUILD'
source PKGBUILD
echo -e '+ curl -s --head --fail https://example.com/vieter/x86_64/$pkgname-$pkgver-$pkgrel && exit 0'
curl -s --head --fail https://example.com/vieter/x86_64/$pkgname-$pkgver-$pkgrel && exit 0
echo -e '+ [ "$(id -u)" == 0 ] && exit 0'
[ "$(id -u)" == 0 ] && exit 0
echo -e '+ MAKEFLAGS="-j$(nproc)" makepkg -s --noconfirm --needed && for pkg in $(ls -1 *.pkg*); do curl -XPOST -T "$pkg" -H "X-API-KEY: $API_KEY" https://example.com/vieter/publish; done'
MAKEFLAGS="-j$(nproc)" makepkg -s --noconfirm --needed && for pkg in $(ls -1 *.pkg*); do curl -XPOST -T "$pkg" -H "X-API-KEY: $API_KEY" https://example.com/vieter/publish; done

View File

@ -23,45 +23,20 @@ pub fn echo_commands(cmds []string) []string {
} }
// create_build_script generates a shell script that builds a given Target. // create_build_script generates a shell script that builds a given Target.
fn create_build_script(address string, target &Target, build_arch string) string { fn create_build_script(address string, repo &Target, build_arch string) string {
repo_url := '$address/$target.repo' repo_url := '$address/$repo.repo'
mut commands := [ commands := echo_commands([
// This will later be replaced by a proper setting for changing the // This will later be replaced by a proper setting for changing the
// mirrorlist // mirrorlist
"echo -e '[$target.repo]\\nServer = $address/\$repo/\$arch\\nSigLevel = Optional' >> /etc/pacman.conf" "echo -e '[$repo.repo]\\nServer = $address/\$repo/\$arch\\nSigLevel = Optional' >> /etc/pacman.conf"
// We need to update the package list of the repo we just added above. // We need to update the package list of the repo we just added above.
// This should however not pull in a lot of packages as long as the // This should however not pull in a lot of packages as long as the
// builder image is rebuilt frequently. // builder image is rebuilt frequently.
'pacman -Syu --needed --noconfirm', 'pacman -Syu --needed --noconfirm',
// makepkg can't run as root // makepkg can't run as root
'su builder', 'su builder',
] 'git clone --single-branch --depth 1 --branch $repo.branch $repo.url repo',
commands << match target.kind {
'git' {
if target.branch == '' {
[
"git clone --single-branch --depth 1 '$target.url' repo",
]
} else {
[
"git clone --single-branch --depth 1 --branch $target.branch '$target.url' repo",
]
}
}
'url' {
[
'mkdir repo',
"curl -o repo/PKGBUILD -L '$target.url'",
]
}
else {
panic("Invalid kind. This shouldn't be possible.")
}
}
commands << [
'cd repo', 'cd repo',
'makepkg --nobuild --syncdeps --needed --noconfirm', 'makepkg --nobuild --syncdeps --needed --noconfirm',
'source PKGBUILD', 'source PKGBUILD',
@ -74,7 +49,7 @@ fn create_build_script(address string, target &Target, build_arch string) string
// we're in root so we don't proceed. // we're in root so we don't proceed.
'[ "\$(id -u)" == 0 ] && exit 0', '[ "\$(id -u)" == 0 ] && exit 0',
'MAKEFLAGS="-j\$(nproc)" makepkg -s --noconfirm --needed && for pkg in \$(ls -1 *.pkg*); do curl -XPOST -T "\$pkg" -H "X-API-KEY: \$API_KEY" $repo_url/publish; done', 'MAKEFLAGS="-j\$(nproc)" makepkg -s --noconfirm --needed && for pkg in \$(ls -1 *.pkg*); do curl -XPOST -T "\$pkg" -H "X-API-KEY: \$API_KEY" $repo_url/publish; done',
] ])
return echo_commands(commands).join('\n') return commands.join('\n')
} }

View File

@ -2,42 +2,15 @@ module build
import models { Target } import models { Target }
fn test_create_build_script_git_branch() { fn test_create_build_script() {
target := Target{ target := Target{
id: 1 id: 1
kind: 'git'
url: 'https://examplerepo.com' url: 'https://examplerepo.com'
branch: 'main' branch: 'main'
repo: 'vieter' repo: 'vieter'
} }
build_script := create_build_script('https://example.com', target, 'x86_64') build_script := create_build_script('https://example.com', target, 'x86_64')
expected := $embed_file('build_script_git_branch.sh') expected := $embed_file('build_script.sh')
assert build_script == expected.to_string().trim_space()
}
fn test_create_build_script_git() {
target := Target{
id: 1
kind: 'git'
url: 'https://examplerepo.com'
repo: 'vieter'
}
build_script := create_build_script('https://example.com', target, 'x86_64')
expected := $embed_file('build_script_git.sh')
assert build_script == expected.to_string().trim_space()
}
fn test_create_build_script_url() {
target := Target{
id: 1
kind: 'url'
url: 'https://examplerepo.com'
repo: 'vieter'
}
build_script := create_build_script('https://example.com', target, 'x86_64')
expected := $embed_file('build_script_url.sh')
assert build_script == expected.to_string().trim_space() assert build_script == expected.to_string().trim_space()
} }

View File

@ -40,17 +40,18 @@ pub fn (c &Client) get_target(id int) ?Target {
return data.data return data.data
} }
pub struct NewTarget {
kind string
url string
branch string
repo string
arch []string
}
// add_target adds a new target to the server. // add_target adds a new target to the server.
pub fn (c &Client) add_target(t NewTarget) ?Response<string> { pub fn (c &Client) add_target(url string, branch string, repo string, arch []string) ?Response<string> {
params := models.params_from<NewTarget>(t) mut params := {
'url': url
'branch': branch
'repo': repo
}
if arch.len > 0 {
params['arch'] = arch.join(',')
}
data := c.send_request<string>(Method.post, '/api/v1/targets', params)? data := c.send_request<string>(Method.post, '/api/v1/targets', params)?
return data return data

View File

@ -3,7 +3,7 @@ module targets
import cli import cli
import vieter.vconf import vieter.vconf
import cron.expression { parse_expression } import cron.expression { parse_expression }
import client { NewTarget } import client
import console import console
import models { TargetFilter } import models { TargetFilter }
@ -65,34 +65,14 @@ pub fn cmd() cli.Command {
}, },
cli.Command{ cli.Command{
name: 'add' name: 'add'
required_args: 2 required_args: 3
usage: 'url repo' usage: 'url branch repo'
description: 'Add a new target with the given URL & target repo.' description: 'Add a new Git repository target.'
flags: [
cli.Flag{
name: 'kind'
description: "Kind of target to add. Defaults to 'git' if not specified. One of 'git', 'url'."
flag: cli.FlagType.string
default_value: ['git']
},
cli.Flag{
name: 'branch'
description: "Which branch to clone; only applies to kind 'git'."
flag: cli.FlagType.string
},
]
execute: fn (cmd cli.Command) ? { execute: fn (cmd cli.Command) ? {
config_file := cmd.flags.get_string('config-file')? config_file := cmd.flags.get_string('config-file')?
conf := vconf.load<Config>(prefix: 'VIETER_', default_path: config_file)? conf := vconf.load<Config>(prefix: 'VIETER_', default_path: config_file)?
t := NewTarget{ add(conf, cmd.args[0], cmd.args[1], cmd.args[2])?
kind: cmd.flags.get_string('kind')?
url: cmd.args[0]
repo: cmd.args[1]
branch: cmd.flags.get_string('branch') or { '' }
}
add(conf, t)?
} }
}, },
cli.Command{ cli.Command{
@ -123,11 +103,11 @@ pub fn cmd() cli.Command {
name: 'edit' name: 'edit'
required_args: 1 required_args: 1
usage: 'id' usage: 'id'
description: 'Edit the target that matches the given id.' description: 'Edit the Git repository target that matches the given id.'
flags: [ flags: [
cli.Flag{ cli.Flag{
name: 'url' name: 'url'
description: 'URL value. Meaning depends on kind of target.' description: 'URL of the Git repository.'
flag: cli.FlagType.string flag: cli.FlagType.string
}, },
cli.Flag{ cli.Flag{
@ -150,11 +130,6 @@ pub fn cmd() cli.Command {
description: 'Cron schedule for repository.' description: 'Cron schedule for repository.'
flag: cli.FlagType.string flag: cli.FlagType.string
}, },
cli.Flag{
name: 'kind'
description: 'Kind of target.'
flag: cli.FlagType.string
},
] ]
execute: fn (cmd cli.Command) ? { execute: fn (cmd cli.Command) ? {
config_file := cmd.flags.get_string('config-file')? config_file := cmd.flags.get_string('config-file')?
@ -196,21 +171,22 @@ pub fn cmd() cli.Command {
fn list(conf Config, filter TargetFilter) ? { fn list(conf Config, filter TargetFilter) ? {
c := client.new(conf.address, conf.api_key) c := client.new(conf.address, conf.api_key)
repos := c.get_targets(filter)? repos := c.get_targets(filter)?
data := repos.map([it.id.str(), it.kind, it.url, it.repo]) data := repos.map([it.id.str(), it.url, it.branch, it.repo])
println(console.pretty_table(['id', 'kind', 'url', 'repo'], data)?) println(console.pretty_table(['id', 'url', 'branch', 'repo'], data)?)
} }
// add adds a new repository to the server's list. // add adds a new repository to the server's list.
fn add(conf Config, t &NewTarget) ? { fn add(conf Config, url string, branch string, repo string) ? {
c := client.new(conf.address, conf.api_key) c := client.new(conf.address, conf.api_key)
res := c.add_target(t)? res := c.add_target(url, branch, repo, [])?
println(res.message) println(res.message)
} }
// remove removes a repository from the server's list. // remove removes a repository from the server's list.
fn remove(conf Config, id string) ? { fn remove(conf Config, id string) ? {
// id, _ := get_repo_by_prefix(conf, id_prefix) ?
id_int := id.int() id_int := id.int()
if id_int != 0 { if id_int != 0 {

View File

@ -16,13 +16,9 @@ const (
migrations_up = [ migrations_up = [
$embed_file('migrations/001-initial/up.sql'), $embed_file('migrations/001-initial/up.sql'),
$embed_file('migrations/002-rename-to-targets/up.sql'), $embed_file('migrations/002-rename-to-targets/up.sql'),
$embed_file('migrations/003-target-url-type/up.sql'),
]
migrations_down = [
$embed_file('migrations/001-initial/down.sql'),
$embed_file('migrations/002-rename-to-targets/down.sql'),
$embed_file('migrations/003-target-url-type/down.sql'),
] ]
migrations_down = [$embed_file('migrations/001-initial/down.sql'),
$embed_file('migrations/002-rename-to-targets/down.sql')]
) )
// init initializes a database & adds the correct tables. // init initializes a database & adds the correct tables.

View File

@ -1,4 +0,0 @@
-- I'm not sure whether I should remove any non-git targets here. Keeping them
-- will result in invalid targets, but removing them means losing data.
ALTER TABLE Target DROP COLUMN kind;

View File

@ -1 +0,0 @@
ALTER TABLE Target ADD COLUMN kind TEXT NOT NULL DEFAULT 'git';

View File

@ -1,7 +1,5 @@
module models module models
pub const valid_kinds = ['git', 'url']
pub struct TargetArch { pub struct TargetArch {
pub: pub:
id int [primary; sql: serial] id int [primary; sql: serial]
@ -16,14 +14,11 @@ pub fn (gra &TargetArch) str() string {
pub struct Target { pub struct Target {
pub mut: pub mut:
id int [primary; sql: serial] id int [primary; sql: serial]
kind string [nonull] // URL of the Git repository
// If kind is git: URL of the Git repository
// If kind is url: URL to PKGBUILD file
url string [nonull] url string [nonull]
// Branch of the Git repository to use; only applicable when kind is git. // Branch of the Git repository to use
// If not provided, the repository is cloned with the default branch. branch string [nonull]
branch string
// Which repo the builder should publish packages to // Which repo the builder should publish packages to
repo string [nonull] repo string [nonull]
// Cron schedule describing how frequently to build the repo. // Cron schedule describing how frequently to build the repo.
@ -37,7 +32,6 @@ pub mut:
pub fn (gr &Target) str() string { pub fn (gr &Target) str() string {
mut parts := [ mut parts := [
'id: $gr.id', 'id: $gr.id',
'kind: $gr.kind',
'url: $gr.url', 'url: $gr.url',
'branch: $gr.branch', 'branch: $gr.branch',
'repo: $gr.repo', 'repo: $gr.repo',

View File

@ -52,11 +52,6 @@ fn (mut app App) v1_post_target() web.Result {
return app.json(http.Status.bad_request, new_response(err.msg())) return app.json(http.Status.bad_request, new_response(err.msg()))
} }
// Ensure someone doesn't submit an invalid kind
if new_repo.kind !in models.valid_kinds {
return app.json(http.Status.bad_request, new_response('Invalid kind.'))
}
app.db.add_target(new_repo) app.db.add_target(new_repo)
return app.json(http.Status.ok, new_response('Repo added successfully.')) return app.json(http.Status.ok, new_response('Repo added successfully.'))