Update SQLite (Manual) #26
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 |