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" />
|
||||
</figure>
|
||||
<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>
|
||||
<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">
|
||||
<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>
|
||||
<span>{{ link.text }}</span>
|
||||
<span>État des services</span>
|
||||
</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>
|
||||
</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."
|
||||
}
|