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

Build Hoff in Nix #105

Merged
merged 5 commits into from
Apr 19, 2022
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,6 @@

# Test output
.hspec-failures

# Nix build result
result
18 changes: 15 additions & 3 deletions .semaphore/semaphore.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ blocks:
task:
secrets:
- name: "opsbot-github-key"
# Keys needed to access our cachix cache.
- name: "cachix-channable-public"

jobs:
- name: "Build, test, package, ship"
Expand Down Expand Up @@ -45,6 +47,10 @@ blocks:
- "./nix/install"
- ". $HOME/.nix-profile/etc/profile.d/nix.sh"

# Install Cachix and use the Channable cache
- "nix-env -iA nixpkgs.cachix"
- "cachix use channable-public"

# Bring all the tools from the pinned build environment into the PATH.
- "export PATH=$(nix-build --no-out-link default.nix)/bin:$PATH"

Expand All @@ -53,9 +59,10 @@ blocks:
# contains them.
- "export LOCALE_ARCHIVE=$(nix-build --no-out-link locale.nix)/lib/locale/locale-archive"

- "stack setup"
- "stack --no-terminal build --split-objs"
- "stack --no-terminal test --split-objs"
# The stack builds are currently broken, see https://github.com/channable/hoff/issues/106
# - "stack setup"
# - "stack --no-terminal build --split-objs"
# - "stack --no-terminal test --split-objs"

# Match the licenses of dependencies agains a whitelist, and fail
# if anything is not whitelisted. Grep -v returns # 1 if nothing
Expand All @@ -68,6 +75,11 @@ blocks:
# Check shell scripts for issues.
- "shellcheck package/*.sh package/deb-postinst"

# Run build and tests in Nix, and push the result to Cachix.
# Because this is a public repository, and not everyone is using Nix,
# we keep the stack setup around. The Nix build however is used in production.
- "nix-build --no-out-link release.nix | cachix push channable-public"

# Store a copy of the nix store. This will be refreshed daily, which
# is more than sufficient for this repo.
- "cache store nix-store-$(date -u -Idate) /nix"
Expand Down
85 changes: 85 additions & 0 deletions hoff.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
{ lib, haskellPackages, nix-gitignore, git, coreutils, openssh }:
haskellPackages.mkDerivation {
pname = "hoff";
version = "0.25.0";

src =
let
# We do not want to include all files, because that leads to a lot of things that nix
# has to copy to the temporary build directory that we don't want to have in there
# (e.g. the `.stack-work` directory, the `.git` directory, etc.)
prefixWhitelist = builtins.map builtins.toString [
./app
./package
Riscky marked this conversation as resolved.
Show resolved Hide resolved
./src
./static
./tests
./hoff.cabal
./stack.yaml
./license
];
# Compute source based on whitelist
whitelistFilter = path: _type: lib.any (prefix: lib.hasPrefix prefix path) prefixWhitelist;
gitignore = builtins.readFile ./.gitignore;
gitignoreFilter = nix-gitignore.gitignoreFilterPure whitelistFilter gitignore ./.;
whitelistedSrc = lib.cleanSourceWith {
src = lib.cleanSource ./.;
filter = gitignoreFilter;
};
in
whitelistedSrc;

isLibrary = false;
isExecutable = true;


executableToolDepends = [
git coreutils openssh
];

testDepends = [
git coreutils openssh
];


libraryHaskellDepends =
with haskellPackages; [
aeson
aeson-pretty
blaze-html
blaze-markup
bytestring
containers
cryptonite
directory
extra
file-embed
filepath
free
github
hspec
hspec-core
http-client
http-conduit
http-types
memory
monad-logger
optparse-applicative
process
process-extras
scotty
stm
text
text-format
time
uuid
vector
wai
warp
warp-tls
];

homepage = "https://github.com/channable/hoff";

license = lib.licenses.asl20;
}
6 changes: 3 additions & 3 deletions nix/sources.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@
"homepage": "",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "2f752379bcc26134d12f2275435f0530593ea5c6",
"sha256": "1smfadbmb6kabjxd2xr99f4qwydynm156kc6kipb37j4y3zcfk21",
"rev": "530a53dcbc9437363471167a5e4762c5fcfa34a1",
"sha256": "11d9m0c4r4kpr3jx3cqblw6ld4d8dwcfv1lk68ipp4c87knwv7fb",
"type": "tarball",
"url": "https://github.com/NixOS/nixpkgs/archive/2f752379bcc26134d12f2275435f0530593ea5c6.tar.gz",
"url": "https://github.com/NixOS/nixpkgs/archive/530a53dcbc9437363471167a5e4762c5fcfa34a1.tar.gz",
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
}
}
5 changes: 5 additions & 0 deletions release.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
let
pkgs = import ./nixpkgs-pinned.nix {};
hoff = pkgs.callPackage ./hoff.nix {};
in
hoff
4 changes: 2 additions & 2 deletions src/Git.hs
Original file line number Diff line number Diff line change
Expand Up @@ -278,8 +278,8 @@ callGit userConfig args = do
-- not prompt for things such as passphrases, because there is no
-- interactive terminal.
Process.env = Just
$ ("GIT_EDITOR", "/usr/bin/env true")
: ("GIT_SSH_COMMAND", "/usr/bin/ssh -F " ++ (Config.sshConfigFile userConfig))
$ ("GIT_EDITOR", "true")
: ("GIT_SSH_COMMAND", "ssh -F " ++ (Config.sshConfigFile userConfig))
: ("GIT_TERMINAL_PROMPT", "0")
: currentEnv
}
Expand Down
17 changes: 10 additions & 7 deletions src/Server.hs
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,16 @@ styleRoute = Literal $ LT.fromStrict WebInterface.stylesheetUrl
isSignatureValid :: Text -> Text -> ByteString -> Bool
isSignatureValid secret hexDigest message =
let actualHmac = hmac (encodeUtf8 secret) message :: HMAC SHA1
binaryDigest = fst $ Base16.decode $ encodeUtf8 hexDigest
in case digestFromByteString binaryDigest of
-- The HMAC type implements a constant-time comparison.
Just expectedDigest -> (HMAC expectedDigest) == actualHmac
-- If the hexDigest was not a valid hexadecimally-encoded digest,
-- the signature was definitely not valid.
Nothing -> False
binaryDigest = Base16.decode $ encodeUtf8 hexDigest
in case binaryDigest of
-- If the hexDigest was not hexadecimal, is was definitely not valid
Left _ -> False
Right x -> case digestFromByteString x of
-- The HMAC type implements a constant-time comparison.
Just expectedDigest -> (HMAC expectedDigest) == actualHmac
-- If the hexDigest was not a valid hexadecimally-encoded digest,
-- the signature was definitely not valid.
Nothing -> False

-- The X-Hub-Signature header value is prefixed with "sha1=", and then the
-- digest in hexadecimal. Strip off that prefix, and ensure that it has the
Expand Down