ci

package
v1.10.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 21, 2026 License: MIT Imports: 2 Imported by: 0

README

ffsend CI/CD Pipeline

This is ffsend's CI/CD pipeline, imported from timvisee/ffsend.

Overview

ffsend is a fully featured Firefox Send client - a command-line tool for secure, encrypted file sharing. This pipeline demonstrates Rust CLI application development and distribution.

Pipeline Characteristics

  • Project ID: 5664378
  • Lines of Code: ~139 lines
  • Language: Rust
  • Features Demonstrated:
    • Rust cross-compilation
    • Multi-platform binary builds (Linux, macOS, Windows)
    • Static binary creation
    • CLI testing
    • Release automation

Key Features

Cross-Platform Builds

Comprehensive cross-compilation for multiple platforms and architectures.

Static Binaries

Creates standalone static binaries for easy distribution.

CLI Testing

Tests command-line interface across different platforms.

Release Automation

Automated binary releases with checksums and signatures.

What You Can Learn

  1. Rust CLI development - Building command-line tools in Rust
  2. Cross-compilation - Compiling for multiple platforms
  3. Static linking - Creating standalone binaries
  4. CLI testing - Testing command-line applications
  5. Secure file transfer - Implementing encryption in CLI tools

Source

Building This Example

cat pipeline.go
mkdir my-ffsend-pipeline && cp pipeline.go my-ffsend-pipeline/
cd my-ffsend-pipeline && go mod init example/my-ffsend-pipeline && go mod tidy

Documentation

Index

Constants

This section is empty.

Variables

