Deploy site
1
.envrc
|
@ -1 +0,0 @@
|
||||||
use nix
|
|
|
@ -1,38 +0,0 @@
|
||||||
name: build site
|
|
||||||
on:
|
|
||||||
pull_request:
|
|
||||||
types: [opened, synchronize, edited, reopened]
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build_site:
|
|
||||||
runs-on: nix
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
- name: Build the site
|
|
||||||
run: nix-build
|
|
||||||
|
|
||||||
- name: Pushing site to pages branch
|
|
||||||
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
|
|
||||||
run: |
|
|
||||||
git switch -C pages
|
|
||||||
find . -mindepth 1 -maxdepth 1 ! -name '.domains' ! -name '.git' ! -name 'result' -exec rm -rf {} +
|
|
||||||
ls -a
|
|
||||||
cp -r result/* .
|
|
||||||
rm result
|
|
||||||
git add .
|
|
||||||
|
|
||||||
git config user.name "DGNum Deploy"
|
|
||||||
git config user.email "tech@dgnum.eu"
|
|
||||||
|
|
||||||
git commit --message "Deploy site"
|
|
||||||
git push --set-upstream origin pages --force
|
|
||||||
|
|
||||||
- uses: actions/upload-artifact@v3
|
|
||||||
with:
|
|
||||||
name: site
|
|
||||||
path: ./
|
|
|
@ -1,25 +0,0 @@
|
||||||
name: build configuration
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
runs-on: nix
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
|
|
||||||
- name: Build
|
|
||||||
run: nix-build
|
|
||||||
|
|
||||||
- name: deploy
|
|
||||||
run: nix-shell -p awscli2 --run "aws s3 sync ./result/ s3://$BUCKET/ --delete --endpoint-url $URL"
|
|
||||||
env:
|
|
||||||
URL: "https://s3.dgnum.eu/"
|
|
||||||
BUCKET: pub.dgnum.eu
|
|
||||||
AWS_ACCESS_KEY_ID: ${{ secrets.KEY_ID }}
|
|
||||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.SECRET_KEY }}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
3
.gitignore
vendored
|
@ -1,3 +0,0 @@
|
||||||
.direnv
|
|
||||||
build
|
|
||||||
result
|
|
0
src/www/css/bulma.css → css/bulma.css
vendored
79
default.nix
|
@ -1,79 +0,0 @@
|
||||||
{
|
|
||||||
sources ? import ./lon.nix,
|
|
||||||
pkgs ? import sources.nixpkgs { },
|
|
||||||
}:
|
|
||||||
|
|
||||||
let
|
|
||||||
description = "La Délégation Générale Numérique est une association loi 1901 domiciliée à l'ENS dont les buts sont de promouvoir la chose numérique ainsi que son usage.";
|
|
||||||
|
|
||||||
links = [
|
|
||||||
{
|
|
||||||
text = "État des services";
|
|
||||||
href = "https://status.dgnum.eu";
|
|
||||||
cls = "link-status";
|
|
||||||
icon = "status.svg";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
text = "Notre site";
|
|
||||||
href = "https://dgnum.eu";
|
|
||||||
cls = "link-classic";
|
|
||||||
icon = "website.svg";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
text = "Forge Git";
|
|
||||||
href = "https://git.dgnum.eu";
|
|
||||||
cls = "link-git";
|
|
||||||
icon = "git.svg";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
text = "Mastodon";
|
|
||||||
href = "https://social.dgnum.eu/@dgnum";
|
|
||||||
cls = "link-mastodon";
|
|
||||||
icon = "mastodon.svg";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
text = "Instagram";
|
|
||||||
href = "https://www.instagram.com/dgnum_eu/";
|
|
||||||
cls = "link-instagram";
|
|
||||||
icon = "instagram.svg";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
text = "Nous contacter";
|
|
||||||
href = "mailto:contact@dgnum.eu";
|
|
||||||
cls = "link-classic";
|
|
||||||
icon = "contact.svg";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
python3 = pkgs.python3.withPackages (ps: [
|
|
||||||
ps.watchdog
|
|
||||||
(ps.callPackage ./pkgs/moody-templates.nix { })
|
|
||||||
]);
|
|
||||||
in
|
|
||||||
|
|
||||||
pkgs.stdenv.mkDerivation {
|
|
||||||
name = "dgnum-landing";
|
|
||||||
version = "1.0.1";
|
|
||||||
src = ./src;
|
|
||||||
|
|
||||||
passthru = {
|
|
||||||
devShell = pkgs.mkShell {
|
|
||||||
packages = [
|
|
||||||
(pkgs.callPackage "${sources.lon}/nix/packages/lon.nix" { })
|
|
||||||
python3
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
buildInputs = [ python3 ];
|
|
||||||
|
|
||||||
env.DATA_FILE = pkgs.writers.writeJSON "data.json" { inherit description links; };
|
|
||||||
|
|
||||||
configurePhase = ''
|
|
||||||
export BUILD_DIR=$out
|
|
||||||
'';
|
|
||||||
|
|
||||||
buildPhase = ''
|
|
||||||
python3 build.py
|
|
||||||
'';
|
|
||||||
}
|
|
Before Width: | Height: | Size: 487 B After Width: | Height: | Size: 487 B |
Before Width: | Height: | Size: 733 B After Width: | Height: | Size: 733 B |
Before Width: | Height: | Size: 419 B After Width: | Height: | Size: 419 B |
Before Width: | Height: | Size: 807 B After Width: | Height: | Size: 807 B |
Before Width: | Height: | Size: 430 B After Width: | Height: | Size: 430 B |
Before Width: | Height: | Size: 770 B After Width: | Height: | Size: 770 B |
Before Width: | Height: | Size: 106 KiB After Width: | Height: | Size: 106 KiB |
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
|
@ -138,17 +138,52 @@
|
||||||
<img alt="Délégation Générale Numérique" height="165" width="315" src="/img/dgnum.svg" />
|
<img alt="Délégation Générale Numérique" height="165" width="315" src="/img/dgnum.svg" />
|
||||||
</figure>
|
</figure>
|
||||||
<h1>Délégation Générale Numérique</h1>
|
<h1>Délégation Générale Numérique</h1>
|
||||||
<p>{{ description }}</p>
|
<p>La Délégation Générale Numérique est une association loi 1901 domiciliée à l'ENS dont les buts sont de promouvoir la chose numérique ainsi que son usage.</p>
|
||||||
</header>
|
</header>
|
||||||
<hr />
|
<hr />
|
||||||
{% for link in links %}
|
|
||||||
<a class="{{ link.cls }}" href="{{ link.href }}">
|
<a class="link-status" href="https://status.dgnum.eu">
|
||||||
<figure class="image is-icon">
|
<figure class="image is-icon">
|
||||||
<img alt="" aria-hidden="true" src="/icons/{{ link.icon }}" height="24px" width="24px" />
|
<img alt="" aria-hidden="true" src="/icons/status.svg" height="24px" width="24px" />
|
||||||
</figure>
|
</figure>
|
||||||
<span>{{ link.text }}</span>
|
<span>État des services</span>
|
||||||
</a>
|
</a>
|
||||||
{% endfor %}
|
|
||||||
|
<a class="link-classic" href="https://dgnum.eu">
|
||||||
|
<figure class="image is-icon">
|
||||||
|
<img alt="" aria-hidden="true" src="/icons/website.svg" height="24px" width="24px" />
|
||||||
|
</figure>
|
||||||
|
<span>Notre site</span>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a class="link-git" href="https://git.dgnum.eu">
|
||||||
|
<figure class="image is-icon">
|
||||||
|
<img alt="" aria-hidden="true" src="/icons/git.svg" height="24px" width="24px" />
|
||||||
|
</figure>
|
||||||
|
<span>Forge Git</span>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a class="link-mastodon" href="https://social.dgnum.eu/@dgnum">
|
||||||
|
<figure class="image is-icon">
|
||||||
|
<img alt="" aria-hidden="true" src="/icons/mastodon.svg" height="24px" width="24px" />
|
||||||
|
</figure>
|
||||||
|
<span>Mastodon</span>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a class="link-instagram" href="https://www.instagram.com/dgnum_eu/">
|
||||||
|
<figure class="image is-icon">
|
||||||
|
<img alt="" aria-hidden="true" src="/icons/instagram.svg" height="24px" width="24px" />
|
||||||
|
</figure>
|
||||||
|
<span>Instagram</span>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a class="link-classic" href="mailto:contact@dgnum.eu">
|
||||||
|
<figure class="image is-icon">
|
||||||
|
<img alt="" aria-hidden="true" src="/icons/contact.svg" height="24px" width="24px" />
|
||||||
|
</figure>
|
||||||
|
<span>Nous contacter</span>
|
||||||
|
</a>
|
||||||
|
|
||||||
</article>
|
</article>
|
||||||
</body>
|
</body>
|
||||||
|
|
25
lon.lock
|
@ -1,25 +0,0 @@
|
||||||
{
|
|
||||||
"version": "1",
|
|
||||||
"sources": {
|
|
||||||
"lon": {
|
|
||||||
"type": "GitHub",
|
|
||||||
"fetchType": "tarball",
|
|
||||||
"owner": "nikstur",
|
|
||||||
"repo": "lon",
|
|
||||||
"branch": "main",
|
|
||||||
"revision": "a8b4406e5151af87b989564d4aa98ecd6d4d3500",
|
|
||||||
"url": "https://github.com/nikstur/lon/archive/a8b4406e5151af87b989564d4aa98ecd6d4d3500.tar.gz",
|
|
||||||
"hash": "sha256-VGvK0ahBl440NMs03WqmP7T4a1DP13yfX47YI84rlGU="
|
|
||||||
},
|
|
||||||
"nixpkgs": {
|
|
||||||
"type": "GitHub",
|
|
||||||
"fetchType": "tarball",
|
|
||||||
"owner": "nixos",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"branch": "master",
|
|
||||||
"revision": "b53cf65876d5b5dd6fc8d0df3f3f3f185fee164a",
|
|
||||||
"url": "https://github.com/nixos/nixpkgs/archive/b53cf65876d5b5dd6fc8d0df3f3f3f185fee164a.tar.gz",
|
|
||||||
"hash": "sha256-IoiRey6txrqjtmzMcw2Uwwj3t6fPo2pkaoKdkfRezuc="
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
41
lon.nix
|
@ -1,41 +0,0 @@
|
||||||
# Generated by lon. Do not modify!
|
|
||||||
let
|
|
||||||
|
|
||||||
lock = builtins.fromJSON (builtins.readFile ./lon.lock);
|
|
||||||
|
|
||||||
# Override with a path defined in an environment variable. If no variable is
|
|
||||||
# set, the original path is used.
|
|
||||||
overrideFromEnv =
|
|
||||||
name: path:
|
|
||||||
let
|
|
||||||
replacement = builtins.getEnv "LON_OVERRIDE_${name}";
|
|
||||||
in
|
|
||||||
if replacement == "" then
|
|
||||||
path
|
|
||||||
else
|
|
||||||
# this turns the string into an actual Nix path (for both absolute and
|
|
||||||
# relative paths)
|
|
||||||
if builtins.substring 0 1 replacement == "/" then
|
|
||||||
/. + replacement
|
|
||||||
else
|
|
||||||
/. + builtins.getEnv "PWD" + "/${replacement}";
|
|
||||||
|
|
||||||
fetchSource =
|
|
||||||
args@{ fetchType, ... }:
|
|
||||||
if fetchType == "git" then
|
|
||||||
builtins.fetchGit {
|
|
||||||
url = args.url;
|
|
||||||
ref = args.branch;
|
|
||||||
rev = args.revision;
|
|
||||||
narHash = args.hash;
|
|
||||||
}
|
|
||||||
else if fetchType == "tarball" then
|
|
||||||
builtins.fetchTarball {
|
|
||||||
url = args.url;
|
|
||||||
sha256 = args.hash;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
builtins.throw "Unsupported source type ${fetchType}";
|
|
||||||
|
|
||||||
in
|
|
||||||
builtins.mapAttrs (name: args: overrideFromEnv name (fetchSource args)) lock.sources
|
|
|
@ -1,37 +0,0 @@
|
||||||
{
|
|
||||||
lib,
|
|
||||||
buildPythonPackage,
|
|
||||||
fetchFromGitHub,
|
|
||||||
setuptools,
|
|
||||||
wheel,
|
|
||||||
}:
|
|
||||||
|
|
||||||
buildPythonPackage rec {
|
|
||||||
pname = "moody-templates";
|
|
||||||
version = "0.9.1-unstable";
|
|
||||||
pyproject = true;
|
|
||||||
|
|
||||||
src = fetchFromGitHub {
|
|
||||||
owner = "etianen";
|
|
||||||
repo = "moody-templates";
|
|
||||||
rev = "243dc91e4fa6f2225c0e327e96f3416bd165f80a";
|
|
||||||
hash = "sha256-MY91vz2QB1WJzW+lFA9N4YHZaXPqv//OpgH6jwBT0m8=";
|
|
||||||
};
|
|
||||||
|
|
||||||
build-system = [
|
|
||||||
setuptools
|
|
||||||
wheel
|
|
||||||
];
|
|
||||||
|
|
||||||
pythonImportsCheck = [
|
|
||||||
"moody"
|
|
||||||
];
|
|
||||||
|
|
||||||
meta = {
|
|
||||||
description = "A fast, extensible templating engine for Python 3 with Django-like syntax";
|
|
||||||
homepage = "https://github.com/etianen/moody-templates";
|
|
||||||
changelog = "https://github.com/etianen/moody-templates/blob/${src.rev}/CHANGELOG.markdown";
|
|
||||||
license = lib.licenses.bsd3;
|
|
||||||
maintainers = with lib.maintainers; [ ];
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1 +0,0 @@
|
||||||
(import ./. { }).devShell
|
|
93
src/build.py
|
@ -1,93 +0,0 @@
|
||||||
import json
|
|
||||||
import os
|
|
||||||
from dataclasses import asdict, dataclass, fields
|
|
||||||
from os import environ as env
|
|
||||||
from pathlib import Path
|
|
||||||
from shutil import copytree
|
|
||||||
|
|
||||||
from moody import render
|
|
||||||
from watchdog.events import FileSystemEventHandler
|
|
||||||
from watchdog.observers import Observer
|
|
||||||
|
|
||||||
|
|
||||||
def dataclass_from_dict(klass, dikt):
|
|
||||||
try:
|
|
||||||
fieldtypes = {f.name: f.type for f in fields(klass)}
|
|
||||||
return klass(**{f: dataclass_from_dict(fieldtypes[f], dikt[f]) for f in dikt})
|
|
||||||
except:
|
|
||||||
if isinstance(dikt, (tuple, list)):
|
|
||||||
return [dataclass_from_dict(klass.__args__[0], f) for f in dikt]
|
|
||||||
return dikt # Not a dataclass field
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class Link:
|
|
||||||
href: str
|
|
||||||
text: str
|
|
||||||
icon: str
|
|
||||||
cls: str
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class Data:
|
|
||||||
links: list[Link]
|
|
||||||
description: str | None = None
|
|
||||||
|
|
||||||
|
|
||||||
def write_files(rendered: str, src_dir: Path, out_dir: Path):
|
|
||||||
# Copy the static files
|
|
||||||
copytree(src_dir / "www", out_dir, dirs_exist_ok=True)
|
|
||||||
|
|
||||||
# Write out the index file
|
|
||||||
with open(out_dir / "index.html", "w") as fp:
|
|
||||||
fp.write(rendered)
|
|
||||||
|
|
||||||
|
|
||||||
def build_project(src_dir: Path, build_dir: Path):
|
|
||||||
if not os.path.exists(build_dir):
|
|
||||||
os.mkdir(build_dir)
|
|
||||||
|
|
||||||
data_path = env.get("DATA_FILE", src_dir / "data.json")
|
|
||||||
|
|
||||||
# Load the data
|
|
||||||
with open(data_path) as fp:
|
|
||||||
data: Data = dataclass_from_dict(Data, json.load(fp)) # pyright: ignore
|
|
||||||
|
|
||||||
# Render the template with the correct data
|
|
||||||
with open(src_dir / "index.html") as fp:
|
|
||||||
rendered = render(fp.read(), links=data.links, description=data.description)
|
|
||||||
|
|
||||||
write_files(rendered, src_dir, build_dir)
|
|
||||||
|
|
||||||
|
|
||||||
class CatchAllHandler(FileSystemEventHandler):
|
|
||||||
def __init__(self, src_dir: Path, build_dir: Path):
|
|
||||||
self.src_dir = src_dir
|
|
||||||
self.build_dir = build_dir
|
|
||||||
self.count = 0
|
|
||||||
|
|
||||||
def on_modified(self, event):
|
|
||||||
print(f"Files changed, rebuilding project [{self.count}]")
|
|
||||||
build_project(self.src_dir, self.build_dir)
|
|
||||||
self.count += 1
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
src_dir = Path(__file__).parent.resolve()
|
|
||||||
build_dir = Path(env.get("BUILD_DIR", src_dir.parent.resolve() / "build"))
|
|
||||||
watch_files = bool(env.get("WATCH_SRC"))
|
|
||||||
|
|
||||||
build_project(src_dir, build_dir)
|
|
||||||
|
|
||||||
if watch_files:
|
|
||||||
# Create the structure to watch for changes
|
|
||||||
observer = Observer()
|
|
||||||
observer.schedule(CatchAllHandler(src_dir, build_dir), src_dir, recursive=True)
|
|
||||||
observer.start()
|
|
||||||
|
|
||||||
try:
|
|
||||||
while observer.is_alive():
|
|
||||||
observer.join()
|
|
||||||
finally:
|
|
||||||
observer.stop()
|
|
||||||
observer.join()
|
|
|
@ -1,41 +0,0 @@
|
||||||
{
|
|
||||||
"links": [
|
|
||||||
{
|
|
||||||
"text": "État des services",
|
|
||||||
"href": "https://status.dgnum.eu",
|
|
||||||
"cls": "link-status",
|
|
||||||
"icon": "status.svg"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"text": "Notre site",
|
|
||||||
"href": "https://dgnum.eu",
|
|
||||||
"cls": "link-classic",
|
|
||||||
"icon": "website.svg"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"text": "Forge Git",
|
|
||||||
"href": "https://git.dgnum.eu",
|
|
||||||
"cls": "link-git",
|
|
||||||
"icon": "git.svg"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"text": "Mastodon",
|
|
||||||
"href": "https://social.dgnum.eu/@dgnum",
|
|
||||||
"cls": "link-mastodon",
|
|
||||||
"icon": "mastodon.svg"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"text": "Instagram",
|
|
||||||
"href": "https://www.instagram.com/dgnum_eu/",
|
|
||||||
"cls": "link-instagram",
|
|
||||||
"icon": "instagram.svg"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"text": "Nous contacter",
|
|
||||||
"href": "mailto:contact@dgnum.eu",
|
|
||||||
"cls": "link-classic",
|
|
||||||
"icon": "contact.svg"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "La Délégation Générale Numérique est une association loi 1901 domiciliée à l'ENS dont les buts sont de promouvoir la chose numérique ainsi que son usage."
|
|
||||||
}
|
|