Skip to content
Open
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
76 changes: 22 additions & 54 deletions .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
@@ -1,67 +1,35 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"
name: CodeQL

on:
push:
branches: [ master ]
branches: ["master"]
pull_request:
# The branches below must be a subset of the branches above
branches: [ master ]
branches: ["master"]
schedule:
- cron: '32 12 * * 0'
- cron: "32 12 * * 0"

permissions:
contents: read
security-events: write

concurrency:
group: "codeql-${{ github.workflow }}-${{ github.ref }}"
cancel-in-progress: true

jobs:
analyze:
name: Analyze
name: Analyze Python
runs-on: ubuntu-latest

strategy:
fail-fast: false
matrix:
language: [ 'python' ]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
# Learn more:
# https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
timeout-minutes: 20

steps:
- name: Checkout repository
uses: actions/checkout@v2

# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# queries: ./path/to/local/query, your-org/your-repo/queries@main

# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v1

# ℹ️ Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl

# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
# and modify them (or add more) to build your code if your project
# uses a compiled language
- name: Checkout repository
uses: actions/checkout@v7

#- run: |
# make bootstrap
# make release
- name: Initialize CodeQL
uses: github/codeql-action/init@v4
with:
languages: python

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1
- name: Perform CodeQL analysis
uses: github/codeql-action/analyze@v4
62 changes: 47 additions & 15 deletions .github/workflows/jekyll-gh-pages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,47 +3,79 @@ name: Deploy Simiki to GitHub Pages
on:
push:
branches: ["master"]
pull_request:
branches: ["master"]
workflow_dispatch:

permissions:
contents: read
pages: write
id-token: write

concurrency:
group: "pages"
cancel-in-progress: false

jobs:
build:
timeout-minutes: 15
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v7
- name: Setup Python
uses: actions/setup-python@v5
uses: actions/setup-python@v6
with:
python-version: "3.11"
- name: Install Simiki
cache: pip
cache-dependency-path: requirements-build.txt
- name: Install pinned build dependencies
run: |
python -m pip install --upgrade pip
pip install simiki
python -m pip install --upgrade "pip==26.1.2" "setuptools==80.9.0" "wheel==0.45.1"
python -m pip install --no-deps --no-build-isolation "simiki==1.6.2.3"
python -m pip install --no-deps -r requirements-build.txt
- name: Build site
shell: bash
run: |
simiki g
set -euo pipefail
build_log="$(mktemp)"
simiki g 2>&1 | tee "$build_log"
if grep -Eq "pages failed|failed to generate" "$build_log"; then
echo "Simiki reported page-generation failures."
exit 1
fi
test -s output/index.html
touch output/.nojekyll
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
if: github.event_name != 'pull_request'
uses: actions/upload-pages-artifact@v5
with:
path: output

test:
timeout-minutes: 10
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v7
- name: Setup Python
uses: actions/setup-python@v6
with:
python-version: "3.11"
- name: Run deployment helper tests
run: |
python -m pip install --upgrade "pip==26.1.2" "pytest==8.4.2"
python -m pytest -q

deploy:
if: github.event_name != 'pull_request'
timeout-minutes: 10
permissions:
pages: write
id-token: write
concurrency:
group: "pages"
cancel-in-progress: false
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
needs: build
needs: [build, test]
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
uses: actions/deploy-pages@v5
27 changes: 0 additions & 27 deletions .travis.yml

This file was deleted.

18 changes: 12 additions & 6 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
FROM python:3.7-alpine
FROM python:3.11-alpine

ENV LANG=C.UTF-8
ENV PYTHONIOENCODING=utf-8
RUN pip install simiki -i https://pypi.tuna.tsinghua.edu.cn/simple
RUN apk add --no-cache gcc musl-dev python3-dev
RUN pip install --upgrade pytz tzlocal watchdog

WORKDIR /src

COPY requirements-build.txt /tmp/requirements-build.txt
RUN python -m pip install --no-cache-dir --upgrade "pip==26.1.2" "setuptools==80.9.0" "wheel==0.45.1" \
&& python -m pip install --no-cache-dir --no-deps --no-build-isolation "simiki==1.6.2.3" \
&& python -m pip install --no-cache-dir --no-deps -r /tmp/requirements-build.txt

COPY . /src

RUN simiki -V
RUN simiki g
RUN simiki -V \
&& simiki g \
&& test -s output/index.html \
&& touch output/.nojekyll

