Skip to content
Merged
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
2 changes: 1 addition & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ LEGACY_DATA_PATH=.
HEARTBEAT_PATH=data/scheduler-heartbeat.json
GEONAMES_USERNAME=
GEONAMES_ENDPOINT=https://secure.geonames.org
SOURCE_URL=
SOURCE_URL=https://github.com/WizardLoop/shabbat/releases/tag/v3.0.0

CUSTOM_EMOJI_ENABLED=1
5 changes: 4 additions & 1 deletion .gitattributes
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
* text=auto
* text=auto eol=lf
*.php text eol=lf
*.json text eol=lf
*.md text eol=lf
Expand All @@ -20,3 +20,6 @@ LICENSES/** -text
migrations/** -text
resources/templates/** -text
tests/Fixtures/** -text

# Preserve pinned preferred-source supplement bytes and original upstream notices.
resources/release/preferred-source/** -text
26 changes: 25 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,32 @@ jobs:
- run: composer analyse
- run: composer check-locales
- run: composer check-docs
- run: composer dependencies
- run: composer dependencies -- --output="$RUNNER_TEMP/dependencies.json"
- run: composer self-check
- name: Verify release packaging regressions
if: matrix.php == '8.4'
run: python3 tests/release_packaging_test.py
- name: Build exact-commit release archives
if: matrix.php == '8.4'
run: composer package
- name: Verify deployment ZIP without Git or BUILD_COMMIT override
if: matrix.php == '8.4'
env:
EXPECTED_COMMIT: ${{ github.sha }}
run: |
archive_dir="$RUNNER_TEMP/shabbat-archive"
mkdir "$archive_dir"
unzip -q "dist/shabbat-$(cat VERSION).zip" -d "$archive_dir"
docker build -t shabbat-archive-ci "$archive_dir"
docker run --rm shabbat-archive-ci php bin/runtime-permissions.php --require-non-root
docker run --rm shabbat-archive-ci php bin/self-check.php --release
docker run --rm -e EXPECTED_COMMIT shabbat-archive-ci php -r '$m=json_decode(file_get_contents("/app/build-info.json"),true,flags:JSON_THROW_ON_ERROR); if ($m["commit"]!==getenv("EXPECTED_COMMIT") || $m["local_changes"]!==false) { exit(1); } echo "Archive identity retained.\n";'
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02
if: matrix.php == '8.4'
with:
name: release-archives-${{ github.sha }}
path: dist/
if-no-files-found: error
docker:
runs-on: ubuntu-latest
steps:
Expand Down
5 changes: 3 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,13 @@ jobs:
- run: composer analyse
- run: composer check-docs
- run: composer check-locales
- run: composer dependencies
- run: composer dependencies -- --output="$RUNNER_TEMP/dependencies.json"
- run: php bin/self-check.php
- run: docker build --build-arg BUILD_COMMIT="${{ github.sha }}" -t shabbat-release .
- run: docker run --rm shabbat-release php bin/runtime-permissions.php --require-non-root
- run: docker run --rm shabbat-release php bin/self-check.php --release
- run: php scripts/package.php
- run: python3 tests/release_packaging_test.py
- run: composer package
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02
with:
name: reviewed-release-archives
Expand Down
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@

PHP 8.3 compatibility: module-delivery bookkeeping now uses the database-owned `BEGIN IMMEDIATE` transaction state and exact connection identity; native callback/message fixtures initialize inherited readonly properties from their declaring class. Regression tests cover rejected foreign/outside transactions, rollback and state reset.

## 3.0.0 - stable

- Promote the reviewed dev.9 implementation to stable 3.0.0 while retaining MadelineProto 8.7.0, SQLite, the Composer lock, all five approved patch sets and migrations 001–016. No new runtime feature or migration is introduced by this promotion.
- Record the owner's successful dev.9 live tests of locking, unlocking, original-permission restoration and restart. Real holy-day transitions, load capacity, long-running soak and feature-specific acceptance remain separate; no broader result is inferred.
- Align English/Hebrew documentation and release identity; provide the complete stopped-writer production cutover into `/root/shabat`, full private backup, explicit import checks, permission recovery, monitoring and rollback.
- Make `composer package` / `php scripts/package.php` produce the two release archives, pinned runtime preferred-source collection, release manifest and SHA-256 sums from an exact clean Git commit. Retain the former installed-tool packager only as explicit `--development` tooling.
- Publish source/metadata with the actual release commit and `local_changes=false`. GitHub publication does not deploy or restart production.

## 3.0.0-dev.9 - GitHub prerelease

- Pin Composer 2.10.3 in CI and Docker to address GitHub Actions token compatibility and the upstream token-disclosure advisory; retain authentication, all quality gates, the application lock and MadelineProto 8.7.0.
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
FROM composer:2.10.3@sha256:af98f42dfff7c68ba8d53c2164fd9fde1087b7d449514baa38c418b1f6bc4bac AS composer
FROM php:8.4.19-cli-bookworm@sha256:3ddb5a91b44a1c922538576d73a6e808fb2438d9d2d65b1fc3ffd55619fac2e3
FROM php:8.4.26-cli-bookworm@sha256:836ac6c672d1372a47c8fd61b625015bd07760f493fb2eaab2087636498a2b4b
RUN apt-get update \
&& apt-get install -y --no-install-recommends ca-certificates tzdata libsqlite3-dev libonig-dev libxml2-dev libzip-dev unzip curl build-essential pkg-config \
&& curl --fail --location --proto '=https' --tlsv1.2 https://www.sqlite.org/2026/sqlite-autoconf-3510300.tar.gz -o /tmp/sqlite.tar.gz \
Expand Down
27 changes: 14 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ A Telegram bot built with PHP, MadelineProto and SQLite for Shabbat and festival
[![License: AGPL-3.0-only](https://img.shields.io/badge/license-AGPL--3.0--only-blue)](LICENSE)
[![PHP 8.3–8.5](https://img.shields.io/badge/PHP-8.3%E2%80%938.5-777BB4)](composer.json)
[![MadelineProto 8.7.0](https://img.shields.io/badge/MadelineProto-8.7.0-2CA5E0)](composer.lock)
[![Development 3.0.0-dev.9](https://img.shields.io/badge/status-3.0.0--dev.9-orange)](VERSION)
[![Stable 3.0.0](https://img.shields.io/badge/status-3.0.0%20stable-green)](VERSION)

**Current version: 3.0.0-dev.9, a prerelease.** Use the matching [release assets](https://github.com/WizardLoop/shabbat/releases/tag/v3.0.0-dev.9) or tagged checkout and retain its build metadata. Automated tests, Docker checks and live Telegram acceptance remain separate. For an existing bot, follow the [production upgrade and rollback guide](docs/PRODUCTION_UPGRADE.md) before replacing files or starting a second instance. See [publication status](docs/PUBLICATION_STATUS.md), [changes](CHANGELOG.md) and [delivery safety](docs/DEV9_DELIVERY_SAFETY.md). Badges describe source configuration, not production acceptance.
**Current version: 3.0.0, stable.** Use the matching [release assets](https://github.com/WizardLoop/shabbat/releases/tag/v3.0.0) or tagged checkout and retain its build metadata. The owner confirmed dev.9 live group locking, unlocking, original-permission restoration and restart. This does not establish holy-day timing, load capacity or a long-running soak; automated and host-specific acceptance remain separate. For an existing bot, follow the [production upgrade and rollback guide](docs/PRODUCTION_UPGRADE.md) before replacing files or starting a second instance. See [publication status](docs/PUBLICATION_STATUS.md), [changes](CHANGELOG.md) and [delivery safety](docs/DEV9_DELIVERY_SAFETY.md). Badges describe source configuration, not production acceptance.

## Contents

Expand All @@ -30,22 +30,22 @@ A Telegram bot built with PHP, MadelineProto and SQLite for Shabbat and festival
| Storage/operation | SQLite migrations/backups, durable delivery jobs, independent scheduler heartbeats, one application writer and explicit maintenance tools. |
| Donations/source | Optional Telegram Stars, including whole custom amounts 1–10000; version, license and an operator-supplied exact source URL. |

dev.9 adds delivery-time eligibility checks, bounded reminder backlogs, actual spacing/quiet-window checks and independent permission, notification and broadcast work. MadelineProto remains 8.7.0 and the dependency lock is retained. Missing solar values are reported; no polar fallback is invented. Times and ritual texts are informational, with method choices made by the administrator.
3.0.0 retains dev.9 delivery-time eligibility checks, bounded reminder backlogs, actual spacing/quiet-window checks and independent permission, notification and broadcast work. MadelineProto remains 8.7.0 and the dependency lock is retained. Missing solar values are reported; no polar fallback is invented. Times and ritual texts are informational, with method choices made by the administrator.

<a id="requirements"></a>
## Requirements

| Component | Requirement |
|---|---|
| Recommended deployment | Linux, Docker Engine and Compose v2, outbound HTTPS/Telegram access, persistent storage. |
| Manual runtime | 64-bit PHP 8.3/8.4/8.5 and Composer 2. Docker pins PHP 8.4.19 and Composer 2.10.3. |
| Extensions | PDO/PDO SQLite, mbstring, XML, DOM, fileinfo, zlib; ZIP for packaging. Verify all locked requirements with `composer check-platform-reqs`. Docker also builds pcntl and sockets. |
| Manual runtime | 64-bit PHP 8.3/8.4/8.5 and Composer 2. Docker pins PHP 8.4.26 and Composer 2.10.3. |
| Extensions | PDO/PDO SQLite, mbstring, XML, DOM, fileinfo, zlib; ZIP for the optional development packager. Verify all locked requirements with `composer check-platform-reqs`. Docker also builds pcntl and sockets. |
| SQLite | Application minimum 3.35. Release gate accepts 3.51.3+, or reviewed 3.44.6 / 3.50.7. Check PHP's loaded library. Docker builds checksum-verified 3.51.3. |
| Telegram | Your application API ID/hash, BotFather token and configured operator user IDs or resolvable usernames. |
| GeoNames | Your webservice-enabled account for city search/automatic timezone lookup. Known cities and explicit coordinates remain available without it. |
| Filesystem | Persistent application data and separate MadelineProto session. The runtime also needs a writable working directory for its library worker log and PrimeModule copies. |

Offline tests use fake Telegram gateways and provider fixtures without bot credentials. Live staging acceptance must cover permission restoration, interruption/restart, topics, client rendering, inline/GPS, Stars and command menus.
Offline tests use fake Telegram gateways and provider fixtures without bot credentials. Recheck permission restoration and restart on the deployment target; test topics, client rendering, inline/GPS, Stars and command menus where used. See the precise [acceptance record](docs/IMPLEMENTATION_STATUS.md).

<a id="docker-installation"></a>
## Docker installation
Expand All @@ -55,17 +55,18 @@ Shell examples use a Linux/POSIX terminal. Run Docker commands **on the host, fr
1. Obtain the reviewed source. For the release deployment archive:

~~~sh
unzip shabbat-3.0.0-dev.9.zip -d shabbat
unzip shabbat-3.0.0.zip -d shabbat
cd shabbat
unset BUILD_COMMIT
~~~

It contains source and `composer.lock`, without installed `vendor/`. Docker installs locked production dependencies. **Retain archive `build-info.json`.** In this publication archive it records the verified historical baseline commit, `local_changes=true` and the exact publication-source fingerprint; the baseline is not a new commit of these changes. For a reviewed Git checkout instead, supply its actual commit before building:
It contains source and `composer.lock`, without installed `vendor/`. Docker installs locked production dependencies. **Retain archive `build-info.json`.** The release archive records its exact reviewed commit, `local_changes=false` and the application-source fingerprint. Leave `BUILD_COMMIT` absent from `.env`; the archive example clears an inherited value so it cannot override this identity. For a reviewed Git checkout instead, supply its actual commit before building:

~~~sh
export BUILD_COMMIT="$(git rev-parse HEAD)"
~~~

A baseline commit alone does not identify uncommitted changes; the source fingerprint also identifies this snapshot. Do not substitute an unrelated commit.
Use an unchanged release archive or a clean matching Git checkout. Do not substitute an unrelated commit or retain archive metadata after editing its source.

2. Create private configuration once in this new installation:

Expand All @@ -74,7 +75,7 @@ cp .env.example .env
chmod 600 .env
~~~

Edit `.env`: replace Telegram examples, set `ADMIN`, your GeoNames account when needed, and `SOURCE_URL` to the exact corresponding source you make available. Keep simple `KEY=value` syntax compatible with PHP raw INI and Compose. Exclude the configured file from uploads.
Edit `.env`: replace Telegram examples, set `ADMIN`, your GeoNames account when needed, and `SOURCE_URL=https://github.com/WizardLoop/shabbat/releases/tag/v3.0.0` for this unchanged release, whose corresponding-source asset must be available. For modified deployments, provide their exact matching source instead. Keep simple `KEY=value` syntax compatible with PHP raw INI and Compose. Exclude the configured file from uploads.

3. Build and check the image. These steps install/patch dependencies and write image metadata without starting the bot:

Expand Down Expand Up @@ -330,7 +331,7 @@ docker compose run --rm --no-deps shabbat php bin/self-check.php --release

`docker compose up -d shabbat` then activates the reviewed image; inspect logs/health. Manual installations follow stop/backup/install-from-lock/migrate/check/start.

dev.8 → dev.9 adds `016_delivery_safety.sql`. dev.6 also needs 013–015; earlier versions apply all missing migrations automatically. Do not edit applied SQL. Uncertain past delivery attempts are handled conservatively; older unverified permission snapshots still require administrator review.
3.0.0 adds no migration beyond dev.9. dev.8 → dev.9 added `016_delivery_safety.sql`. dev.6 also needs 013–015; earlier versions apply all missing migrations automatically. Do not edit applied SQL. Uncertain past delivery attempts are handled conservatively; older unverified permission snapshots still require administrator review.

For the old file-based bot: preserve a protected legacy copy; stop old writers for final import/cutover; initialize a new DB; run dry-run, compare counts/templates/rights/warnings, then apply with stopped writers and backup directory. The exact commands appear above. For Docker mount only the protected copy read-only:

Expand Down Expand Up @@ -446,13 +447,13 @@ php patches/broadcastmanager/generate-artifacts.php

These commands rewrite patch artifacts/manifests from bundled reviewed sources. They are for an intentional patch review, not routine installation. Review the changed hashes/diffs and run the full patch checks afterward. The apply/verify PHP scripts also accept an optional first positional vendor directory; leave it unset for the normal `vendor/` path.

For local packaging with required development dependencies and verified identity:
For release packaging from a clean committed checkout, with Git, Python 3.9+ and the locked development installation available:

~~~sh
php scripts/package.php
~~~

This writes application, corresponding-source and server-test ZIPs/checksums/manifests to `dist/`, without publishing. This prerelease uses `shabbat-3.0.0-dev.9.zip` without installed dependencies and a separately inventoried runtime corresponding-source bundle; do not substitute the developer packager's installed tool distributions for that source collection. Consult each manifest for inclusion/omissions; application source plus a lockfile is not a complete dependency source bundle.
This writes `shabbat-3.0.0.zip`, `shabbat-3.0.0-corresponding-source.zip`, `RELEASE_MANIFEST.json` and `SHA256SUMS` to `dist/`, without publishing. The source bundle includes locked runtime sources, reviewed patches and pinned preferred-source supplements. The legacy three-archive tool is available only through `php scripts/package.php --development` for local development, with default output `dist/development/`; its installed tool distributions do not constitute a release corresponding-source offer. See [release preparation](docs/RELEASE.md) for prerequisites, source scope and artifact checks.

[Architecture](docs/ARCHITECTURE.md) · [Dependencies](docs/DEPENDENCIES.md) · [Patches](docs/PATCHES.md) · [Release preparation](docs/RELEASE.md) · [Contributing](.github/CONTRIBUTING.md) · [Code of conduct](.github/CODE_OF_CONDUCT.md)

Expand Down
4 changes: 2 additions & 2 deletions THIRD_PARTY_NOTICES.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Third-party notices

WizardLoop Shabbat **3.0.0-dev.9** is distributed as an **AGPL-3.0-only** application. Dependency, historical-source and data licenses retain their own scope. The full application license is in [LICENSE](LICENSE); the [licensing guide](docs/LICENSING.md) explains the source offer. Exact locked versions, sources, license paths and findings are recorded in the [dependency inventory](docs/dependencies.json).
WizardLoop Shabbat **3.0.0** is distributed as an **AGPL-3.0-only** application. Dependency, historical-source and data licenses retain their own scope. The full application license is in [LICENSE](LICENSE); the [licensing guide](docs/LICENSING.md) explains the source offer. Exact locked versions, sources, license paths and findings are recorded in the [dependency inventory](docs/dependencies.json).

## Code and tools

Expand Down Expand Up @@ -35,4 +35,4 @@ The complete [CC-BY-4.0](LICENSES/CC-BY-4.0.txt) and [CC-BY-SA-4.0](LICENSES/CC-

No third-party graphic asset was added. Telegram standard emoji and button metadata are interface features. Provenance of an older remote thumbnail is unestablished; current inline results do not depend on it.

Historical formatted-date reference exports had conflicting project declarations and no recovered standalone grant or Git history. Their hashes and findings are retained in [the provenance review](docs/MADELINE_FORMATTED_DATE.md); those original exports are not redistributed. The retained historical UpdateLoop script has a provenance hash but no standalone license header; its authorship/grant provenance remains a release-review item. Do not treat a successful checksum or a package license inventory as a resolution of that item.
Historical formatted-date reference exports had conflicting project declarations and no recovered standalone grant or Git history. Their hashes and findings are retained in [the provenance review](docs/MADELINE_FORMATTED_DATE.md); those original exports are not redistributed. On 2026-10-16, the project maintainer stated that they authored the retained historical UpdateLoop helper and explicitly authorized distribution under AGPL-3.0-only. The dated, hash-scoped attestation is recorded in [its manifest](patches/madelineproto/manifest.json); the original helper bytes remain unchanged. This records the maintainer's statement, not an independent legal certification.
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3.0.0-dev.9
3.0.0
Loading
Loading