Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .envrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
use flake
11 changes: 10 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,13 @@ cabal.project.local~
examples/Main
examples/FileHook
examples/GitLabCommit
examples/UserProjects
examples/UserProjects

# direnv (.envrc)
.direnv/

# nix
result

# integration test vm
gitlab-dev.qcow2
5 changes: 4 additions & 1 deletion cabal.project
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
packages: . examples
packages:
.
examples
integration/suite
77 changes: 77 additions & 0 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

138 changes: 138 additions & 0 deletions flake.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
{
description = "A Haskell library for the GitLab web API";

inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
flake-parts.url = "github:hercules-ci/flake-parts";
haskell-flake.url = "github:srid/haskell-flake";
};

outputs =
inputs:
# https://flake.parts
inputs.flake-parts.lib.mkFlake { inherit inputs; } (
{ lib, withSystem, ... }:
{
systems = [
"x86_64-linux"
"aarch64-linux"
"x86_64-darwin"
"aarch64-darwin"
];
imports = [ inputs.haskell-flake.flakeModule ];

# https://flake.parts/options/flake-parts.html#opt-perSystem
perSystem =
{
self',
pkgs,
system,
...
}:
{
# haskell-flake configuration
# Docs: https://flake.parts/options/haskell-flake.html
# Implicitly defines devShells.default
haskellProjects.default = {
};

checks = {
# Sandboxed VM test that runs the integration test suite against
# an ephemeral instance over a virtual network.
# This is mostly for CI, because the VM does not survive the build
# sandbox. Run with `nix build .#integrationTest`, thanks to alias
# in `packages`.
integrationTest = pkgs.testers.runNixOSTest {
imports = [ ./integration/nixos-test.nix ];
_module.args.withSystem = withSystem;
};
};

packages = {
default = self'.packages.gitlab-haskell;

# Convenience for nix build .#integrationTest
integrationTest = self'.checks.integrationTest;
};

apps = {
gitlab-dev-vm = {
type = "app";
program = "${lib.getExe inputs.self.nixosConfigurations.gitlab-dev.config.system.build.vm}";
meta.description = ''
Runs a GitLab instance in a local VM
Leaves a nixos.qcow2 file in the working directory.
Run with:

nix run .#gitlab-dev-vm
'';
};
};
};

flake.nixosConfigurations = {

# NixOS configuration for VM with GitLab instance in it, for local dev.
gitlab-dev = inputs.nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [
(
{ modulesPath, ... }:
{
imports = [
"${modulesPath}/virtualisation/qemu-vm.nix"
./integration/gitlab-module.nix
];

# Appears in window name
networking.hostName = "gitlab-dev";

# Passwordless root login for local development
users.users.root.initialHashedPassword = "";
services.getty.autologinUser = "root";

# Install GitLab startup monitor script
environment.systemPackages = [
(inputs.nixpkgs.legacyPackages.x86_64-linux.writeShellScriptBin "wait-for-gitlab" ''
echo "Waiting for GitLab to become ready..."
while ! curl -sf http://localhost/users/sign_in > /dev/null 2>&1; do
sleep 2
done
echo "GitLab is ready!"
'')
];

# Add hint to MOTD
users.motd = ''
GitLab development VM

Run 'wait-for-gitlab' to monitor GitLab startup.
Once ready, run tests from the host with: cabal run integration-suite
'';

# Forward GitLab HTTP and SSH ports to host (localhost only)
virtualisation.forwardPorts = [
{
from = "host";
host.address = "127.0.0.1";
host.port = 8427;
guest.port = 80;
}
{
from = "host";
host.address = "127.0.0.1";
host.port = 8422;
guest.port = 22;
}
];

# Larger disk for development
virtualisation.diskSize = 8192;
}
)
];
};
};
}
);
}
64 changes: 64 additions & 0 deletions integration/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# Integration Tests

This directory contains integration tests for the gitlab-haskell library.

## Test Environment

The integration tests use a NixOS VM running GitLab for testing. The VM configuration is defined in `flake.nix` (`nixosConfigurations.gitlab-dev`) and `gitlab-module.nix`.

### VM Configuration

- **Root password**: `glhs-insecure-test-password` (configured via `GITLAB_ROOT_PASSWORD`)
- **Default user**: root
- **Port forwarding**: VM binds to host ports
- 8427 on the host for HTTP
- 8422 on the host for SSH (may / may not be used)

### Running the VM

From the repository root:

```bash
nix run .#gitlab-dev-vm
```

The VM will:
1. Start up and initialize GitLab
2. Wait for GitLab to become ready
3. Display "GitLab is ready!" when initialization is complete

The VM creates and/or uses `nixos.qcow2` in the working directory.
Maybe it could be made to be stateless.

### Running the Tests

When the VM is running, you can run the tests outside the VM, to iterate quickly without gitlab startup overhead, which is significant.
In a separate terminal, once the VM is ready:

```bash
cabal run integration-suite
```

The tests will:
1. Check for `GITLAB_TOKEN` environment variable
2. If not set, obtain an OAuth token via password grant flow
3. Run the test suite against the GitLab instance

### Environment Variables

- `GITLAB_URL`: GitLab instance URL (default: `http://localhost:8427`)
- `GITLAB_TOKEN`: OAuth access token (if not set, automatically obtained)
- `GITLAB_PASSWORD`: Root password (default: `glhs-insecure-test-password`)

### Nix sandboxed

You may also run the tests in the Nix build sandbox.
This has the overhead of having to start GitLab, but proves that the test is self-contained, and is useful for CI.

```bash
nix build .#integrationTest
```

## Test Suite Structure

See [suite](suite/README.md).
Loading