View Source
var BuildX8664LinuxGnu = pipeline.Job{
	Name:   "build-x86_64-linux-gnu",
	Stage:  "build",
	Script: List("cargo build --target=$RUST_TARGET --release --verbose", "mv target/$RUST_TARGET/release/ffsend ./ffsend-$RUST_TARGET", "strip -g ./ffsend-$RUST_TARGET"),
	Artifacts: pipeline.Artifacts{
		Paths:    List("ffsend-$RUST_TARGET"),
		ExpireIn: "1 month",
		Name:     "ffsend-x86_64-linux-gnu",
	},
}
View Source
var BuildX8664LinuxMusl = pipeline.Job{
	Name:   "build-x86_64-linux-musl",
	Stage:  "build",
	Script: List("rustup target add $RUST_TARGET", "apt-get install -y build-essential wget musl-tools", "wget https://github.com/openssl/openssl/releases/download/openssl-3.0.15/openssl-3.0.15.tar.gz", "tar xzvf openssl-3.0.15.tar.gz", "cd openssl-3.0.15", "./config no-async -fPIC --openssldir=/usr/local/ssl --prefix=/usr/local", "make", "make install", "cd ..", "export OPENSSL_STATIC=1", "export OPENSSL_LIB_DIR=/usr/local/lib64", "export OPENSSL_INCLUDE_DIR=/usr/local/include", "cargo build --target=$RUST_TARGET --release --verbose", "find . -name ffsend -exec ls -lah {} \\;", "mv target/$RUST_TARGET/release/ffsend ./ffsend-$RUST_TARGET", "strip -g ./ffsend-$RUST_TARGET"),
	Variables: Json{
		"RUST_TARGET": "x86_64-unknown-linux-musl",
	},
	Artifacts: pipeline.Artifacts{
		Paths:    List("ffsend-$RUST_TARGET"),
		ExpireIn: "1 month",
		Name:     "ffsend-x86_64-linux-musl",
	},
}
View Source
var Cache = pipeline.Job{
	Name: "cache",
}
View Source
var CheckBeta = pipeline.Job{
	Name:   "check-beta",
	Stage:  "check",
	Script: List("cargo check --verbose", "cargo check --no-default-features --features send3,crypto-ring --verbose", "cargo check --no-default-features --features send2,crypto-openssl --verbose", "cargo check --no-default-features --features send3,crypto-openssl --verbose", "cargo check --no-default-features --features send2,send3,crypto-openssl --verbose", "cargo check --no-default-features --features send3,crypto-ring,archive --verbose", "cargo check --no-default-features --features send3,crypto-ring,history --verbose", "cargo check --no-default-features --features send3,crypto-ring,qrcode --verbose", "cargo check --no-default-features --features send3,crypto-ring,urlshorten --verbose", "cargo check --no-default-features --features send3,crypto-ring,infer-command --verbose", "cargo check --features no-color --verbose"),
	Variables: Json{
		"RUST_VERSION": "beta",
	},
}
View Source
var CheckMsrv = pipeline.Job{
	Name:   "check-msrv",
	Stage:  "check",
	Script: List("cargo check --verbose", "cargo check --no-default-features --features send3,crypto-ring --verbose", "cargo check --no-default-features --features send2,crypto-openssl --verbose", "cargo check --no-default-features --features send3,crypto-openssl --verbose", "cargo check --no-default-features --features send2,send3,crypto-openssl --verbose", "cargo check --no-default-features --features send3,crypto-ring,archive --verbose", "cargo check --no-default-features --features send3,crypto-ring,history --verbose", "cargo check --no-default-features --features send3,crypto-ring,qrcode --verbose", "cargo check --no-default-features --features send3,crypto-ring,urlshorten --verbose", "cargo check --no-default-features --features send3,crypto-ring,infer-command --verbose", "cargo check --features no-color --verbose"),
	Variables: Json{
		"RUST_VERSION": "1.63.0",
	},
}
View Source
var CheckNightly = pipeline.Job{
	Name:   "check-nightly",
	Stage:  "check",
	Script: List("cargo check --verbose", "cargo check --no-default-features --features send3,crypto-ring --verbose", "cargo check --no-default-features --features send2,crypto-openssl --verbose", "cargo check --no-default-features --features send3,crypto-openssl --verbose", "cargo check --no-default-features --features send2,send3,crypto-openssl --verbose", "cargo check --no-default-features --features send3,crypto-ring,archive --verbose", "cargo check --no-default-features --features send3,crypto-ring,history --verbose", "cargo check --no-default-features --features send3,crypto-ring,qrcode --verbose", "cargo check --no-default-features --features send3,crypto-ring,urlshorten --verbose", "cargo check --no-default-features --features send3,crypto-ring,infer-command --verbose", "cargo check --features no-color --verbose"),
	Variables: Json{
		"RUST_VERSION": "nightly",
	},
}
View Source
var CheckStable = pipeline.Job{
	Name:   "check-stable",
	Stage:  "check",
	Script: List("cargo check --verbose", "cargo check --no-default-features --features send3,crypto-ring --verbose", "cargo check --no-default-features --features send2,crypto-openssl --verbose", "cargo check --no-default-features --features send3,crypto-openssl --verbose", "cargo check --no-default-features --features send2,send3,crypto-openssl --verbose", "cargo check --no-default-features --features send3,crypto-ring,archive --verbose", "cargo check --no-default-features --features send3,crypto-ring,history --verbose", "cargo check --no-default-features --features send3,crypto-ring,qrcode --verbose", "cargo check --no-default-features --features send3,crypto-ring,urlshorten --verbose", "cargo check --no-default-features --features send3,crypto-ring,infer-command --verbose", "cargo check --features no-color --verbose"),
}
View Source
var MainPipeline = pipeline.Pipeline{
	Stages: List("check", "build", "test", "release", "package"),
	Variables: Json{
		"RUST_VERSION": "stable",
		"RUST_TARGET":  "x86_64-unknown-linux-gnu",
	},
}
View Source
var PackageAur = pipeline.Job{
	Name:   "package-aur",
	Stage:  "package",
	Script: List("cd ./pkg/aur", "VERSION=$(echo $CI_COMMIT_REF_NAME | cut -c 2-)", "echo \"Determined binary version number 'v$VERSION'\"", "echo \"Determining SHA checksums for remote files...\"", "URL_BIN=https://github.com/timvisee/ffsend/releases/download/v$VERSION/ffsend-v$VERSION-linux-x64-static", "URL_SOURCE=https://gitlab.com/timvisee/ffsend/-/archive/v$VERSION/ffsend-v$VERSION.tar.gz", "URL_BASH_COMPLETION=https://gitlab.com/timvisee/ffsend/raw/v$VERSION/contrib/completions/ffsend.bash", "URL_ZSH_COMPLETION=https://gitlab.com/timvisee/ffsend/raw/v$VERSION/contrib/completions/_ffsend", "URL_FISH_COMPLETION=https://gitlab.com/timvisee/ffsend/raw/v$VERSION/contrib/completions/ffsend.fish", "URL_LICENSE=https://gitlab.com/timvisee/ffsend/raw/v$VERSION/LICENSE", "echo \"Selected binary URL: $URL_BIN\"", "echo \"Selected source URL: $URL_SOURCE\"", "echo \"Determining sha256sum for remote binary...\"", "SHA_BIN=$(curl -sSL \"$URL_BIN\" | sha256sum | cut -d\" \" -f1)", "echo \"Got sha256sum: $SHA_BIN\"", "SHA_BASH_COMPLETION=$(curl -sSL \"$URL_BASH_COMPLETION\" | sha256sum | cut -d\" \" -f1)", "echo \"Got sha256sums of bash completion: $SHA_BASH_COMPLETION\"", "SHA_ZSH_COMPLETION=$(curl -sSL \"$URL_ZSH_COMPLETION\" | sha256sum | cut -d\" \" -f1)", "echo \"Got sha256sums of ZSH completion: $SHA_ZSH_COMPLETION\"", "SHA_FISH_COMPLETION=$(curl -sSL \"$URL_FISH_COMPLETION\" | sha256sum | cut -d\" \" -f1)", "echo \"Got sha256sums of fish completion: $SHA_FISH_COMPLETION\"", "SHA_LICENSE=$(curl -sSL \"$URL_LICENSE\" | sha256sum | cut -d\" \" -f1)", "echo \"Got sha256sums of LICENSE: $SHA_LICENSE\"", "echo \"Determining sha256sum for remote source...\"", "SHA_SOURCE=$(curl -sSL \"$URL_SOURCE\" | sha256sum | cut -d\" \" -f1)", "echo \"Got sha256sum: $SHA_SOURCE\"", "echo \"Updating PKGBUILDS with release information...\"", "sed \"s/^pkgver=.*\\$/pkgver=$VERSION/\" -i ffsend/PKGBUILD", "sed \"s/^pkgver=.*\\$/pkgver=$VERSION/\" -i ffsend-bin/PKGBUILD", "sed \"s/^pkgver=.*\\$/pkgver=$VERSION.$CI_COMMIT_SHORT_SHA/\" -i ffsend-git/PKGBUILD", "sed \"s/^source=(\\\".*\\\").*\\$/source=(\\\"$(echo $URL_SOURCE | sed 's/\\//\\\\\\//g')\\\")/\" -i ffsend/PKGBUILD", "sed \"s/\\(\\\"ffsend-v\\$pkgver::\\).*\\\"/\\1$(echo $URL_BIN | sed 's/\\//\\\\\\//g')\\\"/\" -i ffsend-bin/PKGBUILD", "sed \"s/\\(\\\"ffsend-v\\$pkgver.bash::\\).*\\\"/\\1$(echo $URL_BASH_COMPLETION | sed 's/\\//\\\\\\//g')\\\"/\" -i ffsend-bin/PKGBUILD", "sed \"s/\\(\\\"ffsend-v\\$pkgver.zsh::\\).*\\\"/\\1$(echo $URL_ZSH_COMPLETION | sed 's/\\//\\\\\\//g')\\\"/\" -i ffsend-bin/PKGBUILD", "sed \"s/\\(\\\"ffsend-v\\$pkgver.fish::\\).*\\\"/\\1$(echo $URL_FISH_COMPLETION | sed 's/\\//\\\\\\//g')\\\"/\" -i ffsend-bin/PKGBUILD", "sed \"s/\\(\\\"LICENSE-v\\$pkgver::\\).*\\\"/\\1$(echo $URL_LICENSE | sed 's/\\//\\\\\\//g')\\\"/\" -i ffsend-bin/PKGBUILD", "sed \"s/^sha256sums=.*\\$/sha256sums=('$SHA_SOURCE')/\" -i ffsend/PKGBUILD", "sed \"s/^sha256sums=.*\\$/sha256sums=('$SHA_BIN' '$SHA_BASH_COMPLETION' '$SHA_ZSH_COMPLETION' '$SHA_FISH_COMPLETION' '$SHA_LICENSE')/\" -i ffsend-bin/PKGBUILD", "SHA_STRIP_LOCAL=$(cat ffsend-git/PKGBUILD | sed /^pkgver=.\\*/d | sha256sum | cut -d\" \" -f1)", "SHA_STRIP_REMOTE=$(curl -sSL \"https://aur.archlinux.org/cgit/aur.git/plain/PKGBUILD?h=ffsend-git\" | sed /^pkgver=.\\*/d | sha256sum | cut -d\" \" -f1)", "echo \"Installing required build packages...\"", "pacman -Syu --noconfirm sudo base-devel binutils openssh rust cargo cmake git openssl", "mkdir -p /.cargo", "chmod -R 777 /.cargo", "cd ffsend-bin/", "echo \"Making binary package...\"", "sudo -u nobody makepkg -c", "sudo -u nobody makepkg --printsrcinfo > .SRCINFO", "cd ../ffsend", "echo \"Making main source package...\"", "sudo -u nobody makepkg -c", "sudo -u nobody makepkg --printsrcinfo > .SRCINFO", "if [ ! \"$SHA_STRIP_LOCAL\" == \"$SHA_STRIP_REMOTE\" ]; then\n  cd ../ffsend-git\n  echo \"Making git source package...\"\n  sudo -u nobody makepkg -c\n  sudo -u nobody makepkg --printsrcinfo > .SRCINFO\nelse\n  echo \"Not making git source package, it has not changed\"\nfi\n", "cd ..", "mkdir -p /root/.ssh", "cp ./aur.pub /root/.ssh/id_rsa.pub", "echo \"$AUR_SSH_PRIVATE\" > /root/.ssh/id_rsa", "echo \"Host aur.archlinux.org\" >> /root/.ssh/config", "echo \"  IdentityFile /root/.ssh/aur\" >> /root/.ssh/config", "echo \"  User aur\" >> /root/.ssh/config", "chmod 600 /root/.ssh/{id_rsa*,config}", "eval `ssh-agent -s`", "ssh-add /root/.ssh/id_rsa", "ssh-keyscan -H aur.archlinux.org >> /root/.ssh/known_hosts", "git config --global user.name \"timvisee\"", "git config --global user.email \"tim@visee.me\"", "git clone ssh://aur@aur.archlinux.org/ffsend.git aur-ffsend", "cd aur-ffsend", "cp ../ffsend/{PKGBUILD,.SRCINFO} ./", "git add PKGBUILD .SRCINFO", "git commit -m \"Release v$VERSION\"", "git push", "cd ..", "git clone ssh://aur@aur.archlinux.org/ffsend-bin.git aur-ffsend-bin", "cd aur-ffsend-bin", "cp ../ffsend-bin/{PKGBUILD,.SRCINFO} ./", "git add PKGBUILD .SRCINFO", "git commit -m \"Release v$VERSION\"", "git push", "cd ..", "if [ ! \"$SHA_STRIP_LOCAL\" == \"$SHA_STRIP_REMOTE\" ]; then\n  git clone ssh://aur@aur.archlinux.org/ffsend-git.git aur-ffsend-git\n  cd aur-ffsend-git\n  cp ../ffsend-git/{PKGBUILD,.SRCINFO} ./\n  git add PKGBUILD .SRCINFO\n  git commit -m \"Update PKGBUILD for release v$VERSION\"\n  git push\n  cd ..\nelse\n  echo \"Not pushing git package, it has not changed\"\nfi\n"),
	Image:  pipeline.Image{Name: "archlinux"},
	Needs:  []any{ReleaseGithub},
}
View Source
var ReleaseCrate = pipeline.Job{
	Name:   "release-crate",
	Stage:  "release",
	Script: List("echo \"Creating release crate to publish on crates.io...\"", "echo $CARGO_TOKEN | cargo login", "echo \"Publishing crate to crates.io...\"", "cargo publish --verbose --allow-dirty"),
}
View Source
var ReleaseDocker = pipeline.Job{
	Name:   "release-docker",
	Stage:  "release",
	Script: List("mv ./ffsend-$RUST_TARGET ./pkg/docker/ffsend", "cd ./pkg/docker", "docker build -t timvisee/ffsend:latest ./", "docker run --rm timvisee/ffsend:latest -V", "VERSION=$(echo $CI_COMMIT_REF_NAME | cut -c 2-)", "echo \"Determined Docker image version number 'v$VERSION', retagging image...\"", "docker tag timvisee/ffsend:latest timvisee/ffsend:$VERSION", "echo \"$DOCKER_PASSWORD\" | docker login -u \"$DOCKER_USER\" --password-stdin", "docker push timvisee/ffsend:$VERSION", "docker push timvisee/ffsend:latest"),
	Image:  pipeline.Image{Name: "docker:git"},
	Services: List(
		pipeline.Service{Name: "docker:dind"},
	),
	Variables: Json{
		"RUST_TARGET": "x86_64-unknown-linux-musl",
		"DOCKER_HOST": "tcp://docker:2375",
	},
}
View Source
var ReleaseGithub = pipeline.Job{
	Name:   "release-github",
	Stage:  "release",
	Script: List("apt-get update", "apt-get install -y curl wget gzip netbase", "wget https://github.com/tfausak/github-release/releases/download/1.2.5/github-release-linux.gz -O github-release.gz", "gunzip github-release.gz", "chmod a+x ./github-release", "./github-release release --token \"$GITHUB_TOKEN\" --owner timvisee --repo ffsend --tag \"$CI_COMMIT_REF_NAME\"  --title \"ffsend $CI_COMMIT_REF_NAME\"", "./github-release upload --token \"$GITHUB_TOKEN\" --owner timvisee --repo ffsend --tag \"$CI_COMMIT_REF_NAME\" --file ./ffsend-x86_64-unknown-linux-gnu --name ffsend-$CI_COMMIT_REF_NAME-linux-x64", "./github-release upload --token \"$GITHUB_TOKEN\" --owner timvisee --repo ffsend --tag \"$CI_COMMIT_REF_NAME\" --file ./ffsend-x86_64-unknown-linux-musl --name ffsend-$CI_COMMIT_REF_NAME-linux-x64-static"),
}
View Source
var ReleaseSnap = pipeline.Job{
	Name:   "release-snap",
	Stage:  "release",
	Script: List("apt-get update -y", "apt-get install python3 -yqq", "cd pkg/snap", "VERSION=$(echo $CI_COMMIT_REF_NAME | cut -c 2-)", "echo \"Determined binary version number 'v$VERSION', updating snapcraft.yaml...\"", "sed \"s/^version:.*\\$/version: $VERSION/\" -i snapcraft.yaml", "sed \"s/^pkgver=.*\\$/pkgver=$VERSION/\" -i snapcraft.yaml", "echo \"Building snap package...\"", "snapcraft", "echo \"Publishing snap package...\"", "snapcraft whoami", "snapcraft push --release=stable ffsend_*_amd64.snap"),
	Image:  pipeline.Image{Name: "snapcore/snapcraft:stable"},
	Artifacts: pipeline.Artifacts{
		Paths:    List("pkg/snap/ffsend_*_amd64.snap"),
		ExpireIn: "1 month",
		Name:     "ffsend-snap-x86_64",
	},
}
View Source
var TestCargo = pipeline.Job{
	Name:   "test-cargo",
	Stage:  "test",
	Script: List("cargo test --verbose"),
}
View Source
var TestPublic = pipeline.Job{
	Name:   "test-public",
	Stage:  "test",
	Script: List("mv ./ffsend-$RUST_TARGET ./ffsend", "chmod a+x ./ffsend", "head -c1m </dev/urandom >test.txt", "./ffsend upload test.txt -I", "./ffsend download $(./ffsend history -q) -I -o=download.txt", "cmp -s ./test.txt ./download.txt || (echo ERROR: Downloaded file is different than original; exit 1)", "rm ./download.txt"),
	Image:  pipeline.Image{Name: "alpine:latest"},
	Variables: Json{
		"GIT_STRATEGY": "none",
		"RUST_TARGET":  "x86_64-unknown-linux-musl",
	},
}

Functions

This section is empty.

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL