Skip to content

ppg:devel:19: switch pg_tde source to percona/pg_tde main, add build … #6

ppg:devel:19: switch pg_tde source to percona/pg_tde main, add build …

ppg:devel:19: switch pg_tde source to percona/pg_tde main, add build … #6

Workflow file for this run

name: Sync to OBS (main)
# Runs whenever a push to main touches any file under root/.
# Syncs the full package tree to OBS (releases/ directories are excluded from
# sync push traversal), then creates git tags from any release.yaml files
# that changed since the last successful run to trigger obs-release.yml.
#
# Two-job debounce design: the `sync` job serializes on its own concurrency
# group and is never cancelled mid-upload, so back-to-back pushes queue up
# short sync runs instead of waiting behind a multi-hour build poll. The
# `poll` job runs in a cancel-superseding group so a newer push's poll
# replaces an older run's poll (the OBS badge, version lists and release
# tags are derived from the last *successful* run's SHA, so whichever poll
# survives covers the superseded runs' ranges too).
on:
push:
branches: [main]
paths:
- 'root/**'
- '!root/README.md'
workflow_dispatch: {}
jobs:
sync:
name: percona-obs sync push
runs-on: ubuntu-latest
container: ghcr.io/${{ github.repository_owner }}/obs-tools:latest
# Serialize syncs; never cancel a sync mid-upload.
concurrency:
group: sync-main-sync
cancel-in-progress: false
permissions:
contents: read
packages: read
steps:
- uses: actions/checkout@v4
with:
# Full history is required: sync push reads git log to detect
# per-package changes since the last OBS sync commit SHA.
fetch-depth: 0
token: ${{ secrets.GH_PAT }}
# Packages synced before the migration to percona/obs-packaging carry
# OBS sync comments whose SHAs come from the legacy repo's history and
# do not resolve in this clone, which forces --skip-unchanged off the
# cheap git gate into services + upload comparison for every such
# package. Fetch the legacy history so those SHAs resolve; drop this
# step once all packages have been re-synced with percona SHAs.
- name: Fetch legacy repo history (pre-migration sync SHAs)
run: |
git fetch https://github.com/rjd15372/percona-obs-packaging.git \
'refs/heads/*:refs/remotes/legacy/*' \
|| echo "::warning::legacy repo unreachable; sync falls back to content checks"
# Persists the content-addressed .cache/ tree across runs, split in
# two entries:
#
# deps — download_url, cargo_vendor and Phase 2 manual-service
# outputs (crates, go tarballs, vendor tarballs): small and
# stable across commits. Also carries the sync_state
# manifest used by --skip-unchanged.
# scm — Phase 1 obs_scm outputs: multi-GB source archives keyed by
# upstream HEAD, churning on every upstream advance.
#
# Splitting keeps the small, highly-reusable deps cache from being
# evicted out of the repo's 10 GB Actions cache quota by churn in the
# much larger scm tree. Without any cache, every main sync would
# regenerate vendor tarballs with new file mtimes and needlessly
# re-upload them. Entries are content-addressed so a partial hit via
# restore-keys is always safe: unused SHA-keyed subdirs are ignored.
- name: Restore percona-obs deps cache
uses: actions/cache@v4
with:
path: |
.cache/download_url
.cache/cargo_vendor
.cache/services
.cache/sync_state
key: percona-obs-deps-${{ runner.os }}-${{ github.sha }}
restore-keys: |
percona-obs-deps-${{ runner.os }}-
- name: Restore percona-obs scm cache
uses: actions/cache@v4
with:
path: .cache/obs_scm
key: percona-obs-scm-${{ runner.os }}-${{ github.sha }}
restore-keys: |
percona-obs-scm-${{ runner.os }}-
- uses: ./.github/actions/obs-setup
with:
obs-apiurl: ${{ vars.OBS_APIURL }}
obs-user: ${{ vars.OBS_USER }}
obs-password: ${{ secrets.OBS_PASSWORD }}
- name: Create percona-obs profile
env:
OBS_APIURL: ${{ vars.OBS_APIURL }}
OBS_ROOTPRJ: ${{ vars.OBS_ROOTPRJ }}
run: |
venv/bin/python -m percona_obs \
-A "$OBS_APIURL" \
-R "$OBS_ROOTPRJ" \
-e "REMOTE_OBS_ORG_INTERCONNECT:" \
-e "PERCONA_OBS_PACKAGING_BRANCH:main" \
-e "PERCONA_OBS_PACKAGING_REPO:${{ github.server_url }}/${{ github.repository }}.git" \
profile create main
# releases/ directories are excluded from sync push traversal (each
# root/*/releases/<name>/ contains a release.yaml marker that prevents
# find_projects/find_packages from descending), so release commits are
# synced normally but produce no OBS changes.
# The report JSON scopes the poll job to the packages this run touched;
# remove any stale report first (self-hosted runners reuse /tmp).
- name: Sync to OBS
run: |
rm -f /tmp/sync-report.json
venv/bin/python -m percona_obs --verbose -P main sync push \
--no-scm-validate --skip-unchanged --report-json /tmp/sync-report.json
# Drop cache entries not used by any run in the last 7 days so the
# .cache/ tree saved by actions/cache stops growing monotonically.
# Entry mtimes are bumped on every cache hit, so age == unused-for.
# Runs even when the sync fails: pruning only removes stale entries.
- name: Prune stale cache entries
if: always()
env:
PYTHONPATH: ${{ github.workspace }}
run: venv/bin/python .github/scripts/prune_obs_cache.py
# Hand the report to the poll job. Only uploaded on success: poll
# only runs after a successful sync, so an always() upload is not
# needed.
- name: Upload sync report
uses: actions/upload-artifact@v4
with:
name: sync-report
path: /tmp/sync-report.json
retention-days: 1
poll:
name: Wait for OBS builds
needs: sync
runs-on: ubuntu-latest
container: ghcr.io/${{ github.repository_owner }}/obs-tools:latest
timeout-minutes: 360
# Newest poll wins: a newer push's poll supersedes (cancels) older polls.
concurrency:
group: sync-main-poll
cancel-in-progress: true
permissions:
# Required to push the badge JSON to the badges branch.
contents: write
# Required to query sibling workflow runs (gh api .../actions/...).
actions: read
packages: read
steps:
- uses: actions/checkout@v4
with:
# Full history is required to git-diff release.yaml files against
# the last-successful base SHA; GH_PAT is required to push tags.
fetch-depth: 0
token: ${{ secrets.GH_PAT }}
- uses: ./.github/actions/obs-setup
with:
obs-apiurl: ${{ vars.OBS_APIURL }}
obs-user: ${{ vars.OBS_USER }}
obs-password: ${{ secrets.OBS_PASSWORD }}
- name: Download sync report
uses: actions/download-artifact@v4
with:
name: sync-report
path: /tmp
# A superseded (cancelled) poll never runs the version-lists / release
# -tags steps below, so the surviving run must cover the cancelled
# runs' ranges too. Diffing from the head SHA of the last SUCCESSFUL
# sync-main run does exactly that (and tag creation already tolerates
# existing tags). Fall back to github.event.before (empty for
# workflow_dispatch), then to the all-zeros SHA.
- name: Compute last-successful base SHA
id: base
env:
GH_TOKEN: ${{ github.token }}
run: |
LAST_GOOD=$(gh api \
"repos/$GITHUB_REPOSITORY/actions/workflows/sync-main.yml/runs?branch=main&status=success&per_page=1" \
--jq '.workflow_runs[0].head_sha // empty' || true)
BASE="${LAST_GOOD:-${{ github.event.before }}}"
BASE="${BASE:-0000000000000000000000000000000000000000}"
echo "sha=${BASE}" >> "$GITHUB_OUTPUT"
echo "Diff base: ${BASE}"
# Poll OBS until all builds reach a terminal state. Fails the job if
# any build fails, is broken, or is unresolvable. The sync report
# scopes polling to the packages the sync job actually touched.
- name: Poll OBS build status
id: poll
env:
OBS_APIURL: ${{ vars.OBS_APIURL }}
OBS_ROOTPRJ: ${{ vars.OBS_ROOTPRJ }}
OBS_SYNC_REPORT: /tmp/sync-report.json
PYTHONPATH: ${{ github.workspace }}
run: venv/bin/python .github/scripts/poll_obs_builds.py
# Update docs/versions/<dist>.md for each distribution project touched
# since the last successful run, and refresh the README "## Development
# Projects" section. Only runs when OBS builds all succeed.
# Disabled: this step git-pushes regenerated docs/versions/*.md and
# README.md directly to main, which is blocked once main is protected
# against direct pushes. Re-enable (restore the poll-outcome guard) once
# a PR-based or badges-branch publishing path is in place.
- name: Update version lists
if: false
env:
GITHUB_EVENT_BEFORE: ${{ steps.base.outputs.sha }}
OBS_WEB_URL: ${{ vars.OBS_WEB_URL }}
OBS_ROOTPRJ: ${{ vars.OBS_ROOTPRJ }}
PYTHONPATH: ${{ github.workspace }}
run: venv/bin/python .github/scripts/update_version_lists.py
# After builds succeed, detect any release.yaml files changed since the
# last successful run and create git tags from their latest releases:
# entries. The tag (e.g. ppg/17.9-1) triggers obs-release.yml.
- name: Create release tags
if: steps.poll.outcome == 'success'
env:
GH_TOKEN: ${{ secrets.GH_PAT }}
run: |
CHANGED=$(git diff --name-only "${{ steps.base.outputs.sha }}" "$GITHUB_SHA" \
-- 'root/*/releases/*/release.yaml' 2>/dev/null || true)
for release_file in $CHANGED; do
[ -f "$release_file" ] || continue
TAG=$(venv/bin/python3 -c \
"import yaml,sys; d=yaml.safe_load(open(sys.argv[1])); r=d.get('releases',[]); print(r[-1] if r else d.get('revision',''))" \
"$release_file" 2>/dev/null)
[ -z "$TAG" ] && continue
echo "Creating tag ${TAG} → $GITHUB_SHA"
gh api "repos/$GITHUB_REPOSITORY/git/refs" \
-X POST \
-f "ref=refs/tags/${TAG}" \
-f "sha=$GITHUB_SHA" || echo "Tag ${TAG} already exists, skipping"
done
# Push the badge JSON to the orphan `badges` branch so it can be
# embedded in README.md via a shields.io endpoint badge.
# Runs even when the poll step fails so the badge always reflects the
# latest build outcome.
- name: Publish OBS build badge
if: always()
env:
GH_TOKEN: ${{ github.token }}
run: |
[ -f /tmp/obs-build-badge.json ] || exit 0
BADGE=$(base64 -w0 /tmp/obs-build-badge.json)
FILE_SHA=$(gh api \
"repos/$GITHUB_REPOSITORY/contents/obs-build-badge.json?ref=badges" \
--jq '.sha' 2>/dev/null || echo "")
if [ -n "$FILE_SHA" ]; then
gh api "repos/$GITHUB_REPOSITORY/contents/obs-build-badge.json" \
-X PUT \
-f message="ci: update OBS build badge" \
-f content="$BADGE" \
-f branch=badges \
-f sha="$FILE_SHA"
else
gh api "repos/$GITHUB_REPOSITORY/contents/obs-build-badge.json" \
-X PUT \
-f message="ci: update OBS build badge" \
-f content="$BADGE" \
-f branch=badges
fi