Skip to content

Update SQLite (Manual) #26

Update SQLite (Manual)

Update SQLite (Manual) #26

Workflow file for this run

name: Update SQLite (Manual)
on:
workflow_dispatch:
inputs:
sqlite3mc_version:
description: "SQLite3MC version (e.g. 2.3.4)"
required: true
sqlite_version:
description: "SQLite version (e.g. 3.53.1)"
required: true
android_check_in:
description: "SQLite Android Check-In (e.g. fc6c086470)"
required: true
mode:
description: "Update mode"
required: true
type: choice
default: dry-run
options:
- sanity
- dry-run
- update
permissions:
contents: read
concurrency:
group: update-sqlite-${{ github.ref }}
cancel-in-progress: false
env:
CONFIG_FILE: config.json
SQLITE_PATH: sqlite3
ARCHIVES: archives
jobs:
generate:
name: Update version information and SQLite sources
runs-on: ubuntu-latest
timeout-minutes: 30
permissions:
contents: write # commits & pushes updated SQLite sources
env:
MODE: ${{ github.event.inputs.mode }}
steps:
# -------------------------------------------------
# Checkout repository
# -------------------------------------------------
- name: Checkout repository
uses: actions/checkout@v7
with:
fetch-depth: 0
# -------------------------------------------------
# Setup Python
# -------------------------------------------------
- name: Setup Python
uses: actions/setup-python@v6
with:
python-version: "3.12"
# -------------------------------------------------
# Update SQLite version number in configuration
# -------------------------------------------------
- name: Update config
shell: bash
run: |
set -euo pipefail
python scripts/update_config.py "${{ inputs.sqlite3mc_version }}" "${{ inputs.sqlite_version }}" "${{ inputs.android_check_in }}"
# -------------------------------------------------
# Validate config
# -------------------------------------------------
- name: Validate config
run: |
set -euo pipefail
python scripts/validate_config.py config.json
# -------------------------------------------------
# Create environment variables
# -------------------------------------------------
- name: Build context
shell: bash
run: |
set -euo pipefail
python scripts/build_context.py
# -------------------------------------------------
# Display environment variables
# -------------------------------------------------
- name: Show environment
shell: bash
run: |
set -euo pipefail
echo "SQLite3MC Version: $SQLITE3MC_VERSION"
echo "SQLite Version: $SQLITE_VERSION"
echo "SQLite Version Raw: $SQLITE_VERSION_RAW"
echo "SQLite URL Official: $SQLITE_URL_OFFICIAL"
echo "SQLite URL GitHub: $SQLITE_URL_GITHUB"
# -------------------------------------------------
# Generate version-dependent files
# -------------------------------------------------
- name: Generate version-dependent files
shell: bash
run: |
set -euo pipefail
python scripts/render_template.py packaging/sqlite3mc_version.h.in "src/sqlite3mc_version.h"
python scripts/render_template.py packaging/autoconf/VERSION.in "autoconf/VERSION"
python scripts/render_template.py packaging/autoconf/sqlite3rc.h.in "autoconf/sqlite3rc.h"
# -------------------------------------------------
# Update version in CMake build file
# -------------------------------------------------
- name: Update version in build files
shell: bash
run: |
set -euo pipefail
python scripts/update_build_files.py
# -------------------------------------------------
# Upload version-dependent files (for debugging)
# -------------------------------------------------
- name: Upload version-dependent files
uses: actions/upload-artifact@v7
with:
name: version-deps
path: |
config.json
CMakeLists.txt
configure.ac
autoconf/VERSION
autoconf/sqlite3rc.h
src/sqlite3mc_version.h
# -------------------------------------------------
# Create directories for intermediate files
# -------------------------------------------------
- name: Create directories
shell: bash
run: |
set -euo pipefail
mkdir -p "$SQLITE_PATH"
mkdir -p "$ARCHIVES"
# -------------------------------------------------
# Download current SQLite download page
# -------------------------------------------------
- name: Download SQLite download page
run: |
set -euo pipefail
curl -fsSL https://sqlite.org/download.html -o download.html
# -------------------------------------------------
# Extract SHA3 for amalgamation from download page
# -------------------------------------------------
- name: Extract SHA3 for amalgamation
id: sqlite-download
run: |
set -euo pipefail
line=$(grep "^PRODUCT,${SQLITE_VERSION},.*sqlite-amalgamation.*\.zip," download.html)
if [ -z "$line" ]; then
echo "No amalgamation entry found for SQLite ${SQLITE_VERSION}"
exit 1
fi
IFS=',' read -r product version relurl size sha3 <<< "$line"
echo "url=https://sqlite.org/${relurl}" >> "$GITHUB_OUTPUT"
echo "sha3=${sha3}" >> "$GITHUB_OUTPUT"
echo "Found:"
echo "URL : https://sqlite.org/${relurl}"
echo "SHA3: ${sha3}"
# -------------------------------------------------
# Download amalgamation archive
# -------------------------------------------------
- name: Download amalgamation archive
run: |
set -euo pipefail
echo "Downloading SQLite source amalgamation: ${{ steps.sqlite-download.outputs.url }}"
curl -fsSL --retry 3 --retry-delay 5 \
"${{ steps.sqlite-download.outputs.url }}" \
-o sqlite-amalgamation.zip
# -------------------------------------------------
# Verify SHA3-256 checksum
# -------------------------------------------------
- name: Verify SHA3-256 checksum
env:
EXPECTED_SHA3: ${{ steps.sqlite-download.outputs.sha3 }}
run: |
set -euo pipefail
python3 scripts/verify_sha3.py \
sqlite-amalgamation.zip \
"${{ steps.sqlite-download.outputs.sha3 }}"
# -------------------------------------------------
# Extract SQLite sources from amalgamation archive
# -------------------------------------------------
- name: Extract SQLite sources from amalgamation archive
shell: bash
run: |
set -euo pipefail
echo "Extracting..."
unzip -q sqlite-amalgamation.zip -d "$SQLITE_PATH"
rm sqlite-amalgamation.zip
echo "Done. Contents of $SQLITE_PATH:"
ls -la "$SQLITE_PATH"
# -------------------------------------------------
# Generate patched SQLite source files
# -------------------------------------------------
- name: Patch SQLite3 amalgamation
shell: bash
run: |
set -euo pipefail
sqlite3_h="${{ env.SQLITE_PATH }}/sqlite-amalgamation-${{ env.SQLITE_VERSION_RAW }}/sqlite3.h"
sqlite3ext_h="${{ env.SQLITE_PATH }}/sqlite-amalgamation-${{ env.SQLITE_VERSION_RAW }}/sqlite3ext.h"
sqlite_src="${{ env.SQLITE_PATH }}/sqlite-amalgamation-${{ env.SQLITE_VERSION_RAW }}/sqlite3.c"
shell_src="${{ env.SQLITE_PATH }}/sqlite-amalgamation-${{ env.SQLITE_VERSION_RAW }}/shell.c"
dest_sqlite="${{ env.SQLITE_PATH }}/sqlite3patched.c"
dest_shell="${{ env.SQLITE_PATH }}/shell.c"
dest_rekey="${{ env.SQLITE_PATH }}/rekeyvacuum.c"
# Make sure that scripts are executable
chmod +x scripts/patchsqlite3.sh
chmod +x scripts/patchshell.sh
chmod +x scripts/rekeyvacuum.sh
ls -l scripts/
bash scripts/patchsqlite3.sh $sqlite_src > $dest_sqlite
bash scripts/patchshell.sh $shell_src > $dest_shell
bash scripts/rekeyvacuum.sh $sqlite_src > $dest_rekey
cp "$sqlite_src" "$SQLITE_PATH/"
cp "$shell_src" "$SQLITE_PATH/shell-orig.c"
cp "$sqlite3_h" "$SQLITE_PATH/"
cp "$sqlite3ext_h" "$SQLITE_PATH/"
ls -l "${{ env.SQLITE_PATH }}"
# -------------------------------------------------
# Compare generated patched source files with previous version
# -------------------------------------------------
# Usually they will differ when updating to a new version.
# However, after a successful update, repeating the update process
# for the same version should result in identical files.
# -------------------------------------------------
- name: Comparing patched SQLite files
shell: bash
run: |
set -euo pipefail
FILES=(
"sqlite3patched.c"
"rekeyvacuum.c"
"shell.c"
)
echo "=== Patch comparison report ==="
CHANGED=0
for f in "${FILES[@]}"; do
echo ""
echo "Checking: $f"
if cmp -s "src/$f" "$SQLITE_PATH/$f"; then
echo "OK: identical"
else
echo "DIFF: changed"
CHANGED=1
echo "--- diff ($f) ---"
diff -u "src/$f" "$SQLITE_PATH/$f" || true
fi
done
echo ""
echo "=== Summary ==="
if [ "$CHANGED" -eq 0 ]; then
echo "All files identical"
else
echo "Some files differ (see above)"
fi
exit 0
# -------------------------------------------------
# Compare generated patched source files with originals
# -------------------------------------------------
# If the number of deviations doesn't correspond to the
# number of applied patch hunks, it will be required to
# inspect the files carefully, and to adjust the patches
# if necessary.
# -------------------------------------------------
- name: Per-file patch impact analysis
shell: bash
run: |
set -euo pipefail
COMPARE_PAIRS=(
"sqlite3.c:sqlite3patched.c"
"shell-orig.c:shell.c"
"../src/rekeyvacuum.c:rekeyvacuum.c"
)
for pair in "${COMPARE_PAIRS[@]}"; do
SRC="${pair%%:*}"
DST="${pair##*:}"
ORIGINAL="$SQLITE_PATH/$SRC"
PATCHED="$SQLITE_PATH/$DST"
echo ""
echo "Comparing:"
echo " original: $SRC"
echo " patched : $DST"
DIFF_BLOCKS=$(diff -u "$ORIGINAL" "$PATCHED" \
| grep -c '^@@' || true)
echo "Patch blocks: $DIFF_BLOCKS"
done
# -------------------------------------------------
# Create ZIP archive(s) for the updated and patched SQLite source files
# -------------------------------------------------
- name: Create ZIP archive for updated SQLite sources
shell: bash
run: |
set -euo pipefail
DESTPATH="$ARCHIVES"
(
SOURCEPATH="$SQLITE_PATH"
cd "$SOURCEPATH"
find . -maxdepth 1 -type f -print \
| zip "../$DESTPATH/sqlite3source.zip" -@
)
ls -l "$DESTPATH"
# -------------------------------------------------
# Upload ZIP archive
# -------------------------------------------------
- name: Upload ZIP archives
uses: actions/upload-artifact@v7
with:
name: sqlite-sources
path: |
${{ env.ARCHIVES }}/sqlite3source.zip
# -------------------------------------------------
# Replace original and patched SQLite sources
# -------------------------------------------------
- name: Copy original and patched files into src
shell: bash
run: |
set -euo pipefail
echo "Copying files into src/ ..."
for f in sqlite3.c sqlite3.h sqlite3ext.h sqlite3patched.c rekeyvacuum.c shell.c; do
echo "Copying $f"
cp -f "$SQLITE_PATH/$f" src/
done
echo "Done. Checking for changes..."
git status --porcelain
# -------------------------------------------------
# GIT + GPG SETUP (only non-sanity)
# -------------------------------------------------
- name: Configure Git
if: ${{ inputs.mode != 'sanity' }}
run: |
git config user.name "${{ vars.GIT_USER_NAME }}"
git config user.email "${{ vars.GIT_USER_EMAIL }}"
git config user.signingkey "${{ vars.GPG_KEY_ID }}"
git config commit.gpgsign true
# -------------------------------------------------
# Import GPG key (only non-sanity)
# -------------------------------------------------
- name: Import GPG key
if: ${{ inputs.mode != 'sanity' }}
run: |
echo "${{ secrets.GPG_PRIVATE_KEY }}" | gpg --batch --import
# -------------------------------------------------
# DRY RUN VALIDATION
# -------------------------------------------------
- name: Dry-run signing validation
if: ${{ inputs.mode == 'dry-run' }}
shell: bash
run: |
set -euo pipefail
echo "Testing GPG setup..."
gpg --list-secret-keys --keyid-format=long
echo "Testing commit signing..."
git commit --allow-empty -S -m "dry-run signing test"
echo "Verifying signature..."
git log -1 --show-signature
echo "Commit email:"
git log -1 --format='%ae'
echo "Commit signature:"
git log -1 --show-signature
echo "Verify commit:"
git verify-commit HEAD
# -------------------------------------------------
# Commit changed source files and configuration (only update)
# -------------------------------------------------
- name: Commit config and source changes
if: ${{ inputs.mode == 'update' }}
shell: bash
run: |
set -euo pipefail
git add config.json
git add CMakeLists.txt
git add configure.ac
git add autoconf/VERSION
git add autoconf/sqlite3rc.h
git add src/sqlite3.c
git add src/sqlite3.h
git add src/sqlite3ext.h
git add src/sqlite3mc_version.h
git add src/sqlite3patched.c
git add src/shell.c
git add src/rekeyvacuum.c
if git diff --cached --quiet; then
echo "No changes to commit"
exit 0
fi
git commit -m "Update SQLite version to ${{ inputs.sqlite_version }}"
git push