CMD ["simiki", "p", "-w", "--host", "0.0.0.0", "--port", "8000"]

Expand Down
6 changes: 3 additions & 3 deletions fabfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,8 @@ def deploy_ftp(deploy_configs):
rel_root = os.path.relpath(root, output_dir)
for fn in files:
store_fn = os.path.join(ftp_dir, rel_root, fn)
ftp.storbinary('STOR %s' % store_fn,
open(os.path.join(root, fn), 'rb'))
with open(os.path.join(root, fn), 'rb') as upload_file:
ftp.storbinary('STOR %s' % store_fn, upload_file)

ftp.close()

Expand Down Expand Up @@ -142,7 +142,7 @@ def deploy(type=None):
func_name = 'deploy_{0}'.format(deploy_type)
func = globals().get(func_name)
if not func:
do_exit('Warning: not supprt {0} deploy method'
do_exit('Warning: not support {0} deploy method'
.format(deploy_type))
func(deploy_item)
done = True
Expand Down
13 changes: 13 additions & 0 deletions requirements-build.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Simiki 1.6.2.3 pins dependencies from 2013-2019 that do not run reliably on
# current Python. The workflow installs Simiki itself with --no-deps, then uses
# this tested, reproducible compatibility set on Python 3.11+.
Markdown==3.8.2
Pygments==2.19.2
Jinja2==3.1.6
MarkupSafe==3.0.3
PyYAML==6.0.3
docopt==0.6.2
watchdog==6.0.0
pytz==2025.2
tzlocal==5.3.1
tzdata==2026.2
85 changes: 85 additions & 0 deletions tests/test_fabfile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import contextlib
import pathlib
import sys
import types

ROOT = pathlib.Path(__file__).resolve().parents[1]
sys.path.insert(0, str(ROOT))

fabric_module = types.ModuleType("fabric")
fabric_api = types.ModuleType("fabric.api")
fabric_colors = types.ModuleType("fabric.colors")
fabric_contrib = types.ModuleType("fabric.contrib")
fabric_contrib_project = types.ModuleType("fabric.contrib.project")
simiki_module = types.ModuleType("simiki")
simiki_config = types.ModuleType("simiki.config")
simiki_compat = types.ModuleType("simiki.compat")


@contextlib.contextmanager
def _settings(*args, **kwargs):
yield


def _task(func=None, *args, **kwargs):
if func is None:
return lambda inner: inner
return func


def _local(*args, **kwargs):
return None


fabric_api.env = types.SimpleNamespace()
fabric_api.local = _local
fabric_api.task = _task
fabric_api.settings = _settings
fabric_colors.blue = lambda message: message
fabric_colors.red = lambda message: message
fabric_contrib_project.rsync_project = lambda *args, **kwargs: None
simiki_config.parse_config = lambda *args, **kwargs: {}
simiki_compat.raw_input = lambda *args, **kwargs: ""

sys.modules["fabric"] = fabric_module
sys.modules["fabric.api"] = fabric_api
sys.modules["fabric.colors"] = fabric_colors
sys.modules["fabric.contrib"] = fabric_contrib
sys.modules["fabric.contrib.project"] = fabric_contrib_project
sys.modules["simiki"] = simiki_module
sys.modules["simiki.config"] = simiki_config
sys.modules["simiki.compat"] = simiki_compat

import fabfile


def test_get_rsync_configs_returns_rsync_entry(monkeypatch):
sample_configs = {
"deploy": [
{"type": "ftp", "host": "ftp.example.com"},
{"type": "rsync", "host": "rsync.example.com"},
{"type": "git", "remote": "origin"},
]
}

monkeypatch.setattr(fabfile, "configs", sample_configs)

assert fabfile.get_rsync_configs() == {
"type": "rsync",
"host": "rsync.example.com",
}


def test_deploy_does_not_mutate_config(monkeypatch):
sample_configs = {"deploy": [{"type": "git", "remote": "origin"}]}
received_config = {}

monkeypatch.setattr(fabfile, "configs", sample_configs)
monkeypatch.setattr(
fabfile, "deploy_git", lambda deploy_config: received_config.update(deploy_config)
)

fabfile.deploy()

assert sample_configs["deploy"][0]["type"] == "git"
assert received_config == {"type": "git", "remote": "origin"}
Loading