Compare commits

...

5 Commits

Author SHA1 Message Date
iratusmachina bda72d8c08 Merge pull request 'post/cicd-setup' (#2) from blog/cicd-setup into main
ci/woodpecker/push/build Pipeline was successful Details
Reviewed-on: #2
2023-08-14 04:58:07 +00:00
OLUWADAMILOLA OKUSANYA 6bee88469c Fixing a few typos
ci/woodpecker/push/build Pipeline was successful Details
ci/woodpecker/pr/build Pipeline was successful Details
2023-08-14 00:54:14 -04:00
OLUWADAMILOLA OKUSANYA deb859c999 Adding proer links
ci/woodpecker/push/build Pipeline was successful Details
2023-08-14 00:43:56 -04:00
OKUSANYA DAVID 569efbc660 Adding images
ci/woodpecker/push/build Pipeline was successful Details
2023-08-14 04:35:38 +00:00
OLUWADAMILOLA OKUSANYA c8561d6410 Adding new blog CICD Setup
ci/woodpecker/push/build Pipeline was successful Details
2023-08-14 00:18:20 -04:00
21 changed files with 569 additions and 6 deletions

View File

@ -17,6 +17,7 @@ ENV PATH="/opt/venv/bin:${PATH}" PYTHONDONTWRITEBYTECODE="1" PYTHONUNBUFFERED="1
# COPY --chown=python:python requirements.txt /home/python/docker-pelican/requirements.txt # COPY --chown=python:python requirements.txt /home/python/docker-pelican/requirements.txt
COPY requirements.txt . COPY requirements.txt .
# RUN /home/python/venv/bin/pip install --no-cache-dir --requirement /home/python/docker-pelican/requirements.txt # RUN /home/python/venv/bin/pip install --no-cache-dir --requirement /home/python/docker-pelican/requirements.txt
RUN pip install --no-cache-dir wheel
RUN pip install --no-cache-dir -r requirements.txt RUN pip install --no-cache-dir -r requirements.txt
EXPOSE 7070 EXPOSE 7070

View File

@ -10,8 +10,9 @@ This is the code for the my blog at iratusmachina.com. It is powered by
```sh ```sh
$ python3 -m venv venv $ python3 -m venv venv
$ source venv/bin/activate $ source venv/bin/activate
$ python3 -m pip install wheel
$ python3 -m pip install --no-cache-dir -r requirements.txt $ python3 -m pip install --no-cache-dir -r requirements.txt
# Comment out BINF in the pelicanconf.py # Comment out BIND in the pelicanconf.py
$ make serve $ make serve
``` ```

464
content/CICD_Setup.md Normal file
View File

@ -0,0 +1,464 @@
Title: CICD Setup
Date: 2023-07-01 15:25
Category: Devops
Tags: publishing
Slug: cicd
Authors: Okusanya David
Summary: About my cicd setup
### OUTLINE
- [Introduction](#deploy-cicd-introduction)
- [Install instructions](#deploy-cicd-install-instructions)
- [Testing Instructions](#deploy-cicd-testing-instructions)
- [Observations](#deploy-cicd-testing-observations)
### INTRODUCTION {#deploy-cicd-introduction}
CI/CD is a fixture of my job as a software engineer and I wanted to learn more about it. So I looked into self-hosting a git forge and a build server. My criteria , in order, was this:
- easy to adminster
- able to be left alone, that is, it does not need constant maintenance
- easy integration between the forge and build server
- simple UI
Looking the Awesome Self-hosted page on [Github](https://github.com/awesome-selfhosted/awesome-selfhosted), [Wikipedia](https://en.wikipedia.org/wiki/Forge_(software)), and on r/selfhosted, I settled on Gitea for the git forge because:
- it is similar to Github in feel
- it has [Gitea actions](https://docs.gitea.com/usage/actions/overview) which is based on Github actions. This makes easy for me to learn Github actions later on.
- It has integrations to Gitlab which is another git forge that I use.
As for the build server, I was torn between [Jenkins](https://www.jenkins.io/) (which I used at a previous job) and [Woodpecker CI](https://woodpecker-ci.org/). I went with Woodpecker CI because:
- It is "docker-based", which was very useful when I was trying it out. This means that each instance of a build is a workspace based on docker. This is similar to what most build systems (AWS, Azure, Github) do.
- It is very simple
- It has a native integration with Gitea.
- It is written in go which is the same as Gitea
Now, I noticed that. most examples that combine, both Gitea and Woodpecker CI, online use a docker-compose approach. I was weary of that path especially when interfacing with Nginx. Since they were both written in go and are single binaries (well, in the case of Woodpecker CI, three binaries), I figured that they should be able to run them using systemd instead of docker. This will help learn linux further and will also interface properly with the Nginx that is installed on the boxes where they would both live.
### INSTALL INSTRUCTIONS {#deploy-cicd-install-instructions}
I am using Debian, instead of Ubuntu as the OS for the boxes where the Gitea and Woodpecker CI would live. This is to avoid dealing with snaps. So the instructions to set this is as follows:
(1). Create a domain for each. Mine is woodpecker.iratusmachina.com for the Woodpecker CI and ci.iratusmachina.com for the Gitea instance. I use DigitalOCean to host all my projects so domain creation was easy. I just needed to add `A records` for both.
(2). Ssh into the Woodpecker box. Install `docker` by following the instructions in these links: [here](https://docs.docker.com/engine/install/debian/) and [here](https://docs.docker.com/engine/install/linux-postinstall/)
(3). Ssh into the Gitea Box. Download gitea from [here](https://dl.gitea.com/gitea/1.19.4/gitea-1.19.4-linux-amd64)
```sh
$ wget https://dl.gitea.com/gitea/1.19.4/gitea-1.19.4-linux-amd64
$ sudo mv gitea-1.19.4-linux-amd64 /usr/local/bin/gitea
$ sudo chmod +x /usr/local/bin/gitea
```
(4). Ssh into the Woodpecker box. Download the woodpecker binaries from [here](https://github.com/woodpecker-ci/woodpecker/releases/tag/v0.15.11).
```sh
$ wget https://github.com/woodpecker-ci/woodpecker/releases/download/v0.15.11/woodpecker-agent_0.15.11_amd64.deb
$ wget https://github.com/woodpecker-ci/woodpecker/releases/download/v0.15.11/woodpecker-cli_0.15.11_amd64.deb
$ wget https://github.com/woodpecker-ci/woodpecker/releases/download/v0.15.11/woodpecker-server_0.15.11_amd64.deb
$ sudo dpkg -i ./woodpecker-*
```
(5). Create users to allow each application to manage their own data.
```sh
# In the Gitea box
$ sudo apt install git
$ sudo adduser --system --shell /bin/bash --gecos 'Git Version Control' --group --disabled-password --home /home/git git
# In the Woodpecker Box
$ sudo adduser --system --shell /bin/bash --gecos 'Woodpecker CI' --group --disabled-password --home /home/<woodpecker-username> <woodpecker-username>
$ sudo usermod -aG docker <woodpecker-username>
```
(6). Ssh into the Gitea Box.Create directories for gitea based on this [link](https://docs.gitea.com/installation/install-from-binary#create-required-directory-structure)
```sh
$ sudo mkdir -p /var/lib/<gitea-username>/{custom,data,log}
$ sudo chown -R git:git /var/lib/<gitea-username>/
$ sudo chmod -R 750 /var/lib/<gitea-username>/
$ sudo mkdir /etc/<gitea-username>
$ sudo chown root:git /etc/<gitea-username>
$ sudo chmod 770 /etc/<gitea-username>
```
(7). Ssh into the Woodpecker box and create directories for the woodpecker user.
```sh
$ sudo mkdir -p /var/lib/<woodpecker-username>
$ sudo chown -R <woodpecker-username>:<woodpecker-username> /var/lib/<woodpecker-username>
$ sudo chmod -R 750 /var/lib/<woodpecker-username>/
$ sudo touch /etc/woodpecker.conf
$ sudo chmod 770 /etc/woodpecker.conf
```
(8). Set up database with [this guide](https://docs.gitea.com/installation/database-prep)
```sh
# In the both boxes
$ sudo apt-get install postgresql postgresql-contrib
$ sudo -u postgres psql
# In the Gitea Box
postgres=# CREATE ROLE <gitea-username> WITH LOGIN PASSWORD '<gitea-password>';
postgres=# CREATE DATABASE <gitea-database-name> WITH OWNER <gitea-username> TEMPLATE template0 ENCODING UTF8 LC_COLLATE 'en_US.UTF-8' LC_CTYPE 'en_US.UTF-8';
# In the Woodpecker Box
postgres=# CREATE ROLE <woodpecker-username> WITH LOGIN PASSWORD '<woodpecker-database-name>';
postgres=# CREATE DATABASE <woodpecker-database-name> WITH OWNER <woodpecker-username> TEMPLATE template0 ENCODING UTF8 LC_COLLATE 'en_US.UTF-8' LC_CTYPE 'en_US.UTF-8';
# In both boxes
postgres=# exit;
```
Add the following lines to the your hba_conf
```sh
# In both boxes
$ sudo -u postgres psql
postgres=# SHOW hba_file;
hba_file
-------------------------------------
/etc/postgresql/14/main/pg_hba.conf
(1 row)
postgres=# exit;
# In Gitea Box
$ sudo nano -c /etc/postgresql/14/main/pg_hba.conf
# Database administrative login by Unix domain socket
local <gitea-database-name> <gitea-username> scram-sha-256
# In Woodpecker Box
$ sudo nano -c /etc/postgresql/14/main/pg_hba.conf
# Database administrative login by Unix domain socket
local <woodpecker-database-name> <woodpecker-username> scram-sha-256
```
(9). Ssh into the Gitea box. Follow
[this guide](https://docs.gitea.com/installation/linux-service) to set up the gitea as a systemd service
```sh
$ sudo wget https://raw.githubusercontent.com/go-gitea/gitea/main/contrib/systemd/gitea.service -P /etc/systemd/system/
$ sudo nano -c /etc/systemd/system/gitea.service // Uncomment all the postgresql stuff
```
(10). Start the gitea service with the command `sudo systemctl start gitea`, Do not worry if you get a failure message like this
```sh
Job for gitea.service failed because a timeout was exceeded.
See "systemctl status gitea.service" and "journalctl -xeu gitea.service" for details.
```
(11). The Gitea server runs on port 3000. Open `http://localhost:3000` to configure database settings and create your first admin user for Gitea.
(12). Create the nginx config for the Gitea service.
```sh
$ sudo nano -c /etc/nginx/sites-available/gitea.conf
server {
listen 80;
server_name git.YOUR_DOMAIN;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Connection "";
chunked_transfer_encoding off;
proxy_buffering off;
}
}
```
(13). Edit the `/etc/gitea/app.ini` to resemble the below:
```sh
$ sudo nano -c /etc/gitea/app.ini
....
[server]
SSH_DOMAIN = git.YOUR_DOMAIN
DOMAIN = git.YOUR_DOMAIN
HTTP_PORT = 3000
ROOT_URL = http://git.YOUR_DOMAIN/
---
```
(14). Enable the domain and restart the box.
```sh
$ sudo ln -s /etc/nginx/sites-available/gitea.conf /etc/nginx/sites-enabled/
$ sudo reboot
```
(15). Relogin and restart the gitea service.
(16). Navigate to `http://git.YOUR_DOMAIN/admin/applications` to configure to the Oauth application as shown below:
![oauth_gitea]({static}/images/cicd-setup/oauth_gitea.png)
Replace the hightlighted line in the picture above with `http://build.YOUR_DOMAIN/authorize`.Save the Client Id and Client Secret.
(17). Ssh into the Woodpecker box. Create the nginx config for the Woodpecker CI service.
```sh
$ sudo nano -c /etc/nginx/sites-available/woodpecker.conf
server {
listen 80;
server_name build.YOUR_DOMAIN;
location / {
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $http_host;
proxy_pass http://127.0.0.1:8000;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_buffering off;
chunked_transfer_encoding off;
}
}
```
(18). Enable the domain and restart the box.
```sh
$ sudo ln -s /etc/nginx/sites-available/woodpecker.conf /etc/nginx/sites-enabled/
$ sudo reboot
```
(19). Ssh into Woodpecker Box. Open a file `/etc/systemd/system/woodpecker.service` and paste the following:
```sh
$ sudo nano -c /etc/systemd/system/woodpecker.service
[Unit]
Description=Woodpecker
Documentation=https://woodpecker-ci.org/docs/intro
Requires=network-online.target
After=network-online.target
[Service]
User=woodpecker
Group=woodpecker
EnvironmentFile=/etc/woodpecker.conf
ExecStart=/usr/local/bin/woodpecker-server
RestartSec=5
Restart=on-failure
SyslogIdentifier=woodpecker-server
WorkingDirectory=/var/lib/woodpecker
[Install]
WantedBy=multi-user.target
```
(20). Open another file and pass the following:
```sh
WOODPECKER_OPEN=true
WOODPECKER_HOST=http://build.YOUR_DOMAIN
WOODPECKER_GITEA=true
WOODPECKER_GITEA_URL=http://git.YOUR_DOMAIN
WOODPECKER_GITEA_CLIENT=<Client ID from 16>
WOODPECKER_GITEA_SECRET=<Client Secret from 16>
WOODPECKER_GITEA_SKIP_VERIFY=true
WOODPECKER_DATABASE_DRIVER=postgres
WOODPECKER_LOG_LEVEL=info
WOODPECKER_DATABASE_DATASOURCE=postgres://<woodpecker-username>:<woodpecker-db-password>@127.0.0.1:5432/<woodpecker-db-username>?sslmode=disable
GODEBUG=netdns=go
```
(21). Start the woodpecker service and navigate to `http://build.YOUR_DOMAIN`. Click the login button. It will take to a page where you can authorize woodpecker to receive webhooks.
(22). Stop the woodpecker service
```sh
$ sudo systemctl stop woodpecker
```
(23). Generate a long random string to be used a secret for the woodpecker-agent to communicate with the woodpecker-server with this command
```sh
$ openssl rand -hex 32`
```
(24). Add that secret from step (23) to the /etc/woodpecker.conf as follows:
```sh
...
WOODPECKER_AGENT_SECRET=GENERATED_SECRET
```
(25). Open file /etc/systemd/system/woodpecker-agent.service and add this
```sh
$ sudo nano -c /etc/systemd/system/woodpecker-agent.service
[Unit]
Description=Woodpecker
Documentation=https://woodpecker-ci.org/docs/intro
Requires=network-online.target
After=network-online.target
[Service]
User=woodpecker
Group=woodpecker
EnvironmentFile=/etc/woodpecker-agent.conf
ExecStart=/usr/local/bin/woodpecker-agent
RestartSec=5
Restart=on-failure
SyslogIdentifier=woodpecker-agent
WorkingDirectory=/var/lib/woodpecker
[Install]
WantedBy=multi-user.target
```
(26). Open file /etc/woodpecker-agent.conf and add the same secret from step (23).
```sh
WOODPECKER_SERVER=localhost:9000
WOODPECKER_BACKEND=docker
WOODPECKER_AGENT_SECRET=GENERATED_SECRET
```
(27). Restart woodpecker-server
```sh
$ sudo systemctl start woodpecker`
```
(28). Start woodpecker-agent with
```sh
$ sudo systemctl start woodpecker-agent
```
(29). Reboot the two boxes.
(30). To add https, install [certbot](https://certbot.eff.org/) and select all default choices
```sh
# In both boxes
$ sudo apt-get install certbot python3-certbot-nginx
$ sudo certbot --nginx
$ sudo systemctl restart nginx
```
(31). Modify the `/etc/gitea/app.ini` to add https
```sh
$ sudo nano -c /etc/gitea/app.ini
....
[server]
SSH_DOMAIN = git.YOUR_DOMAIN
DOMAIN = git.YOUR_DOMAIN
HTTP_PORT = 3000
ROOT_URL = https://git.YOUR_DOMAIN/
```
(32). Modify the `/etc/woodpecker.conf` to add the https urls
```sh
WOODPECKER_HOST=https://build.YOUR_DOMAIN
...
WOODPECKER_GITEA_URL=https://git.YOUR_DOMAIN
...
```
(33). Enable all the services to start on boot
```sh
# In the Gitea box
$ sudo systemctl enable gitea
# In the Woodpecker box
$ sudo systemctl enable woodpecker
$ sudo systemctl enable woodpecker-agent
```
### TESTING INSTRUCTIONS {#deploy-cicd-testing-instructions}
For testing this setup, follow these instructions:
(a) Go to the Gitea UI. Select "+". There should be a dropdown with some options. Select "New Repository"
![select_new_repository]({static}/images/cicd-setup/select_new_repository.png)
(b) Fill out the form and select the checkbox "Initialize Repository". Click the button "Create Repository".
![new_repo_creation]({static}/images/cicd-setup/new_repo_creation.png)
![init_repository]({static}/images/cicd-setup/init_repository.png)
![newly_created_repo]({static}/images/cicd-setup/newly_created_repo.png)
(c) Go back to the Woodpecker CI UI. And click "Add repository".
![add_repository]({static}/images/cicd-setup/add_repository.png)
(d) Then click "Reload Repositories" and your repository should appear.
![reload_repositories]({static}/images/cicd-setup/reload_repositories.png)
(e) Then click "Enable".
![enable_repositories]({static}/images/cicd-setup/enable_repositories.png)
![enable_repositories_v2]({static}/images/cicd-setup/enable_repositories_v2.png)
(f) Head back to the Gitea UI in (b) and click "New File". Add a sample pipeline.yml from this [link](https://woodpecker-ci.org/docs/usage/pipeline-syntax)
```yml
pipeline:
run-one:
image: busybox
group: first
commands:
- echo "first run"
run-two:
image: busybox
group: first
commands:
- echo "second run"
run-three:
image: ubuntu
commands:
- echo hi
when:
branch:
include: [ master, release/* ]
exclude: [ test/1.0.0, test/1.1.* ]
```
![new_file]({static}/images/cicd-setup/new_file.png)
(g) Commit the file to the master branch. Head to the Woodpecker CI UI and you should see that your build should have completed.
![commit_changes]({static}/images/cicd-setup/commit_changes.png)
![successful_run]({static}/images/cicd-setup/successful_run.png)
### OBSERVATIONS {#deploy-cicd-testing-observations}
(a) I had initially wanted to run both of them, the Gitea instance and Woodpecker CI on the same host. I tried running both to them locally testing with localhost but I never went past step 21 of the installation guide. I kept getting errors like below and is referenced below [this](https://github.com/woodpecker-ci/woodpecker/issues/1485)
```json
{"level":"error","time":"2022-12-xxxx","message":"cannot authenticate user. Post \"http://localhost.lan/login/oauth/access_token\": dial tcp 127.0.0.1:80: connect: connection refused"}
```
This error magically did not show up when running in docker. Since I was not running in docker for my production setup, I had to run both on their own host
(b) So when you go to the Gitea UI fron the installation steps above, you would see this:
![gitea_instance_homepage]({static}/images/cicd-setup/gitea_instance_homepage.png)
So based on this, anyone can register for an account at your service. The side effect is that any new account has automatic admin priviledges upon creation, which is described [here](https://github.com/go-gitea/gitea/issues/10260). If you want to disable signups, you would set this attribute in the `etc/gitea/app.ini` according to this [link](https://docs.gitea.com/next/administration/config-cheat-sheet#service-service)
```sh
...
[service]
...
DISABLE_REGISTRATION = true
...
```

View File

@ -1,7 +1,7 @@
Title: First post Title: First post
Date: 2020-08-09 14:52 Date: 2020-08-09 14:52
Category: Python Category: Python
Tags: puiblishing Tags: publishing
Slug: my first post Slug: my first post
Authors: Okusanya David Authors: Okusanya David
Summary: About my first post Summary: About my first post

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

View File

@ -1,6 +1,8 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # # -*- coding: utf-8 -*- #
from __future__ import unicode_literals from __future__ import unicode_literals
# import markdown
# markdown.Markdown(extensions=['pymdownx.superfences'])
AUTHOR = 'Okusanya David' AUTHOR = 'Okusanya David'
SITENAME = 'Ad meliora' SITENAME = 'Ad meliora'
@ -48,3 +50,16 @@ PORT = 7070
# Needed to serve the output from a Docker container # Needed to serve the output from a Docker container
BIND = '0.0.0.0' BIND = '0.0.0.0'
# Using the SuperFences https://facelessuser.github.io/pymdown-extensions/extensions/superfences/#limitations
# MARKDOWN = {
# 'extension_configs': {
# 'pymdownx.superfences': {},
# 'markdown.extensions.codehilite': {
# 'css_class': 'highlight'
# },
# 'markdown.extensions.extra': {},
# 'markdown.extensions.meta': {},
# },
# 'output_format': 'html5',
# }

View File

@ -1,4 +1,6 @@
blinker blinker
build
click
docutils docutils
feedgenerator feedgenerator
Jinja2 Jinja2
@ -6,13 +8,17 @@ Markdown
markdown-it-py markdown-it-py
MarkupSafe MarkupSafe
mdurl mdurl
packaging
pelican pelican
Pygments Pygments
pymdown-extensions
pyproject_hooks
python-dateutil python-dateutil
pytz pytz
PyYAML
rich rich
six six
smartypants smartypants
tomli
typogrify typogrify
Unidecode Unidecode

View File

@ -2,7 +2,7 @@
# This file is autogenerated by pip-compile with Python 3.10 # This file is autogenerated by pip-compile with Python 3.10
# by the following command: # by the following command:
# #
# pip-compile --generate-hashes --output-file=requirements.txt # pip-compile --generate-hashes requirements.in
# #
blinker==1.6.2 \ blinker==1.6.2 \
--hash=sha256:4afd3de66ef3a9f8067559fb7a1cbe555c17dcbe15971b05d1b625c3e7abe213 \ --hash=sha256:4afd3de66ef3a9f8067559fb7a1cbe555c17dcbe15971b05d1b625c3e7abe213 \
@ -10,6 +10,14 @@ blinker==1.6.2 \
# via # via
# -r requirements.in # -r requirements.in
# pelican # pelican
build==0.10.0 \
--hash=sha256:af266720050a66c893a6096a2f410989eeac74ff9a68ba194b3f6473e8e26171 \
--hash=sha256:d5b71264afdb5951d6704482aac78de887c80691c52b88a9ad195983ca2c9269
# via -r requirements.in
click==8.1.6 \
--hash=sha256:48ee849951919527a045bfe3bf7baa8a959c423134e1a5b98c05c20ba75a1cbd \
--hash=sha256:fa244bb30b3b5ee2cae3da8f55c9e5e0c0e86093306301fb418eb9dc40fbded5
# via -r requirements.in
docutils==0.20.1 \ docutils==0.20.1 \
--hash=sha256:96f387a2c5562db4476f09f13bbab2192e764cac08ebbf3a34a95d9b1e4a59d6 \ --hash=sha256:96f387a2c5562db4476f09f13bbab2192e764cac08ebbf3a34a95d9b1e4a59d6 \
--hash=sha256:f08a4e276c3a1583a86dce3e34aba3fe04d02bba2dd51ed16106244e8a923e3b --hash=sha256:f08a4e276c3a1583a86dce3e34aba3fe04d02bba2dd51ed16106244e8a923e3b
@ -31,7 +39,9 @@ jinja2==3.1.2 \
markdown==3.4.3 \ markdown==3.4.3 \
--hash=sha256:065fd4df22da73a625f14890dd77eb8040edcbd68794bcd35943be14490608b2 \ --hash=sha256:065fd4df22da73a625f14890dd77eb8040edcbd68794bcd35943be14490608b2 \
--hash=sha256:8bf101198e004dc93e84a12a7395e31aac6a9c9942848ae1d99b9d72cf9b3520 --hash=sha256:8bf101198e004dc93e84a12a7395e31aac6a9c9942848ae1d99b9d72cf9b3520
# via -r requirements.in # via
# -r requirements.in
# pymdown-extensions
markdown-it-py==3.0.0 \ markdown-it-py==3.0.0 \
--hash=sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1 \ --hash=sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1 \
--hash=sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb --hash=sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb
@ -98,6 +108,12 @@ mdurl==0.1.2 \
# via # via
# -r requirements.in # -r requirements.in
# markdown-it-py # markdown-it-py
packaging==23.1 \
--hash=sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61 \
--hash=sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f
# via
# -r requirements.in
# build
pelican==4.8.0 \ pelican==4.8.0 \
--hash=sha256:6445c00cff2142a30592a2de046e5647b84a36c5a0cfafc0eba75abbabb2b4b1 \ --hash=sha256:6445c00cff2142a30592a2de046e5647b84a36c5a0cfafc0eba75abbabb2b4b1 \
--hash=sha256:c80a81930f57f9b1a11c9ab5894ce1465dcda2028c9e4e3993cf9cbf2061a57d --hash=sha256:c80a81930f57f9b1a11c9ab5894ce1465dcda2028c9e4e3993cf9cbf2061a57d
@ -109,6 +125,16 @@ pygments==2.15.1 \
# -r requirements.in # -r requirements.in
# pelican # pelican
# rich # rich
pymdown-extensions==10.1 \
--hash=sha256:508009b211373058debb8247e168de4cbcb91b1bff7b5e961b2c3e864e00b195 \
--hash=sha256:ef25dbbae530e8f67575d222b75ff0649b1e841e22c2ae9a20bad9472c2207dc
# via -r requirements.in
pyproject-hooks==1.0.0 \
--hash=sha256:283c11acd6b928d2f6a7c73fa0d01cb2bdc5f07c57a2eeb6e83d5e56b97976f8 \
--hash=sha256:f271b298b97f5955d53fb12b72c1fb1948c22c1a6b70b315c54cedaca0264ef5
# via
# -r requirements.in
# build
python-dateutil==2.8.2 \ python-dateutil==2.8.2 \
--hash=sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86 \ --hash=sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86 \
--hash=sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9 --hash=sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9
@ -122,6 +148,50 @@ pytz==2023.3 \
# -r requirements.in # -r requirements.in
# feedgenerator # feedgenerator
# pelican # pelican
pyyaml==6.0.1 \
--hash=sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc \
--hash=sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741 \
--hash=sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206 \
--hash=sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27 \
--hash=sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595 \
--hash=sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62 \
--hash=sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98 \
--hash=sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696 \
--hash=sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d \
--hash=sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867 \
--hash=sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47 \
--hash=sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486 \
--hash=sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6 \
--hash=sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3 \
--hash=sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007 \
--hash=sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938 \
--hash=sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c \
--hash=sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735 \
--hash=sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d \
--hash=sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba \
--hash=sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8 \
--hash=sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5 \
--hash=sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd \
--hash=sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3 \
--hash=sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0 \
--hash=sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515 \
--hash=sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c \
--hash=sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c \
--hash=sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924 \
--hash=sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34 \
--hash=sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43 \
--hash=sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859 \
--hash=sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673 \
--hash=sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a \
--hash=sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab \
--hash=sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa \
--hash=sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c \
--hash=sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585 \
--hash=sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d \
--hash=sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f
# via
# -r requirements.in
# pymdown-extensions
rich==13.4.2 \ rich==13.4.2 \
--hash=sha256:8f87bc7ee54675732fa66a05ebfe489e27264caeeff3728c945d25971b6485ec \ --hash=sha256:8f87bc7ee54675732fa66a05ebfe489e27264caeeff3728c945d25971b6485ec \
--hash=sha256:d653d6bccede5844304c605d5aac802c7cf9621efd700b46c7ec2b51ea914898 --hash=sha256:d653d6bccede5844304c605d5aac802c7cf9621efd700b46c7ec2b51ea914898
@ -139,6 +209,13 @@ smartypants==2.0.1 \
# via # via
# -r requirements.in # -r requirements.in
# typogrify # typogrify
tomli==2.0.1 \
--hash=sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc \
--hash=sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f
# via
# -r requirements.in
# build
# pyproject-hooks
typogrify==2.0.7 \ typogrify==2.0.7 \
--hash=sha256:8be4668cda434163ce229d87ca273a11922cb1614cb359970b7dc96eed13cb38 --hash=sha256:8be4668cda434163ce229d87ca273a11922cb1614cb359970b7dc96eed13cb38
# via -r requirements.in # via -r requirements.in

View File

@ -333,7 +333,6 @@ code {
padding-top: 2px; padding-top: 2px;
} }
.highlight code { .highlight code {
color: #93a1a1; color: #93a1a1;
} }