Docker image (#84)

* Add [guix](https://guix.gnu.org/) package.

This enables:

- [direnv](https://direnv.net/) integration to setup and tear down
  a suitable development environment;
- if you're not a direnv user you can always
  `guix environment -l guix.scm` to spawn a shell
  with all the necessary dependencies;
- Export of Mobilizon Reshare and its dependencies
  to one of the formats supported by `guix pack`. Right now they are:

    + tarball       Self-contained tarball, ready to run on another machine
    + squashfs      Squashfs image suitable for Singularity
    + docker        Docker image ready for 'docker load'
    + deb           Debian archive installable via dpkg/apt

* Add docker image and docker-compose.yml.

* Add Github CI workflow.
This commit is contained in:
Giacomo Leidi 2021-10-31 01:55:25 +02:00 committed by GitHub
parent 84e54a503e
commit ba3eef4341
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 970 additions and 2 deletions

35
.envrc Normal file
View File

@ -0,0 +1,35 @@
if command -v guix; then
eval "$(guix time-machine -C channels-lock.scm -- shell -r .guix-root -D -f guix.scm -m manifest.scm --pure --search-paths -L . -L ./patches)"
# Add development scripts to PATH
export PATH="$(pwd)/scripts:${PATH}"
venv_dir=".venv"
if [ ! -e "$venv_dir/bin/python" ] ; then
rm -rvf "$venv_dir"
pre-commit uninstall
fi
if [ ! -d "$venv_dir" ] ; then
virtualenv -p `which python3.9` "$venv_dir"
poetry install
pre-commit install
fi
clear
git-cal --author="$(git config user.name)"
run-tests () {
poetry run pytest
}
export_function run-tests
cat << EOF
run-tests Runs pytest in the current directory
The 'scripts' directory has been added to your PATH: you can now invoke scripts without typing the relative path.
EOF
fi

67
.github/workflows/main.yml vendored Normal file
View File

@ -0,0 +1,67 @@
# This is a basic workflow to help you get started with Actions
name: CI
# Controls when the workflow will run
on:
push:
# Sequence of patterns matched against refs/tags
tags:
- v*
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
# This workflow contains a single job called "build"
build:
# The type of runner that the job will run on
runs-on: ubuntu-latest
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v2
# Runs a single command using the runners shell
- name: Install GNU Guix
uses: PromyLOPh/guix-install-action@v1
# Runs a set of commands using the runners shell
- name: Build image
run: scripts/build_docker_image.sh
- name: Upload pack (Docker)
uses: actions/upload-artifact@v2
with:
name: mobilizon-reshare-docker
path: docker-image.tar.gz
publish:
# The type of runner that the job will run on
runs-on: ubuntu-latest
needs: build
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v2
- name: Get release tag
id: vars
run: echo ::set-output name=tag::${GITHUB_REF#refs/*/}
- name: Download image
uses: actions/download-artifact@v2
with:
name: mobilizon-reshare-docker
- name: Publish to Docker Hub
uses: fishinthecalculator/publish-docker-image-action@v0.1.3
env:
IMAGE_TAG: ${{ steps.vars.outputs.tag }}
with:
name: fishinthecalculator/mobilizon-reshare
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
image: docker-image.tar.gz

5
.gitignore vendored
View File

@ -176,3 +176,8 @@ crashlytics-build.properties
fabric.properties
.idea
*/local_testing.toml
.direnv/
etc/
var/
docker-image.tar.gz
.guix-root

11
channels-lock.scm Normal file
View File

@ -0,0 +1,11 @@
(list
(channel
(name 'guix)
(url "https://git.savannah.gnu.org/git/guix.git")
(commit
"de3bf035b4e42474355af3a4b110b54835098ac4")
(introduction
(make-channel-introduction
"9edb3f66fd807b096b48283debdcddccfea34bad"
(openpgp-fingerprint
"BBB0 2DDF 2CEA F6A8 0D1D E643 A2A0 6DF2 A33A 54FA")))))

View File

@ -0,0 +1,118 @@
# Hacking with Guix on Mobilizon Reshare
To setup a development environment to hack on `mobilizon-reshare` you can use [Guix](https://guix.gnu.org/) and [direnv](https://direnv.net/).
If you already have `guix` and `direnv` installed on your system, the development environment setup is as easy as:
```shell
$ git clone https://github.com/Tech-Workers-Coalition-Italia/mobilizon-reshare
$ cd mobilizon-reshare/
direnv: error .envrc is blocked. Run `direnv allow` to approve its content.
$ direnv allow
direnv: loading .envrc
[...]
direnv: export +CPLUS_INCLUDE_PATH +C_INCLUDE_PATH +LIBRARY_PATH ~GUIX_LOCPATH ~PATH ~PYTHONPATH
$
```
Hurray 🎉 ! Now you can hack on `mobilizon-reshare` without worrying about dependencies.
## Installing Guix
*Caveat:* Guix currently runs only on Linux, if you run a different OS you're probably better off with something like [poetry](https://python-poetry.org/). Just beware that you may end up with slightly different behavior, since `poetry` only locks Python dependencies.
### Debian Bullseye
If you run Debian Bullseye (or one of its derivatives) installing Guix is achieved with:
```shell
$ sudo apt install guix
```
If you want to find out if your distribution is a derivative of Debian Bullseye you can run:
```shell
$ sudo cat /etc/debian_release
```
### Arch Linux
The Arch Wiki has a very good [article](https://wiki.archlinux.org/title/Guix).
### Other distributions
For every other distributions you can install Guix with the installer script. It will guide you through the process of installing Guix.
```shell
$ curl https://git.savannah.gnu.org/cgit/guix.git/plain/etc/guix-install.sh | sudo bash
```
Beware that piping to `sudo bash` is usually a *very* bad idea. Before running the above command please read the script and the Guix manual.
## Configuring Guix
To make Guix applications work out of the box you should add the following variables to your `.bash_profile` (or its equivalent for shells other than Bash):
```shell
GUIX_PROFILE="${HOME}/.guix-profile"
. "$GUIX_PROFILE/etc/profile"
export GUIX_LOCPATH="$GUIX_PROFILE/lib/locale"
export SSL_CERT_DIR="$GUIX_PROFILE/etc/ssl/certs"
export SSL_CERT_FILE="$GUIX_PROFILE/etc/ssl/certs/ca-certificates.crt"
export GIT_SSL_CAINFO="$SSL_CERT_FILE"
export CURL_CA_BUNDLE="$SSL_CERT_FILE"
export INFOPATH="$GUIX_PROFILE${INFOPATH:+:}${INFOPATH}"
export MANPATH="$GUIX_PROFILE${MANPATH:+:}${MANPATH}"
GUIX_PROFILE="$XDG_CONFIG_HOME/guix/current"
. "$GUIX_PROFILE/etc/profile"
```
and then run **in a new shell**
```shell
$ guix install nss-certs
$ sudo -i guix install glibc-locales
```
## Installing direnv
Once you have Guix properly setup, you can install `direnv` with:
```shell
$ guix install direnv
```
then you should [hook it](https://direnv.net/docs/hook.html) into your shell.
## Troubleshooting
Guix sometimes prints somewhat scary messages like:
```shell
$ guix install hello
The following package will be installed:
hello 2.10
The following derivation will be built:
/gnu/store/15s9gs89i6bf16skwb1c03bm4wj9h30a-profile.drv
building CA certificate bundle...
listing Emacs sub-directories...
building fonts directory...
building directory of Info manuals...
building database for manual pages...
building profile with 1 package...
hint: Consider setting the necessary environment variables by running:
GUIX_PROFILE="~/.guix-profile/hello-profile"
. "$GUIX_PROFILE/etc/profile"
Alternately, see `guix package --search-paths'.
$
```
when you see a message like that you can either run it to make the current shell work with the new packages installed by Guix or just close the current shell and spawn another, this way it'll put Guix packages in the right plache in your `PATH`.

10
docker-compose.yml Normal file
View File

@ -0,0 +1,10 @@
version: "3.7"
services:
mobilizon-reshare:
image: fishinthecalculator/mobilizon-reshare:latest
environment:
SECRETS_FOR_DYNACONF: /etc/xdg/mobilizon-reshare/0.1.0/.secrets.toml
ENV_FOR_DYNACONF: production
volumes:
- ./etc:/etc/xdg/mobilizon-reshare/0.1.0
- ./var:/var/lib/mobilizon-reshare

60
docker/image.scm Normal file
View File

@ -0,0 +1,60 @@
(define-module (docker image)
#:use-module (gnu)
#:use-module (gnu packages admin) ;; for shadow
#:use-module (gnu packages base) ;; for coreutils
#:use-module (gnu packages bash) ;; for bash
#:use-module (gnu packages gawk) ;; for gawk
#:use-module (gnu packages less) ;; for less
#:use-module (guix gexp) ;; for #$ and #~
#:use-module (docker mobilizon-reshare) ;; for mobilizon-reshare.git
#:use-module (docker service) ;; for mobilizon-reshare-service-type
#:use-module (gnu services base) ;; for special-file-service-type
#:use-module (gnu services mcron)) ;; for mcron
(define mobilizon-reshare-job
;; Run mobilizon-reshare every 15th minute.
#~(job "*/15 * * * *"
(string-append #$mobilizon-reshare.git "/bin/mobilizon-reshare start")
"mobilizon-reshare-start"
#:user "mobilizon-reshare"))
(define mobilizon-reshare-docker-image
(operating-system
(locale "it_IT.utf8")
(timezone "Europe/Rome")
(keyboard-layout
(keyboard-layout "it" "nodeadkeys"))
(bootloader
(bootloader-configuration
(bootloader grub-bootloader)))
(file-systems
(list
(file-system
(mount-point "/")
(device "/dev/fake")
(type "ext4"))))
(host-name "mobilizon-reshare-scheduler")
(packages
(list
coreutils
findutils
less
grep
gawk
sed))
(services
(list
(service mobilizon-reshare-service-type)
(service special-files-service-type
`(("/bin/sh" ,(file-append bash "/bin/bash"))))
(service mcron-service-type)
(simple-service 'mobilizon-reshare-cron-jobs
mcron-service-type
(list mobilizon-reshare-job))))))
mobilizon-reshare-docker-image

View File

@ -0,0 +1,401 @@
(define-module (docker mobilizon-reshare)
#:use-module (guix download)
#:use-module (guix gexp)
#:use-module (guix git-download)
#:use-module (guix packages)
#:use-module (guix utils)
#:use-module ((guix licenses) #:prefix license:)
#:use-module (guix build-system python)
#:use-module (gnu packages)
#:use-module (gnu packages check)
#:use-module (gnu packages databases)
#:use-module (gnu packages django)
#:use-module (gnu packages python)
#:use-module (gnu packages python-build)
#:use-module (gnu packages python-check)
#:use-module (gnu packages python-web)
#:use-module (gnu packages python-xyz)
#:use-module (gnu packages serialization)
#:use-module (gnu packages time)
#:use-module (gnu packages web)
#:use-module (ice-9 popen)
#:use-module (ice-9 rdelim)
#:use-module (srfi srfi-1))
(define %source-dir (getcwd))
(define coopyleft
(let ((license (@@ (guix licenses) license)))
(license "Coopyleft"
"https://wiki.coopcycle.org/en:license"
"Coopyleft License")))
(define wrap-python3
(@@ (gnu packages python) wrap-python3))
(define-public python-3.9-wrapper
(wrap-python3 python-3.9))
;; TODO: This should probably be upstreamed.
(define-public python-dotenv
(package
(name "python-dotenv")
(version "0.17.0")
(source
(origin
(method url-fetch)
(uri (pypi-uri "python-dotenv" version))
(sha256
(base32
"0jjg7b8073gxsmh47ic152xdxym5zhw887ilh0ddl45gl0nph6s7"))))
(build-system python-build-system)
(propagated-inputs
`(("python-click" ,python-click)))
(native-inputs
`(("python-mock" ,python-mock)
("python-pytest" ,python-pytest)
("python-sh" ,python-sh)))
(home-page
"https://github.com/theskumar/python-dotenv")
(synopsis
"Setup environment variables according to .env files")
(description
"This package provides the @code{python-dotenv} Python module to
read key-value pairs from a .env file and set them as environment variables")
(license license:bsd-3)))
;; TODO: This should probably be upstreamed.
;; This is only for python-dynaconf.
(define-public python-dotenv-0.13.0
(package (inherit python-dotenv)
(name "python-dotenv")
(version "0.13.0")
(source
(origin
(method url-fetch)
(uri (pypi-uri "python-dotenv" version))
(sha256
(base32
"0x5dagmfn31phrbxlwacw3s4w5vibv8fxqc62nqcdvdhjsy0k69v"))))))
;; TODO: This should probably be upstreamed.
;; This is only for python-dynaconf.
(define-public python-ruamel.yaml-0.16.10
(package (inherit python-ruamel.yaml)
(name "python-ruamel.yaml")
(version "0.16.10")
(source
(origin
(method url-fetch)
(uri (pypi-uri "ruamel.yaml" version))
(sha256
(base32
"0m5rwlf3iwsb1w9l98qx9alvqxk41gfphksj03x2zxwbfx569709"))))))
;; TODO: This should probably be upstreamed.
(define-public python-dynaconf
(package
(name "dynaconf")
(version "3.1.5")
(source
(origin
(method git-fetch)
(uri
(git-reference
(url "https://github.com/rochacbruno/dynaconf")
(commit version)))
(file-name (git-file-name name version))
(sha256
(base32
"0hxp1iadwmva79l16frvc77jrisppb09z6k1asm0qfjjzwyaswg3"))
(patches (search-patches "dynaconf-Unvendor-dependencies.patch"))
(modules '((guix build utils)))
(snippet '(begin
;; Remove vendored dependencies
(let ((unvendor '("click" "dotenv" "ruamel" "toml")))
(with-directory-excursion "dynaconf/vendor"
(for-each delete-file-recursively unvendor))
(with-directory-excursion "dynaconf/vendor_src"
(for-each delete-file-recursively unvendor)))))))
(build-system python-build-system)
(arguments
`(#:phases
(modify-phases %standard-phases
(replace 'check
(lambda* (#:key tests? outputs #:allow-other-keys)
(when tests?
(setenv "PATH"
(string-append (assoc-ref outputs "out") "/bin:"
(getenv "PATH")))
;; These tests depend on hvac and a
;; live Vault process.
(delete-file "tests/test_vault.py")
(invoke "make" "test_only")))))))
(propagated-inputs
`(("python-click" ,python-click)
("python-configobj" ,python-configobj)
("python-dotenv" ,python-dotenv-0.13.0)
("python-ruamel.yaml" ,python-ruamel.yaml-0.16.10)
("python-toml" ,python-toml)))
(native-inputs
`(("python-django" ,python-django)
("python-flask" ,python-flask)
("python-pytest" ,python-pytest-6)
("python-pytest-cov" ,python-pytest-cov)
("python-pytest-mock" ,python-pytest-mock)))
(home-page "https://www.dynaconf.com/")
(synopsis "The dynamic configurator for your Python project")
(description
"This package provides @code{dynaconf} the dynamic configurator manager for
your Python project. It provides features such as:
@itemize
@item Inspired by the @url{https://12factor.net/config, 12-factor application guide};
@item Settings management (default values, validation, parsing, templating);
@item Protection of sensitive information (passwords/tokens);
@item Multiple file formats @code{toml|yaml|json|ini|py} and also customizable
loaders;
@item Full support for environment variables to override existing settings
(dotenv support included);
@item Optional layered system for multiple environments @code{[default,
development, testing, production]};
@item Built-in support for Hashicorp Vault and Redis as settings and secrets storage;
@item Built-in extensions for Django and Flask web frameworks;
@item CLI for common operations such as @code{init, list, write, validate, export}.
@end itemize")
(license license:expat)))
;; This is only for mobilizon-bots.git.
(define-public python-arrow-1.1
(package (inherit python-arrow)
(name "python-arrow")
(version "1.1.0")
(source
(origin
(method url-fetch)
(uri (pypi-uri "arrow" version))
(sha256
(base32
"1n2vzyrirfj7fp0zn6iipm3i8bch0g4m14z02nrvlyjiyfmi7zmq"))))))
;; This is only for mobilizon-bots.git.
(define-public python-tortoise-orm-0.17
(package (inherit python-tortoise-orm)
(name "python-tortoise-orm")
(version "0.17.6")
(source
(origin
(method url-fetch)
(uri (pypi-uri "tortoise-orm" version))
(sha256
(base32
"0viwmd8773b4bz8119d26wd3qxrdhmafrqd4m8bdz3439gcpq67l"))))))
;; This is only for mobilizon-bots.git.
(define-public python-pytest-asyncio-0.15
(package (inherit python-pytest-asyncio)
(name "python-pytest-asyncio")
(version "0.15.1")
(source
(origin
(method url-fetch)
(uri (pypi-uri "pytest-asyncio" version))
(sha256
(base32
"0vrzsrg3j1cfd57m0b3r5xf87rslgcs42jya346mdg9bc6wwwr15"))))
(arguments
(substitute-keyword-arguments (package-arguments python-pytest-asyncio)
((#:tests? _ #f) #f)))))
(define-public python-markdownify
(package
(name "python-markdownify")
(version "0.9.2")
(source
(origin
(method url-fetch)
(uri (pypi-uri "markdownify" version))
(sha256
(base32
"0zfpzdwkf34spmfr2iwkqch3fi0nnll2v5nghvgnrmazjn4rcxdr"))))
(build-system python-build-system)
(arguments
`(#:tests? #f))
(native-inputs
`(("python-pytest" ,python-pytest-6)))
(propagated-inputs
`(("python-flake8" ,python-flake8)
("python-beautifulsoup4" ,python-beautifulsoup4)
("python-six" ,python-six)))
(home-page
"http://github.com/matthewwithanm/python-markdownify")
(synopsis "Convert HTML to markdown.")
(description "Convert HTML to markdown.")
(license license:expat)))
(define-public python-ipaddress
(package
(name "python-ipaddress")
(version "1.0.23")
(source
(origin
(method url-fetch)
(uri (pypi-uri "ipaddress" version))
(sha256
(base32 "1qp743h30s04m3cg3yk3fycad930jv17q7dsslj4mfw0jlvf1y5p"))))
(build-system python-build-system)
(home-page "https://github.com/phihag/ipaddress")
(synopsis "IPv4/IPv6 manipulation library")
(description "IPv4/IPv6 manipulation library")
(license #f)))
(define-public python-vcrpy
(package
(name "python-vcrpy")
(version "4.1.1")
(source
(origin
(method url-fetch)
(uri (pypi-uri "vcrpy" version))
(sha256
(base32 "16gmzxs3lzbgf1828n0q61vbmwyhpvzdlk37x6gdk8n05zr5n2ap"))))
(build-system python-build-system)
(arguments
`(#:phases
(modify-phases %standard-phases
(replace 'check
(lambda* (#:key tests? outputs #:allow-other-keys)
(when tests?
(substitute* "tox.ini"
(("AWS_ACCESS_KEY_ID") "PYTHONPATH"))
(setenv "PYTHONPATH" (string-append ".:" (getenv "PYTHONPATH")))
;; These tests require network access.
(delete-file "tests/unit/test_stubs.py")
(invoke "pytest" "tests/unit")))))))
(native-inputs
`(
("python-black" ,python-black)
("python-coverage" ,python-coverage)
("python-flake8" ,python-flake8)
("python-flask" ,python-flask)
("python-httplib2" ,python-httplib2)
("python-ipaddress" ,python-ipaddress)
("python-mock" ,python-mock)
("python-pytest" ,python-pytest)
("python-pytest-cov" ,python-pytest-cov)
("python-pytest-httpbin" ,python-pytest-httpbin)
("python-tox" ,python-tox)
("python-urllib3" ,python-urllib3)))
(propagated-inputs
`(("python-pyyaml" ,python-pyyaml)
("python-six" ,python-six)
("python-wrapt" ,python-wrapt)
("python-yarl" ,python-yarl)))
(home-page "https://github.com/kevin1024/vcrpy")
(synopsis
"Automatically mock your HTTP interactions to simplify and speed up testing")
(description
"Automatically mock your HTTP interactions to simplify and speed up testing")
(license license:expat)))
(define-public python-tweepy
(package
(name "python-tweepy")
(version "4.1.0")
(source
(origin
(method git-fetch)
(uri
(git-reference
(url "https://github.com/tweepy/tweepy")
(commit (string-append "v" version))))
(file-name (git-file-name name version))
(sha256
(base32
"1c0paxc38i5jq8i20f9xwv966sap4nnhgnbdxg3611pllnzg5wdv"))))
(build-system python-build-system)
(arguments
`(#:phases
(modify-phases %standard-phases
(replace 'check
(lambda* (#:key tests? inputs outputs #:allow-other-keys)
(when tests?
(invoke "python" "-m" "unittest")))))))
(propagated-inputs
`(("python-aiohttp" ,python-aiohttp)
("python-requests" ,python-requests)
("python-requests-oauthlib" ,python-requests-oauthlib)))
(native-inputs
`(("python-coveralls" ,python-coveralls)
("python-tox" ,python-tox)
("python-vcrpy" ,python-vcrpy)))
(home-page "https://www.tweepy.org/")
(synopsis "Twitter library for Python")
(description "Twitter library for Python")
(license license:expat)))
(define-public mobilizon-reshare.git
(let ((source-version (with-input-from-file
(string-append %source-dir
"/mobilizon_reshare/VERSION")
read-line))
(revision "0")
(commit (read-line
(open-input-pipe "git show HEAD | head -1 | cut -d ' ' -f 2"))))
(package
(name "mobilizon-reshare.git")
(version (git-version source-version revision commit))
(source (local-file %source-dir
#:recursive? #t
#:select? (git-predicate %source-dir)))
(build-system python-build-system)
(arguments
`(#:python ,python-3.9
#:phases
(modify-phases %standard-phases
(add-after 'unpack 'generate-setup.py
(lambda* (#:key inputs outputs #:allow-other-keys)
;; This is a hack needed to get poetry's
;; setup.py.
(setenv "POETRY_VIRTUALENVS_CREATE" "false")
(invoke "poetry" "build" "-f" "sdist")
(invoke "bash" "-c"
"tar --wildcards -xvf dist/*-`poetry version -s`.tar.gz -O '*/setup.py' > setup.py")
(substitute* "setup.py"
(("'install_requires': install_requires,") ""))))
(replace 'check
(lambda* (#:key tests? inputs outputs #:allow-other-keys)
(when tests?
(invoke "python" "-m" "pytest"
;; This test fails because of the unvendoring
;; of toml from dynaconf.
"-k" "not test_get_settings_failure_invalid_toml")))))))
(native-inputs
`(("python-asynctest" ,python-asynctest)
("python-iniconfig" ,python-iniconfig)
("poetry" ,poetry)
("python-pytest" ,python-pytest-6)
("python-pytest-asyncio" ,python-pytest-asyncio-0.15)
("python-responses" ,python-responses)
("python-wrapper" ,python-3.9-wrapper)))
(propagated-inputs
`(("python-aiosqlite" ,python-aiosqlite)
("python-appdirs" ,python-appdirs)
("python-arrow" ,python-arrow-1.1)
("python-beautifulsoup4" ,python-beautifulsoup4)
("python-click" ,python-click)
("python-dynaconf" ,python-dynaconf)
("python-jinja2" ,python-jinja2)
("python-markdownify" ,python-markdownify)
("python-requests" ,python-requests)
("python-tweepy" ,python-tweepy)
("python-tortoise-orm" ,python-tortoise-orm-0.17)))
(home-page
"https://github.com/Tech-Workers-Coalition-Italia/mobilizon-reshare")
(synopsis
"Publish Mobilizon events to your social networks")
(description
"This package provides a CLI application to publish your Mobilizon
events to your social media.")
(license coopyleft))))

52
docker/service.scm Normal file
View File

@ -0,0 +1,52 @@
(define-module (docker service)
#:use-module (gnu services)
#:use-module (gnu system shadow)
#:use-module (gnu packages admin)
#:use-module (guix records)
#:use-module (guix gexp)
#:use-module (docker mobilizon-reshare)
#:export (mobilizon-reshare-service-type
mobilizon-reshare-configuration
mobilizon-reshare-configuration?))
(define-record-type* <mobilizon-reshare-configuration>
mobilizon-reshare-configuration make-mobilizon-reshare-configuration
mobilizon-reshare-configuration?
(mobilizon-reshare mobilizon-reshare-configuration-mobilizon-reshare (default mobilizon-reshare.git))
(datadir mobilizon-reshare-datadir (default "/var/lib/mobilizon-reshare")))
(define %mobilizon-reshare-accounts
(list (user-group
(name "mobilizon-reshare")
(system? #t))
(user-account
(name "mobilizon-reshare")
(comment "Mobilizon Reshare's Service Account")
(group "mobilizon-reshare")
(system? #t)
(home-directory "/var/empty")
(shell (file-append shadow "/sbin/nologin")))))
(define (%mobilizon-reshare-activation config)
"Return an activation gexp for Mobilizon Reshare."
(let ((datadir (mobilizon-reshare-datadir config)))
#~(begin
(use-modules (guix build utils))
(let* ((user (getpwnam "mobilizon-reshare"))
(uid (passwd:uid user))
(gid (passwd:gid user))
(datadir #$datadir))
(mkdir-p datadir)
(chown datadir uid gid)))))
(define mobilizon-reshare-service-type
(service-type
(name 'mobilizon-reshare)
(extensions
(list (service-extension profile-service-type
(compose list mobilizon-reshare-configuration-mobilizon-reshare))
(service-extension account-service-type
(const %mobilizon-reshare-accounts))
(service-extension activation-service-type
%mobilizon-reshare-activation)))
(default-value (mobilizon-reshare-configuration))))

3
guix.scm Normal file
View File

@ -0,0 +1,3 @@
(use-modules (docker mobilizon-reshare))
mobilizon-reshare.git

18
manifest.scm Normal file
View File

@ -0,0 +1,18 @@
(define-module (manifest)
#:use-module (docker mobilizon-reshare)
#:use-module (gnu packages)
#:use-module (guix profiles))
(packages->manifest
(append
(list
python-3.9-wrapper)
(map specification->package+output
'("meld" "git-cal" "man-db" "texinfo"
"python-pre-commit" "poetry" "bzip2"
"guix" "grep" "sed" "unzip" "bash" "ncurses"
"findutils" "ripgrep" "python-semver"
"util-linux" "python-black" "gawk" "fd"
"coreutils" "less" "git" "git:credential-libsecret"
"gitg" "direnv" "which" "vim" "emacs"
"tar" "gzip" "openssh" "docker-cli" "docker-compose"))))

View File

@ -0,0 +1,180 @@
From 3f7b48195500cbbbbecd3cac2f5308c64004479b Mon Sep 17 00:00:00 2001
From: Giacomo Leidi <goodoldpaul@autistici.org>
Date: Sun, 29 Aug 2021 23:39:27 +0200
Subject: [PATCH] Use system site dependencies.
Box was not unvendored because it appears to be heavily patched.
---
dynaconf/cli.py | 4 ++--
dynaconf/default_settings.py | 2 +-
dynaconf/loaders/env_loader.py | 2 +-
dynaconf/loaders/toml_loader.py | 2 +-
dynaconf/loaders/yaml_loader.py | 2 +-
dynaconf/utils/parse_conf.py | 2 +-
dynaconf/vendor/box/converters.py | 4 ++--
dynaconf/vendor/box/from_file.py | 4 ++--
dynaconf/vendor_src/box/converters.py | 4 ++--
dynaconf/vendor_src/box/from_file.py | 4 ++--
tests/test_cli.py | 2 +-
11 files changed, 16 insertions(+), 16 deletions(-)
diff --git a/dynaconf/cli.py b/dynaconf/cli.py
index 5bb8316..1341a95 100644
--- a/dynaconf/cli.py
+++ b/dynaconf/cli.py
@@ -20,8 +20,8 @@ from dynaconf.utils.functional import empty
from dynaconf.utils.parse_conf import parse_conf_data
from dynaconf.validator import ValidationError
from dynaconf.validator import Validator
-from dynaconf.vendor import click
-from dynaconf.vendor import toml
+import click
+import toml
CWD = Path.cwd()
diff --git a/dynaconf/default_settings.py b/dynaconf/default_settings.py
index 66601b0..9605fc5 100644
--- a/dynaconf/default_settings.py
+++ b/dynaconf/default_settings.py
@@ -8,7 +8,7 @@ from dynaconf.utils import upperfy
from dynaconf.utils import warn_deprecations
from dynaconf.utils.files import find_file
from dynaconf.utils.parse_conf import parse_conf_data
-from dynaconf.vendor.dotenv import load_dotenv
+from dotenv import load_dotenv
def try_renamed(key, value, older_key, current_key):
diff --git a/dynaconf/loaders/env_loader.py b/dynaconf/loaders/env_loader.py
index e7b13bd..b034c8a 100644
--- a/dynaconf/loaders/env_loader.py
+++ b/dynaconf/loaders/env_loader.py
@@ -2,7 +2,7 @@ from os import environ
from dynaconf.utils import upperfy
from dynaconf.utils.parse_conf import parse_conf_data
-from dynaconf.vendor.dotenv import cli as dotenv_cli
+from dotenv import cli as dotenv_cli
IDENTIFIER = "env"
diff --git a/dynaconf/loaders/toml_loader.py b/dynaconf/loaders/toml_loader.py
index 07b973f..d81d675 100644
--- a/dynaconf/loaders/toml_loader.py
+++ b/dynaconf/loaders/toml_loader.py
@@ -5,7 +5,7 @@ from dynaconf import default_settings
from dynaconf.constants import TOML_EXTENSIONS
from dynaconf.loaders.base import BaseLoader
from dynaconf.utils import object_merge
-from dynaconf.vendor import toml
+import toml
def load(obj, env=None, silent=True, key=None, filename=None):
diff --git a/dynaconf/loaders/yaml_loader.py b/dynaconf/loaders/yaml_loader.py
index 33c6532..3ef419a 100644
--- a/dynaconf/loaders/yaml_loader.py
+++ b/dynaconf/loaders/yaml_loader.py
@@ -7,7 +7,7 @@ from dynaconf.constants import YAML_EXTENSIONS
from dynaconf.loaders.base import BaseLoader
from dynaconf.utils import object_merge
from dynaconf.utils.parse_conf import try_to_encode
-from dynaconf.vendor.ruamel import yaml
+from ruamel import yaml
# Add support for Dynaconf Lazy values to YAML dumper
yaml.SafeDumper.yaml_representers[
diff --git a/dynaconf/utils/parse_conf.py b/dynaconf/utils/parse_conf.py
index c42b07a..01ccdae 100644
--- a/dynaconf/utils/parse_conf.py
+++ b/dynaconf/utils/parse_conf.py
@@ -9,7 +9,7 @@ from dynaconf.utils import isnamedtupleinstance
from dynaconf.utils import multi_replace
from dynaconf.utils import recursively_evaluate_lazy_format
from dynaconf.utils.boxing import DynaBox
-from dynaconf.vendor import toml
+import toml
try:
from jinja2 import Environment
diff --git a/dynaconf/vendor/box/converters.py b/dynaconf/vendor/box/converters.py
index 93cdcfb..e34c7dc 100644
--- a/dynaconf/vendor/box/converters.py
+++ b/dynaconf/vendor/box/converters.py
@@ -7,9 +7,9 @@ _B='utf-8'
_A=None
import csv,json,sys,warnings
from pathlib import Path
-import dynaconf.vendor.ruamel.yaml as yaml
+import ruamel.yaml as yaml
from dynaconf.vendor.box.exceptions import BoxError,BoxWarning
-from dynaconf.vendor import toml
+import toml
BOX_PARAMETERS='default_box','default_box_attr','conversion_box','frozen_box','camel_killer_box','box_safe_prefix','box_duplicates','ordered_box','default_box_none_transform','box_dots','modify_tuples_box','box_intact_types','box_recast'
def _exists(filename,create=_E):
A=filename;B=Path(A)
diff --git a/dynaconf/vendor/box/from_file.py b/dynaconf/vendor/box/from_file.py
index daa1137..d75940b 100644
--- a/dynaconf/vendor/box/from_file.py
+++ b/dynaconf/vendor/box/from_file.py
@@ -1,8 +1,8 @@
from json import JSONDecodeError
from pathlib import Path
from typing import Union
-from dynaconf.vendor.toml import TomlDecodeError
-from dynaconf.vendor.ruamel.yaml import YAMLError
+from toml import TomlDecodeError
+from ruamel.yaml import YAMLError
from .exceptions import BoxError
from .box import Box
from .box_list import BoxList
diff --git a/dynaconf/vendor_src/box/converters.py b/dynaconf/vendor_src/box/converters.py
index c9a2293..ae42bf6 100644
--- a/dynaconf/vendor_src/box/converters.py
+++ b/dynaconf/vendor_src/box/converters.py
@@ -9,9 +9,9 @@ import sys
import warnings
from pathlib import Path
-import dynaconf.vendor.ruamel.yaml as yaml
+import ruamel.yaml as yaml
from dynaconf.vendor.box.exceptions import BoxError, BoxWarning
-from dynaconf.vendor import toml
+import toml
BOX_PARAMETERS = ('default_box', 'default_box_attr', 'conversion_box',
diff --git a/dynaconf/vendor_src/box/from_file.py b/dynaconf/vendor_src/box/from_file.py
index 2e2a6ad..3f76819 100644
--- a/dynaconf/vendor_src/box/from_file.py
+++ b/dynaconf/vendor_src/box/from_file.py
@@ -3,8 +3,8 @@
from json import JSONDecodeError
from pathlib import Path
from typing import Union
-from dynaconf.vendor.toml import TomlDecodeError
-from dynaconf.vendor.ruamel.yaml import YAMLError
+from toml import TomlDecodeError
+from ruamel.yaml import YAMLError
from .exceptions import BoxError
diff --git a/tests/test_cli.py b/tests/test_cli.py
index 6693701..df44409 100644
--- a/tests/test_cli.py
+++ b/tests/test_cli.py
@@ -11,7 +11,7 @@ from dynaconf.cli import main
from dynaconf.cli import read_file_in_root_directory
from dynaconf.cli import WRITERS
from dynaconf.utils.files import read_file
-from dynaconf.vendor.click.testing import CliRunner
+from click.testing import CliRunner
runner = CliRunner()
base-commit: ebf7b17cffd5e08b212948bd8036d580718d5bf8
--
2.32.0

4
scripts/build_docker_image.sh Executable file
View File

@ -0,0 +1,4 @@
#!/bin/sh
set -eu
guix time-machine -C channels-lock.scm -- system docker-image -L . -L ./patches --root=docker-image.tar.gz docker/image.scm

View File

@ -5,6 +5,7 @@ set -eu
myself="$(basename "$0")"
version_file="$(pwd)/mobilizon_reshare/VERSION"
pyproject_toml="$(pwd)/pyproject.toml"
docker_compose_yml="$(pwd)/docker-compose.yml"
current_branch="$(git rev-parse --abbrev-ref HEAD)"
current_commit="$(git log -1 --format='%H')"
dryrun=0
@ -81,8 +82,11 @@ release-new-version() {
[ "$verbose" = "1" ] && echo "Updating $pyproject_toml"
[ "$dryrun" = "0" ] && sed -i -E "s/version.*=.*\"${current}\"$/version = \"${next}\"/" "$pyproject_toml"
[ "$verbose" = "1" ] && echo "Committing ${pyproject_toml} and ${version_file}"
[ "$dryrun" = "0" ] && git add "${pyproject_toml}" "${version_file}" && git commit -m "Release v${next}."
[ "$verbose" = "1" ] && echo "Updating $docker_compose_yml"
[ "$dryrun" = "0" ] && sed -i "s/${current}/${next}/" "$docker_compose_yml"
[ "$verbose" = "1" ] && echo "Committing ${pyproject_toml}, ${docker_compose_yml} and ${version_file}"
[ "$dryrun" = "0" ] && git add "$docker_compose_yml" "${pyproject_toml}" "${version_file}" && git commit -m "Release v${next}."
[ "$verbose" = "1" ] && echo "Tagging Git HEAD with v${next}"
[ "$dryrun" = "0" ] && git tag "v${next}"