forked from vieter-v/vieter
				
			feat(build): show shell commands in build logs
							parent
							
								
									9f753f9c93
								
							
						
					
					
						commit
						48e2ae7645
					
				| 
						 | 
					@ -16,6 +16,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 | 
				
			||||||
    * BuildLog: filter by start & end date, repo, exit code & arch
 | 
					    * BuildLog: filter by start & end date, repo, exit code & arch
 | 
				
			||||||
* CLI flags to take advantage of above API improvements
 | 
					* CLI flags to take advantage of above API improvements
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Changed
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* Packages from target repo are available during builds
 | 
				
			||||||
 | 
					    * This can be used as a basic way to support AUR dependencies, by adding
 | 
				
			||||||
 | 
					      the dependencies to the same repository
 | 
				
			||||||
 | 
					* Every build now updates its packages first instead of solely relying on the
 | 
				
			||||||
 | 
					  updated builder image
 | 
				
			||||||
 | 
					* Build logs now show commands being executed
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## [0.3.0-alpha.2](https://git.rustybever.be/vieter/vieter/src/tag/0.3.0-alpha.2)
 | 
					## [0.3.0-alpha.2](https://git.rustybever.be/vieter/vieter/src/tag/0.3.0-alpha.2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### Added
 | 
					### Added
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -101,40 +101,19 @@ pub fn build_repo(address string, api_key string, base_image_id string, repo &Gi
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	build_arch := os.uname().machine
 | 
						build_arch := os.uname().machine
 | 
				
			||||||
 | 
						build_script := create_build_script(address, repo, build_arch)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	repo_url := '$address/$repo.repo'
 | 
						// We convert the build script into a base64 string, which then gets passed
 | 
				
			||||||
 | 
						// to the container as an env var
 | 
				
			||||||
	// TODO what to do with PKGBUILDs that build multiple packages?
 | 
						base64_script := base64.encode_str(build_script)
 | 
				
			||||||
	commands := [
 | 
					 | 
				
			||||||
		// This will later be replaced by a proper setting for changing the
 | 
					 | 
				
			||||||
		// mirrorlist
 | 
					 | 
				
			||||||
		"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.
 | 
					 | 
				
			||||||
		// This should however not pull in a lot of packages as long as the
 | 
					 | 
				
			||||||
		// builder image is rebuilt frequently.
 | 
					 | 
				
			||||||
		'pacman -Syu --needed --noconfirm',
 | 
					 | 
				
			||||||
		'su builder',
 | 
					 | 
				
			||||||
		'git clone --single-branch --depth 1 --branch $repo.branch $repo.url repo',
 | 
					 | 
				
			||||||
		'cd repo',
 | 
					 | 
				
			||||||
		'makepkg --nobuild --syncdeps --needed --noconfirm',
 | 
					 | 
				
			||||||
		'source PKGBUILD',
 | 
					 | 
				
			||||||
		// The build container checks whether the package is already
 | 
					 | 
				
			||||||
		// present on the server
 | 
					 | 
				
			||||||
		'curl -s --head --fail $repo_url/$build_arch/\$pkgname-\$pkgver-\$pkgrel && 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',
 | 
					 | 
				
			||||||
	]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// We convert the list of commands into a base64 string, which then gets
 | 
					 | 
				
			||||||
	// passed to the container as an env var
 | 
					 | 
				
			||||||
	cmds_str := base64.encode_str(commands.join('\n'))
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	c := docker.NewContainer{
 | 
						c := docker.NewContainer{
 | 
				
			||||||
		image: '$base_image_id'
 | 
							image: '$base_image_id'
 | 
				
			||||||
		env: ['BUILD_SCRIPT=$cmds_str', 'API_KEY=$api_key']
 | 
							env: ['BUILD_SCRIPT=$base64_script', 'API_KEY=$api_key']
 | 
				
			||||||
		entrypoint: ['/bin/sh', '-c']
 | 
							entrypoint: ['/bin/sh', '-c']
 | 
				
			||||||
		cmd: ['echo \$BUILD_SCRIPT | base64 -d | /bin/bash -e']
 | 
							cmd: ['echo \$BUILD_SCRIPT | base64 -d | /bin/bash -e']
 | 
				
			||||||
		work_dir: '/build'
 | 
							work_dir: '/build'
 | 
				
			||||||
		// user: 'builder:builder'
 | 
							user: '0:0'
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	id := dd.create_container(c)?.id
 | 
						id := dd.create_container(c)?.id
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,20 @@
 | 
				
			||||||
 | 
					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
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,55 @@
 | 
				
			||||||
 | 
					module build
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import models { GitRepo }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// escape_shell_string escapes any characters that could be interpreted
 | 
				
			||||||
 | 
					// incorrectly by a shell. The resulting value should be safe to use inside an
 | 
				
			||||||
 | 
					// echo statement.
 | 
				
			||||||
 | 
					fn escape_shell_string(s string) string {
 | 
				
			||||||
 | 
						return s.replace(r'\', r'\\').replace("'", r"'\''")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// echo_commands takes a list of shell commands & prepends each one with
 | 
				
			||||||
 | 
					// an echo call displaying said command.
 | 
				
			||||||
 | 
					pub fn echo_commands(cmds []string) []string {
 | 
				
			||||||
 | 
						mut out := []string{cap: 2 * cmds.len}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for cmd in cmds {
 | 
				
			||||||
 | 
							out << "echo -e '+ ${escape_shell_string(cmd)}'"
 | 
				
			||||||
 | 
							out << cmd
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return out
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// create_build_script generates a shell script that builds a given GitRepo.
 | 
				
			||||||
 | 
					fn create_build_script(address string, repo &GitRepo, build_arch string) string {
 | 
				
			||||||
 | 
						repo_url := '$address/$repo.repo'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						commands := echo_commands([
 | 
				
			||||||
 | 
							// This will later be replaced by a proper setting for changing the
 | 
				
			||||||
 | 
							// mirrorlist
 | 
				
			||||||
 | 
							"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.
 | 
				
			||||||
 | 
							// This should however not pull in a lot of packages as long as the
 | 
				
			||||||
 | 
							// builder image is rebuilt frequently.
 | 
				
			||||||
 | 
							'pacman -Syu --needed --noconfirm',
 | 
				
			||||||
 | 
							// makepkg can't run as root
 | 
				
			||||||
 | 
							'su builder',
 | 
				
			||||||
 | 
							'git clone --single-branch --depth 1 --branch $repo.branch $repo.url repo',
 | 
				
			||||||
 | 
							'cd repo',
 | 
				
			||||||
 | 
							'makepkg --nobuild --syncdeps --needed --noconfirm',
 | 
				
			||||||
 | 
							'source PKGBUILD',
 | 
				
			||||||
 | 
							// The build container checks whether the package is already present on
 | 
				
			||||||
 | 
							// the server.
 | 
				
			||||||
 | 
							'curl -s --head --fail $repo_url/$build_arch/\$pkgname-\$pkgver-\$pkgrel && exit 0',
 | 
				
			||||||
 | 
							// If the above curl command succeeds, we don't need to rebuild the
 | 
				
			||||||
 | 
							// package. However, because we're in a su shell, the exit command will
 | 
				
			||||||
 | 
							// drop us back into the root shell. Therefore, we must check whether
 | 
				
			||||||
 | 
							// we're in root so we don't proceed.
 | 
				
			||||||
 | 
							'[ "\$(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',
 | 
				
			||||||
 | 
						])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return commands.join('\n')
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,16 @@
 | 
				
			||||||
 | 
					module build
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import models { GitRepo }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn test_create_build_script() {
 | 
				
			||||||
 | 
						repo := GitRepo{
 | 
				
			||||||
 | 
							id: 1
 | 
				
			||||||
 | 
							url: 'https://examplerepo.com'
 | 
				
			||||||
 | 
							branch: 'main'
 | 
				
			||||||
 | 
							repo: 'vieter'
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						build_script := create_build_script('https://example.com', repo, 'x86_64')
 | 
				
			||||||
 | 
						expected := $embed_file('build_script.sh')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						assert build_script == expected.to_string().trim_space()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
		Reference in New Issue