upstream-watch #37
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: upstream-watch | |
| # Keeps the repo "alive": daily check for a newer upstream Quantum ESPRESSO | |
| # release. Opens an issue when one appears — a human still cuts the release tag. | |
| # | |
| # The job FAILS (red run) when it cannot perform the check at all — an | |
| # unreachable GitLab API must not look like "nothing new". | |
| on: | |
| schedule: | |
| - cron: '23 6 * * *' # daily 06:23 UTC | |
| workflow_dispatch: | |
| permissions: | |
| contents: read | |
| issues: write | |
| jobs: | |
| check: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Check for newer Quantum ESPRESSO release | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| MAINTAINER: krabiswabbie | |
| run: | | |
| set -euo pipefail | |
| fetch() { | |
| for _ in 1 2 3; do | |
| curl -fsSL --max-time 60 "$1" && return 0 | |
| sleep 20 | |
| done | |
| return 1 | |
| } | |
| current="$(grep -m1 -oE 'QE_VERSION=[0-9.]+' Dockerfile | cut -d= -f2)" | |
| echo "Pinned QE: $current" | |
| # QE source lives on GitLab (QEF/q-e). Stable releases are tags of the | |
| # form qe-X.Y or qe-X.Y.Z — exclude RCs (-rc.N), -devel, and variant | |
| # tags (e.g. qe-7.5CN, qe-7.2-omp5) by matching pure version tags only. | |
| if ! tags="$(fetch 'https://gitlab.com/api/v4/projects/QEF%2Fq-e/repository/tags?per_page=100')"; then | |
| echo "::error::GitLab API unreachable after 3 attempts — could not check for updates." | |
| exit 1 | |
| fi | |
| latest="$(printf '%s' "$tags" \ | |
| | grep -oE '"name":"qe-[0-9]+\.[0-9]+(\.[0-9]+)?"' \ | |
| | grep -oE '[0-9]+\.[0-9]+(\.[0-9]+)?' \ | |
| | sort -V | tail -1 || true)" | |
| if [ -z "$latest" ]; then | |
| echo "::error::No stable qe-X.Y tag in the GitLab response — API shape probably changed; this watcher needs fixing." | |
| exit 1 | |
| fi | |
| echo "Latest upstream stable: $latest" | |
| if [ "$current" = "$latest" ]; then | |
| echo "Up to date."; exit 0 | |
| fi | |
| newest="$(printf '%s\n%s\n' "$current" "$latest" | sort -V | tail -1)" | |
| if [ "$newest" != "$latest" ]; then | |
| echo "Pinned ($current) is newer than/equal to upstream ($latest); nothing to do."; exit 0 | |
| fi | |
| # Confirm the archive tarball our Dockerfile downloads actually exists. | |
| # A 404 means the tag exists but the archive does not yet — quiet skip. | |
| # A dead connection is not an answer and must not look like one. | |
| # (Capturing curl's output instead of `|| echo 000`: curl already | |
| # prints 000 on a connection failure and the two would concatenate.) | |
| if out="$(curl -sSL --max-time 60 -o /dev/null -w '%{http_code}' \ | |
| "https://gitlab.com/QEF/q-e/-/archive/qe-${latest}/q-e-qe-${latest}.tar.gz" 2>/dev/null)"; then | |
| code="$out" | |
| else | |
| code="000" | |
| fi | |
| if [ "$code" = "000" ]; then | |
| echo "::error::gitlab.com unreachable — could not confirm the ${latest} archive." | |
| exit 1 | |
| fi | |
| if [ "$code" != "200" ]; then | |
| echo "Upstream has $latest but archive tarball returns HTTP $code; skipping." | |
| exit 0 | |
| fi | |
| title="Upstream Quantum ESPRESSO ${latest} available (pinned: ${current})" | |
| if gh issue list --state open --search "in:title \"${title}\"" \ | |
| --json title --jq '.[].title' | grep -Fxq "$title"; then | |
| echo "Issue already open: $title"; exit 0 | |
| fi | |
| body="$(printf '%s\n' \ | |
| "Quantum ESPRESSO **${latest}** is available upstream (GitLab archive tarball verified). This repo is pinned to **${current}**." \ | |
| "" \ | |
| "To release (per README \"Bumping the QE version\"):" \ | |
| "1. Edit \`ARG QE_VERSION\` default in \`Dockerfile\` (both stages) to \`${latest}\`." \ | |
| "2. Update the version examples in \`README.md\`." \ | |
| "3. Commit to \`main\`." \ | |
| "4. Cut the tag: \`git tag v${latest} && git push --tags\` — GHA publishes \`ghcr.io/material-codes/qe-base:${latest}\`." \ | |
| "" \ | |
| "Review the upstream release notes before releasing — a minor-version bump can shuffle CMake flags or build targets (this image builds only the \`pw pp\` targets)." \ | |
| "" \ | |
| "Publishing the image is only half of it. Nothing consumes the new tag until \`material/core\` moves its pins: \`QE_VERSION\` in \`.gitlab-ci.yml\` (the source of truth, it feeds the runner build-args) plus the \`ARG\` default in \`Dockerfile.qerunner\`, which governs local builds and must not drift from it. Adopt only after a runner smoke — a green image build says nothing about whether pw.x still converges the way the runner expects." \ | |
| "" \ | |
| "cc @${MAINTAINER}" \ | |
| "" \ | |
| "_Opened automatically by the upstream-watch workflow._")" | |
| # Assign + @mention deliberately: an issue opened by github-actions[bot] | |
| # generates NO notification unless you watch the repo, while assignment | |
| # and mentions land in the "Participating" class, which is emailed by | |
| # default. If the assignment ever stops working the run goes red, which | |
| # is itself the signal. | |
| gh issue create --title "$title" --body "$body" --assignee "$MAINTAINER" |