Compare commits
8 Commits
2894cf222b
...
v0.2.1
| Author | SHA1 | Date | |
|---|---|---|---|
| a90519807c | |||
| 4cd85e3515 | |||
| 9531730283 | |||
| 66ca05692b | |||
| 13ce2a5b4f | |||
| 5a6f278d8a | |||
| 4b55661aa4 | |||
| 08d12feaa9 |
@@ -0,0 +1,20 @@
|
|||||||
|
.git
|
||||||
|
.github
|
||||||
|
.review-sandboxes
|
||||||
|
.claude
|
||||||
|
.agents
|
||||||
|
.DS_Store
|
||||||
|
.venv
|
||||||
|
venv
|
||||||
|
__pycache__
|
||||||
|
*.py[cod]
|
||||||
|
archive
|
||||||
|
docs
|
||||||
|
tmp
|
||||||
|
bin
|
||||||
|
dist
|
||||||
|
node_modules
|
||||||
|
web/static/dist
|
||||||
|
.air.log
|
||||||
|
*.md
|
||||||
|
!README.md
|
||||||
@@ -0,0 +1,108 @@
|
|||||||
|
name: build
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
pull_request:
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
TAILWIND_VERSION: v3.4.17
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- uses: actions/setup-go@v5
|
||||||
|
with:
|
||||||
|
go-version-file: go.mod
|
||||||
|
cache: true
|
||||||
|
|
||||||
|
- name: Install templ
|
||||||
|
run: go install github.com/a-h/templ/cmd/templ@v0.3.1001
|
||||||
|
|
||||||
|
- name: Install tailwindcss standalone
|
||||||
|
run: |
|
||||||
|
curl -fsSL -o /usr/local/bin/tailwindcss \
|
||||||
|
"https://github.com/tailwindlabs/tailwindcss/releases/download/${TAILWIND_VERSION}/tailwindcss-linux-x64"
|
||||||
|
chmod +x /usr/local/bin/tailwindcss
|
||||||
|
|
||||||
|
- name: Build assets
|
||||||
|
run: |
|
||||||
|
mkdir -p web/static/dist
|
||||||
|
templ generate ./...
|
||||||
|
tailwindcss -c tailwind.config.js -i web/static/src/app.css -o web/static/dist/app.css --minify
|
||||||
|
|
||||||
|
- name: Vet
|
||||||
|
run: go vet ./...
|
||||||
|
|
||||||
|
- name: Test
|
||||||
|
run: go test -race ./...
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: |
|
||||||
|
mkdir -p bin
|
||||||
|
CGO_ENABLED=0 go build -trimpath \
|
||||||
|
-ldflags="-s -w -X github.com/fserg/md-to-html/internal/version.Version=$(cat VERSION)" \
|
||||||
|
-o bin/md-to-html ./cmd/md-to-html
|
||||||
|
|
||||||
|
cross-compile:
|
||||||
|
needs: test
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
TAILWIND_VERSION: v3.4.17
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- goos: linux
|
||||||
|
goarch: amd64
|
||||||
|
- goos: linux
|
||||||
|
goarch: arm64
|
||||||
|
- goos: darwin
|
||||||
|
goarch: arm64
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- uses: actions/setup-go@v5
|
||||||
|
with:
|
||||||
|
go-version-file: go.mod
|
||||||
|
|
||||||
|
- name: Install templ
|
||||||
|
run: go install github.com/a-h/templ/cmd/templ@v0.3.1001
|
||||||
|
|
||||||
|
- name: Install tailwindcss standalone
|
||||||
|
run: |
|
||||||
|
curl -fsSL -o /usr/local/bin/tailwindcss \
|
||||||
|
"https://github.com/tailwindlabs/tailwindcss/releases/download/${TAILWIND_VERSION}/tailwindcss-linux-x64"
|
||||||
|
chmod +x /usr/local/bin/tailwindcss
|
||||||
|
|
||||||
|
- name: Build assets
|
||||||
|
run: |
|
||||||
|
mkdir -p web/static/dist
|
||||||
|
templ generate ./...
|
||||||
|
tailwindcss -c tailwind.config.js -i web/static/src/app.css -o web/static/dist/app.css --minify
|
||||||
|
|
||||||
|
- name: Cross-compile
|
||||||
|
env:
|
||||||
|
GOOS: ${{ matrix.goos }}
|
||||||
|
GOARCH: ${{ matrix.goarch }}
|
||||||
|
CGO_ENABLED: "0"
|
||||||
|
run: |
|
||||||
|
mkdir -p bin
|
||||||
|
go build -trimpath \
|
||||||
|
-ldflags="-s -w -X github.com/fserg/md-to-html/internal/version.Version=$(cat VERSION)" \
|
||||||
|
-o "bin/md-to-html-${GOOS}-${GOARCH}" \
|
||||||
|
./cmd/md-to-html
|
||||||
|
|
||||||
|
- uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: md-to-html-${{ matrix.goos }}-${{ matrix.goarch }}
|
||||||
|
path: bin/md-to-html-${{ matrix.goos }}-${{ matrix.goarch }}
|
||||||
|
retention-days: 7
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
name: release
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- "v*"
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
packages: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
release:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
TAILWIND_VERSION: v3.4.17
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- uses: actions/setup-go@v5
|
||||||
|
with:
|
||||||
|
go-version-file: go.mod
|
||||||
|
|
||||||
|
- name: Install templ
|
||||||
|
run: go install github.com/a-h/templ/cmd/templ@v0.3.1001
|
||||||
|
|
||||||
|
- name: Install tailwindcss standalone
|
||||||
|
run: |
|
||||||
|
curl -fsSL -o /usr/local/bin/tailwindcss \
|
||||||
|
"https://github.com/tailwindlabs/tailwindcss/releases/download/${TAILWIND_VERSION}/tailwindcss-linux-x64"
|
||||||
|
chmod +x /usr/local/bin/tailwindcss
|
||||||
|
|
||||||
|
- name: Build assets
|
||||||
|
run: |
|
||||||
|
mkdir -p web/static/dist
|
||||||
|
templ generate ./...
|
||||||
|
tailwindcss -c tailwind.config.js -i web/static/src/app.css -o web/static/dist/app.css --minify
|
||||||
|
|
||||||
|
- name: Cross-compile binaries
|
||||||
|
run: |
|
||||||
|
mkdir -p dist
|
||||||
|
for target in "linux amd64" "linux arm64" "darwin arm64"; do
|
||||||
|
set -- $target
|
||||||
|
GOOS=$1 GOARCH=$2 CGO_ENABLED=0 go build -trimpath \
|
||||||
|
-ldflags="-s -w -X github.com/fserg/md-to-html/internal/version.Version=$(cat VERSION)" \
|
||||||
|
-o "dist/md-to-html-${1}-${2}" \
|
||||||
|
./cmd/md-to-html
|
||||||
|
done
|
||||||
|
|
||||||
|
- name: Log in to GHCR
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
registry: ghcr.io
|
||||||
|
username: ${{ github.actor }}
|
||||||
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Compute image name
|
||||||
|
id: image
|
||||||
|
run: |
|
||||||
|
repo_lower=$(echo "${GITHUB_REPOSITORY}" | tr '[:upper:]' '[:lower:]')
|
||||||
|
echo "name=ghcr.io/${repo_lower}" >> "${GITHUB_OUTPUT}"
|
||||||
|
|
||||||
|
- uses: docker/setup-qemu-action@v3
|
||||||
|
|
||||||
|
- uses: docker/setup-buildx-action@v3
|
||||||
|
|
||||||
|
- name: Build and push Docker image
|
||||||
|
uses: docker/build-push-action@v5
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
push: true
|
||||||
|
platforms: linux/amd64,linux/arm64
|
||||||
|
tags: |
|
||||||
|
${{ steps.image.outputs.name }}:${{ github.ref_name }}
|
||||||
|
${{ steps.image.outputs.name }}:latest
|
||||||
|
|
||||||
|
- name: Create GitHub Release
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
run: |
|
||||||
|
gh release create "${{ github.ref_name }}" \
|
||||||
|
--title "${{ github.ref_name }}" \
|
||||||
|
--notes-file CHANGELOG.md \
|
||||||
|
dist/*
|
||||||
@@ -4,6 +4,34 @@ All notable changes to this project will be documented in this file.
|
|||||||
|
|
||||||
The format is based on Keep a Changelog, and the project uses Semantic Versioning.
|
The format is based on Keep a Changelog, and the project uses Semantic Versioning.
|
||||||
|
|
||||||
|
## [0.2.1] - 2026-04-18
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- GitHub release workflow now lowercases the GHCR image name before publishing, which fixes releases for repositories with uppercase owner names.
|
||||||
|
|
||||||
|
## [0.2.0] - 2026-04-18
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- **BREAKING**: project fully rewritten in Go (goldmark + templUI); Python implementation moved to `archive/`.
|
||||||
|
- **BREAKING**: heading anchors now use ASCII transliteration (`## Установка` → `id="ustanovka"`).
|
||||||
|
- **BREAKING**: heading HTML markup simplified; `<div class="markdown-heading">` is no longer emitted.
|
||||||
|
- Removed the GitHub Markdown API dependency; conversion now works fully offline.
|
||||||
|
- Replaced the two-process runtime (uvicorn + Streamlit) with a single binary.
|
||||||
|
- Preview and download links are now one-shot, UUID-backed, and expire after one hour.
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Syntax highlighting via chroma with inline styles for self-contained HTML output.
|
||||||
|
- Footnote support in addition to baseline GFM features.
|
||||||
|
- Cross-platform release binaries for `linux/amd64`, `linux/arm64`, and `darwin/arm64`.
|
||||||
|
|
||||||
|
### Removed
|
||||||
|
|
||||||
|
- `READY_CHECK_GITHUB` environment variable.
|
||||||
|
- Streamlit UI on dedicated port `:8501`.
|
||||||
|
|
||||||
## [0.1.2] - 2026-04-18
|
## [0.1.2] - 2026-04-18
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|||||||
+62
@@ -0,0 +1,62 @@
|
|||||||
|
# syntax=docker/dockerfile:1.7
|
||||||
|
|
||||||
|
FROM debian:bookworm-slim AS tailwind
|
||||||
|
|
||||||
|
RUN apt-get update \
|
||||||
|
&& apt-get install -y --no-install-recommends ca-certificates curl \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
WORKDIR /src
|
||||||
|
|
||||||
|
ARG TARGETARCH
|
||||||
|
ARG TAILWIND_VERSION=v3.4.17
|
||||||
|
|
||||||
|
RUN case "$TARGETARCH" in \
|
||||||
|
amd64) tailwind_arch='x64' ;; \
|
||||||
|
arm64) tailwind_arch='arm64' ;; \
|
||||||
|
*) echo "unsupported TARGETARCH: $TARGETARCH" >&2; exit 1 ;; \
|
||||||
|
esac \
|
||||||
|
&& curl -fsSL -o /usr/local/bin/tailwindcss \
|
||||||
|
"https://github.com/tailwindlabs/tailwindcss/releases/download/${TAILWIND_VERSION}/tailwindcss-linux-${tailwind_arch}" \
|
||||||
|
&& chmod +x /usr/local/bin/tailwindcss
|
||||||
|
|
||||||
|
COPY tailwind.config.js ./
|
||||||
|
COPY web/ ./web/
|
||||||
|
COPY internal/ui/ ./internal/ui/
|
||||||
|
|
||||||
|
RUN mkdir -p web/static/dist \
|
||||||
|
&& tailwindcss \
|
||||||
|
-c tailwind.config.js \
|
||||||
|
-i web/static/src/app.css \
|
||||||
|
-o web/static/dist/app.css \
|
||||||
|
--minify
|
||||||
|
|
||||||
|
FROM golang:1.24-alpine AS build
|
||||||
|
|
||||||
|
WORKDIR /src
|
||||||
|
|
||||||
|
RUN apk add --no-cache ca-certificates git
|
||||||
|
RUN go install github.com/a-h/templ/cmd/templ@v0.3.1001
|
||||||
|
|
||||||
|
COPY go.mod go.sum ./
|
||||||
|
RUN go mod download
|
||||||
|
|
||||||
|
COPY . .
|
||||||
|
COPY --from=tailwind /src/web/static/dist/app.css ./web/static/dist/app.css
|
||||||
|
|
||||||
|
RUN templ generate ./... \
|
||||||
|
&& CGO_ENABLED=0 GOOS=linux go build \
|
||||||
|
-trimpath \
|
||||||
|
-ldflags="-s -w -X github.com/fserg/md-to-html/internal/version.Version=$(cat VERSION)" \
|
||||||
|
-o /out/md-to-html \
|
||||||
|
./cmd/md-to-html
|
||||||
|
|
||||||
|
FROM gcr.io/distroless/static-debian12:nonroot
|
||||||
|
|
||||||
|
COPY --from=build /out/md-to-html /md-to-html
|
||||||
|
|
||||||
|
EXPOSE 8080
|
||||||
|
|
||||||
|
USER nonroot
|
||||||
|
|
||||||
|
ENTRYPOINT ["/md-to-html", "serve"]
|
||||||
@@ -1,81 +1,90 @@
|
|||||||
# md-to-html
|
# md-to-html
|
||||||
|
|
||||||
Сервис конвертации Markdown в самодостаточный HTML (через GitHub API).
|
Сервис конвертации Markdown в самодостаточный HTML. Полностью офлайн, без обращений к внешним API.
|
||||||
|
|
||||||
Текущая версия: `0.1.2`
|
Текущая версия: `0.2.1` (Go + goldmark + templUI)
|
||||||
|
|
||||||
Часто нужен адекватно (минималистично) выглядящий HTML из Markdown. HTML получем через открытый API GitHub, а стили просто захардкожены в шаблоне.
|
## Возможности
|
||||||
|
|
||||||

|
- GFM + footnote + emoji + подсветка кода через chroma.
|
||||||
|
- Якоря в заголовках с ASCII-транслитом: `## Установка` → `#ustanovka`.
|
||||||
|
- CLI: `md-to-html cli file.md`.
|
||||||
|
- HTTP API: `POST /convert` совместим с `v0.1.x`.
|
||||||
|
- Web UI на `http://localhost:8080/` с inline-preview в sandbox iframe и одноразовыми ссылками на preview/download.
|
||||||
|
|
||||||
GITHUB_TOKEN не нужен, если не требуется массовая (поточная) конвертация. Но если нужно, то его можно передать через переменную окружения при запуске.
|
## Запуск через Docker
|
||||||
|
|
||||||
Есть два интерфейса:
|
|
||||||
|
|
||||||
- FastAPI на `http://localhost:8000`
|
|
||||||
- Streamlit UI на `http://localhost:8501` с двумя режимами ввода: загрузка `.md` файла или вставка Markdown-текста из буфера обмена
|
|
||||||
|
|
||||||
## Локальный запуск
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
uv venv .venv
|
docker run --rm -p 8080:8080 ghcr.io/fserg/md-to-html:latest
|
||||||
source .venv/bin/activate
|
|
||||||
uv pip install -r requirements.txt
|
|
||||||
uvicorn app.api:app --reload
|
|
||||||
streamlit run app/streamlit_app.py
|
|
||||||
```
|
```
|
||||||
|
|
||||||
CLI сохранился:
|
## Локальная разработка
|
||||||
|
|
||||||
|
Требования: Go 1.23+, `templ` CLI, Node.js для dev-режима Tailwind или standalone `tailwindcss`.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
python3 md_to_html.py /path/to/file.md
|
go install github.com/a-h/templ/cmd/templ@v0.3.1001
|
||||||
|
make tailwind
|
||||||
|
make build
|
||||||
|
./bin/md-to-html serve
|
||||||
```
|
```
|
||||||
|
|
||||||
## Docker
|
Для live-reload:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker build -t md-to-html .
|
make dev
|
||||||
docker run --rm -p 8000:8000 -p 8501:8501 -e GITHUB_TOKEN=your_token md-to-html
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## API
|
## CLI
|
||||||
|
|
||||||
|
```bash
|
||||||
|
md-to-html cli file.md
|
||||||
|
md-to-html cli file.md -o out.html
|
||||||
|
md-to-html cli --stdin < file.md
|
||||||
|
md-to-html cli - --title "Заголовок"
|
||||||
|
```
|
||||||
|
|
||||||
|
## HTTP API
|
||||||
|
|
||||||
`POST /convert`
|
`POST /convert`
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl -X POST http://localhost:8000/convert \
|
curl -X POST http://localhost:8080/convert \
|
||||||
-H 'Content-Type: application/json' \
|
-H 'content-type: application/json' \
|
||||||
-d '{"markdown":"# Hello"}'
|
-d '{"markdown":"# Привет"}'
|
||||||
```
|
```
|
||||||
|
|
||||||
`GET /health`
|
Прочие эндпоинты:
|
||||||
|
|
||||||
```bash
|
- `GET /` — веб-интерфейс.
|
||||||
curl http://localhost:8000/health
|
- `GET /health`, `GET /version`, `GET /ready` — служебные эндпоинты.
|
||||||
```
|
- `GET /preview/{id}`, `GET /download/{id}` — одноразовые ссылки из веб-формы.
|
||||||
|
|
||||||
`GET /version`
|
## Env-переменные
|
||||||
|
|
||||||
```bash
|
| Переменная | По умолчанию | Назначение |
|
||||||
curl http://localhost:8000/version
|
|----------------------|--------------|------------|
|
||||||
```
|
| `ADDR` | `:8080` | Адрес прослушивания |
|
||||||
|
| `MAX_MARKDOWN_BYTES` | `1048576` | Лимит размера markdown |
|
||||||
|
| `MAX_REQUEST_BYTES` | `1200000` | Лимит размера HTTP-запроса |
|
||||||
|
| `PREVIEW_TTL` | `1h` | TTL одноразовых ссылок |
|
||||||
|
|
||||||
|
## Миграция с v0.1.x
|
||||||
|
|
||||||
|
- API-контракт `POST /convert` не изменился, существующие клиенты продолжают работать.
|
||||||
|
- Якоря заголовков теперь используют ASCII-транслит. Ссылки вида `#установка` нужно заменить на `#ustanovka`.
|
||||||
|
- HTML-разметка упрощена: больше нет `<div class="markdown-heading">`, поэтому ручные CSS-оверрайды нужно пересмотреть.
|
||||||
|
- Переменная окружения `READY_CHECK_GITHUB` удалена: сервис больше не зависит от внешнего Markdown API.
|
||||||
|
- UI работает на том же порту `8080`, отдельный UI-порт `:8501` больше не нужен.
|
||||||
|
|
||||||
|
Python-реализация сохранена в `archive/`.
|
||||||
|
|
||||||
## Релизы
|
## Релизы
|
||||||
|
|
||||||
Проект использует Semantic Versioning. Текущая версия хранится в файле `VERSION`, история изменений ведётся в `CHANGELOG.md`.
|
|
||||||
|
|
||||||
Чтобы выпустить релиз:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git add VERSION CHANGELOG.md
|
git commit -am "Release vX.Y.Z"
|
||||||
git commit -m "Release v0.1.2"
|
git tag vX.Y.Z
|
||||||
git tag v0.1.2
|
|
||||||
git push origin main --tags
|
git push origin main --tags
|
||||||
gh release create v0.1.2 --notes-file CHANGELOG.md
|
|
||||||
```
|
```
|
||||||
|
|
||||||
После публикации релиза GitHub Actions автоматически собирает Docker-образ и публикует его в GitHub Container Registry:
|
GitHub Actions публикует Docker-образ для `linux/amd64` и `linux/arm64` в GHCR и прикладывает бинарники для `linux/amd64`, `linux/arm64` и `darwin/arm64` к GitHub Release.
|
||||||
|
|
||||||
```bash
|
|
||||||
docker pull ghcr.io/fserg/md-to-html:v0.1.2
|
|
||||||
```
|
|
||||||
|
|||||||
+2
-2
@@ -15,8 +15,8 @@
|
|||||||
| 3 | [HTTP-сервер](phases/phase-3-server.md) | ✅ done | 2026-04-18 | 2026-04-18 | 843d8dc | |
|
| 3 | [HTTP-сервер](phases/phase-3-server.md) | ✅ done | 2026-04-18 | 2026-04-18 | 843d8dc | |
|
||||||
| 4 | [UI на templUI](phases/phase-4-ui.md) | ✅ done | 2026-04-18 | 2026-04-18 | d6aef55 | |
|
| 4 | [UI на templUI](phases/phase-4-ui.md) | ✅ done | 2026-04-18 | 2026-04-18 | d6aef55 | |
|
||||||
| 5 | [CLI-подкоманда](phases/phase-5-cli.md) | ✅ done | 2026-04-18 | 2026-04-18 | 6aa19fe | |
|
| 5 | [CLI-подкоманда](phases/phase-5-cli.md) | ✅ done | 2026-04-18 | 2026-04-18 | 6aa19fe | |
|
||||||
| 6 | [Docker + CI](phases/phase-6-docker-ci.md) | ⏳ pending | — | — | — | |
|
| 6 | [Docker + CI](phases/phase-6-docker-ci.md) | ✅ done | 2026-04-18 | 2026-04-18 | 4b55661 | Tailwind standalone pinned to `v3.4.17`: `latest` did not emit `web/static/dist/app.css` for the current build pipeline. |
|
||||||
| 7 | [Документация + v0.2.0](phases/phase-7-docs.md) | ⏳ pending | — | — | — | |
|
| 7 | [Документация + v0.2.0](phases/phase-7-docs.md) | 🔄 in_progress | 2026-04-18 | — | 66ca056 | `v0.2.0` tag remains failed in remote history; phase continues via patch release `v0.2.1` after fixing lowercase GHCR tags in `release.yml`. |
|
||||||
|
|
||||||
Легенда статусов:
|
Легенда статусов:
|
||||||
- ⏳ `pending` — не начата
|
- ⏳ `pending` — не начата
|
||||||
|
|||||||
Reference in New Issue
Block a user