Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ci: implement release verification #1264

Merged
merged 2 commits into from
Nov 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
12 changes: 7 additions & 5 deletions .github/workflows/release_validate.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
name: "Release (validate)"

on:
workflow_run:
workflows: ["Release"]
types:
- completed

schedule:
- cron: 0 0 0 1 1 ? 1970 # Never for now, planned to run every six hours
- cron: 0 */6 * * * # Every six hours

jobs:
validate:
Expand All @@ -17,10 +22,7 @@ jobs:

- run: ./scripts/install_zig.sh

- run: ./zig/zig build dotnet_client:ci -- --release-validate
- run: ./zig/zig build go_client:ci -- --release-validate
- run: ./zig/zig build java_client:ci -- --release-validate
- run: ./zig/zig build node_client:ci -- --release-validate
- run: ./zig/zig build ci -- --verify-release

alert_failure:
runs-on: ubuntu-latest
Expand Down
17 changes: 13 additions & 4 deletions src/clients/dotnet/ci.zig
Original file line number Diff line number Diff line change
Expand Up @@ -85,17 +85,26 @@ pub fn tests(shell: *Shell, gpa: std.mem.Allocator) !void {
}
}

pub fn verify_release(shell: *Shell, gpa: std.mem.Allocator, tmp_dir: std.fs.Dir) !void {
var tmp_beetle = try TmpTigerBeetle.init(gpa, .{});
pub fn validate_release(shell: *Shell, gpa: std.mem.Allocator, options: struct {
version: []const u8,
tigerbeetle: []const u8,
}) !void {
var tmp_beetle = try TmpTigerBeetle.init(gpa, .{
.prebuilt = options.tigerbeetle,
});
defer tmp_beetle.deinit(gpa);

try shell.env.put("TB_ADDRESS", tmp_beetle.port_str.slice());

try shell.exec("dotnet new console", .{});
try shell.exec("dotnet add package tigerbeetle", .{});
try shell.exec("dotnet add package tigerbeetle --version {version}", .{
.version = options.version,
});

try Shell.copy_path(
shell.project_root,
"src/clients/dotnet/samples/basic/Program.cs",
tmp_dir,
shell.cwd,
"Program.cs",
);
try shell.exec("dotnet run", .{});
Expand Down
17 changes: 13 additions & 4 deletions src/clients/go/ci.zig
Original file line number Diff line number Diff line change
Expand Up @@ -47,17 +47,26 @@ pub fn tests(shell: *Shell, gpa: std.mem.Allocator) !void {
}
}

pub fn verify_release(shell: *Shell, gpa: std.mem.Allocator, tmp_dir: std.fs.Dir) !void {
var tmp_beetle = try TmpTigerBeetle.init(gpa, .{});
pub fn validate_release(shell: *Shell, gpa: std.mem.Allocator, options: struct {
version: []const u8,
tigerbeetle: []const u8,
}) !void {
var tmp_beetle = try TmpTigerBeetle.init(gpa, .{
.prebuilt = options.tigerbeetle,
});
defer tmp_beetle.deinit(gpa);

try shell.env.put("TB_ADDRESS", tmp_beetle.port_str.slice());

try shell.exec("go mod init tbtest", .{});
try shell.exec("go get github.com/tigerbeetle/tigerbeetle-go", .{});
try shell.exec("go get github.com/tigerbeetle/tigerbeetle-go@v{version}", .{
.version = options.version,
});

try Shell.copy_path(
shell.project_root,
"src/clients/go/samples/basic/main.go",
tmp_dir,
shell.cwd,
"main.go",
);
const zig_exe = try shell.project_root.realpathAlloc(
Expand Down
70 changes: 65 additions & 5 deletions src/clients/java/ci.zig
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,71 @@ pub fn tests(shell: *Shell, gpa: std.mem.Allocator) !void {
}
}

pub fn verify_release(shell: *Shell, gpa: std.mem.Allocator, tmp_dir: std.fs.Dir) !void {
var tmp_beetle = try TmpTigerBeetle.init(gpa, .{});
pub fn validate_release(shell: *Shell, gpa: std.mem.Allocator, options: struct {
version: []const u8,
tigerbeetle: []const u8,
}) !void {
var tmp_beetle = try TmpTigerBeetle.init(gpa, .{
.prebuilt = options.tigerbeetle,
});
defer tmp_beetle.deinit(gpa);

// TODO
_ = shell;
_ = tmp_dir;
try shell.env.put("TB_ADDRESS", tmp_beetle.port_str.slice());

try shell.cwd.writeFile("pom.xml", try shell.print(
\\<project>
\\ <modelVersion>4.0.0</modelVersion>
\\ <groupId>com.tigerbeetle</groupId>
\\ <artifactId>samples</artifactId>
\\ <version>1.0-SNAPSHOT</version>
\\
\\ <properties>
\\ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
\\ <maven.compiler.source>11</maven.compiler.source>
\\ <maven.compiler.target>11</maven.compiler.target>
\\ </properties>
\\
\\ <build>
\\ <plugins>
\\ <plugin>
\\ <groupId>org.apache.maven.plugins</groupId>
\\ <artifactId>maven-compiler-plugin</artifactId>
\\ <version>3.8.1</version>
\\ <configuration>
\\ <compilerArgs>
\\ <arg>-Xlint:all,-options,-path</arg>
\\ </compilerArgs>
\\ </configuration>
\\ </plugin>
\\
\\ <plugin>
\\ <groupId>org.codehaus.mojo</groupId>
\\ <artifactId>exec-maven-plugin</artifactId>
\\ <version>1.6.0</version>
\\ <configuration>
\\ <mainClass>com.tigerbeetle.samples.Main</mainClass>
\\ </configuration>
\\ </plugin>
\\ </plugins>
\\ </build>
\\
\\ <dependencies>
\\ <dependency>
\\ <groupId>com.tigerbeetle</groupId>
\\ <artifactId>tigerbeetle-java</artifactId>
\\ <version>{s}</version>
\\ </dependency>
\\ </dependencies>
\\</project>
, .{options.version}));

try Shell.copy_path(
shell.project_root,
"src/clients/java/samples/basic/src/main/java/Main.java",
shell.cwd,
"src/main/java/Main.java",
);

try shell.exec("mvn package", .{});
try shell.exec("mvn exec:java", .{});
}
15 changes: 0 additions & 15 deletions src/clients/java/validation_pom.xml

This file was deleted.

17 changes: 13 additions & 4 deletions src/clients/node/ci.zig
Original file line number Diff line number Diff line change
Expand Up @@ -95,16 +95,25 @@ pub fn tests(shell: *Shell, gpa: std.mem.Allocator) !void {
}
}

pub fn verify_release(shell: *Shell, gpa: std.mem.Allocator, tmp_dir: std.fs.Dir) !void {
var tmp_beetle = try TmpTigerBeetle.init(gpa, .{});
pub fn validate_release(shell: *Shell, gpa: std.mem.Allocator, options: struct {
version: []const u8,
tigerbeetle: []const u8,
}) !void {
var tmp_beetle = try TmpTigerBeetle.init(gpa, .{
.prebuilt = options.tigerbeetle,
});
defer tmp_beetle.deinit(gpa);

try shell.exec("npm install tigerbeetle-node", .{});
try shell.env.put("TB_ADDRESS", tmp_beetle.port_str.slice());

try shell.exec("npm install tigerbeetle-node@{version}", .{
.version = options.version,
});

try Shell.copy_path(
shell.project_root,
"src/clients/node/samples/basic/main.js",
tmp_dir,
shell.cwd,
"main.js",
);
try shell.exec("node main.js", .{});
Expand Down
100 changes: 74 additions & 26 deletions src/scripts/ci.zig
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const builtin = @import("builtin");
const log = std.log;
const assert = std.debug.assert;

const stdx = @import("../stdx.zig");
const flags = @import("../flags.zig");
const fatal = flags.fatal;
const Shell = @import("../shell.zig");
Expand All @@ -23,7 +24,7 @@ const LanguageCI = .{

const CliArgs = struct {
language: ?Language = null,
verify_release: bool = false,
validate_release: bool = false,
};

pub fn main() !void {
Expand All @@ -46,36 +47,35 @@ pub fn main() !void {
assert(args.skip());
const cli_args = flags.parse_flags(&args, CliArgs);

if (cli_args.validate_release) {
try validate_release(shell, gpa, cli_args.language);
} else {
try run_tests(shell, gpa, cli_args.language);
}
}

fn run_tests(shell: *Shell, gpa: std.mem.Allocator, language_requested: ?Language) !void {
inline for (comptime std.enums.values(Language)) |language| {
if (cli_args.language == language or cli_args.language == null) {
if (language_requested == language or language_requested == null) {
const ci = @field(LanguageCI, @tagName(language));
if (cli_args.verify_release) {
var tmp_dir = std.testing.tmpDir(.{});
defer tmp_dir.cleanup();
var section = try shell.open_section(@tagName(language) ++ " ci");
defer section.close();

try tmp_dir.dir.setAsCwd();
{
try shell.pushd("./src/clients/" ++ @tagName(language));
defer shell.popd();

try ci.verify_release(shell, gpa, tmp_dir.dir);
} else {
var section = try shell.open_section(@tagName(language) ++ " ci");
defer section.close();

{
try shell.pushd("./src/clients/" ++ @tagName(language));
defer shell.popd();

try ci.tests(shell, gpa);
}
try ci.tests(shell, gpa);
}

// Piggy back on node client testing to verify our docs, as we use node to generate
// them anyway.
if (language == .node and builtin.os.tag == .linux) {
const node_version = try shell.exec_stdout("node --version", .{});
if (std.mem.startsWith(u8, node_version, "v14")) {
log.warn("skip building documentation on old Node.js", .{});
} else {
try build_docs(shell);
}
// Piggy back on node client testing to verify our docs, as we use node to generate
// them anyway.
if (language == .node and builtin.os.tag == .linux) {
const node_version = try shell.exec_stdout("node --version", .{});
if (std.mem.startsWith(u8, node_version, "v14")) {
log.warn("skip building documentation on old Node.js", .{});
} else {
try build_docs(shell);
}
}
}
Expand All @@ -89,3 +89,51 @@ fn build_docs(shell: *Shell) !void {
try shell.exec("npm install", .{});
try shell.exec("npm run build", .{});
}

fn validate_release(shell: *Shell, gpa: std.mem.Allocator, language_requested: ?Language) !void {
var tmp_dir = std.testing.tmpDir(.{});
defer tmp_dir.cleanup();

try shell.pushd_dir(tmp_dir.dir);
defer shell.popd();

const release_info = try shell.exec_stdout(
"gh release --repo tigerbeetle/tigerbeetle list --limit 1",
.{},
);
const tag = stdx.cut(release_info, "\t").?.prefix;
log.info("validateing release {s}", .{tag});

try shell.exec(
"gh release --repo tigerbeetle/tigerbeetle download {tag}",
.{ .tag = tag },
);

if (builtin.os.tag != .linux) {
log.warn("skip release verification for platforms other than Linux", .{});
}

try shell.exec("unzip tigerbeetle-x86_64-linux.zip", .{});
const version = try shell.exec_stdout("./tigerbeetle version --verbose", .{});
assert(std.mem.indexOf(u8, version, tag) != null);
assert(std.mem.indexOf(u8, version, "ReleaseSafe") != null);

const tigerbeetle_absolute_path = try shell.cwd.realpathAlloc(gpa, "tigerbeetle");
defer gpa.free(tigerbeetle_absolute_path);

inline for (comptime std.enums.values(Language)) |language| {
if (language_requested == language or language_requested == null) {
const ci = @field(LanguageCI, @tagName(language));
try ci.validate_release(shell, gpa, .{
.tigerbeetle = tigerbeetle_absolute_path,
.version = tag,
});
}
}

const docker_version = try shell.exec_stdout(
\\docker run ghcr.io/tigerbeetle/tigerbeetle:{version} version --verbose
, .{ .version = tag });
assert(std.mem.indexOf(u8, docker_version, tag) != null);
assert(std.mem.indexOf(u8, docker_version, "ReleaseSafe") != null);
}
11 changes: 11 additions & 0 deletions src/shell.zig
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,17 @@ pub fn pushd(shell: *Shell, path: []const u8) !void {
shell.cwd = cwd_new;
}

pub fn pushd_dir(shell: *Shell, dir: std.fs.Dir) !void {
assert(shell.cwd_stack_count < cwd_stack_max);

// Re-open the directory such that `popd` can close it.
const cwd_new = try dir.openDir(".", .{});

shell.cwd_stack[shell.cwd_stack_count] = shell.cwd;
shell.cwd_stack_count += 1;
shell.cwd = cwd_new;
}

pub fn popd(shell: *Shell) void {
shell.cwd.close();
shell.cwd_stack_count -= 1;
Expand Down