Auto-release on new Neo4j version #699
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: Auto-release on new Neo4j version | |
| on: | |
| schedule: | |
| # Every 2 hours. | |
| - cron: '0 */2 * * *' | |
| workflow_dispatch: {} | |
| permissions: | |
| contents: read | |
| actions: write | |
| env: | |
| # Silence the Node 20 deprecation warning on actions/checkout, setup-python, | |
| # etc. The runtime will flip the default to Node 24 in June 2026 anyway. | |
| FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: 'true' | |
| jobs: | |
| detect: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| should_release: ${{ steps.detect.outputs.should_release }} | |
| helm_chart_version: ${{ steps.detect.outputs.helm_chart_version }} | |
| docker_image_version: ${{ steps.detect.outputs.docker_image_version }} | |
| failure_reason: ${{ steps.detect.outputs.failure_reason }} | |
| missing_variants: ${{ steps.detect.outputs.missing_variants }} | |
| steps: | |
| - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 | |
| with: | |
| ref: dev | |
| - name: Set up Python | |
| uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5 | |
| with: | |
| python-version: '3.12' | |
| - name: Detect new Neo4j docker version | |
| id: detect | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} | |
| GITHUB_REPOSITORY: ${{ github.repository }} | |
| DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }} | |
| DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }} | |
| run: | | |
| python bin/release/detect_new_version.py >> "$GITHUB_OUTPUT" | |
| run-tests-and-release: | |
| needs: detect | |
| if: needs.detect.outputs.should_release == 'true' | |
| runs-on: ubuntu-latest | |
| outputs: | |
| run_id: ${{ steps.dispatch.outputs.run_id }} | |
| run_url: ${{ steps.dispatch.outputs.run_url }} | |
| run_conclusion: ${{ steps.watch.outputs.conclusion }} | |
| steps: | |
| - name: Dispatch tests.yml with RELEASE=true | |
| id: dispatch | |
| env: | |
| GH_TOKEN: ${{ secrets.GH_TOKEN }} | |
| GH_REPO: ${{ github.repository }} | |
| HELM_CHART_VERSION: ${{ needs.detect.outputs.helm_chart_version }} | |
| DOCKER_IMAGE_VERSION: ${{ needs.detect.outputs.docker_image_version }} | |
| run: | | |
| set -euo pipefail | |
| # ISO 8601 instant immediately before dispatch; used to identify the | |
| # run we just created via the --created filter on gh run list. | |
| before=$(date -u +%FT%TZ) | |
| gh workflow run tests.yml \ | |
| --ref dev \ | |
| -f HELM_CHART_VERSION="${HELM_CHART_VERSION}" \ | |
| -f DOCKER_IMAGE_VERSION="${DOCKER_IMAGE_VERSION}" \ | |
| -f RELEASE=true | |
| # Poll for the new run to appear (up to ~2 minutes). | |
| run_id="" | |
| for _ in $(seq 1 30); do | |
| sleep 5 | |
| run_id=$(gh run list \ | |
| --workflow=tests.yml \ | |
| --event=workflow_dispatch \ | |
| --branch=dev \ | |
| --created=">=${before}" \ | |
| --limit 1 \ | |
| --json databaseId \ | |
| --jq '.[0].databaseId' || true) | |
| if [[ -n "${run_id}" && "${run_id}" != "null" ]]; then | |
| break | |
| fi | |
| done | |
| if [[ -z "${run_id}" || "${run_id}" == "null" ]]; then | |
| echo "::error::Failed to locate dispatched tests.yml run after 150s" | |
| exit 1 | |
| fi | |
| url="${{ github.server_url }}/${{ github.repository }}/actions/runs/${run_id}" | |
| echo "run_id=${run_id}" >> "$GITHUB_OUTPUT" | |
| echo "run_url=${url}" >> "$GITHUB_OUTPUT" | |
| echo "Dispatched run: ${url}" | |
| - name: Wait for tests.yml to finish | |
| id: watch | |
| env: | |
| GH_TOKEN: ${{ secrets.GH_TOKEN }} | |
| GH_REPO: ${{ github.repository }} | |
| run: | | |
| set -euo pipefail | |
| gh run watch "${{ steps.dispatch.outputs.run_id }}" --exit-status | |
| conclusion=$(gh run view "${{ steps.dispatch.outputs.run_id }}" --json conclusion --jq .conclusion) | |
| echo "conclusion=${conclusion}" >> "$GITHUB_OUTPUT" | |
| notify_failure: | |
| needs: [detect, run-tests-and-release] | |
| if: ${{ always() && (needs.detect.result == 'failure' || needs.run-tests-and-release.result == 'failure') }} | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: slackapi/slack-github-action@fcfb566f8b0aab22203f066d80ca1d7e4b5d05b3 # v1 | |
| env: | |
| SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} | |
| with: | |
| channel-id: ${{ vars.SLACK_CHANNEL_FAILURES }} | |
| payload: | | |
| { | |
| "text": ":x: helm-charts auto-release failed. Detector: ${{ needs.detect.result }}; release run: ${{ needs.run-tests-and-release.result }}. Neo4j: ${{ needs.detect.outputs.docker_image_version || 'unknown' }}; chart: ${{ needs.detect.outputs.helm_chart_version || 'unknown' }}; reason: ${{ needs.detect.outputs.failure_reason || 'workflow_failure' }}; missing variants: ${{ needs.detect.outputs.missing_variants || 'n/a' }}. Dispatched run: ${{ needs.run-tests-and-release.outputs.run_url || 'not dispatched' }} | Orchestrator: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" | |
| } | |
| notify_success: | |
| needs: [detect, run-tests-and-release] | |
| if: ${{ needs.detect.result == 'success' && needs.run-tests-and-release.result == 'success' && needs.detect.outputs.should_release == 'true' }} | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: slackapi/slack-github-action@fcfb566f8b0aab22203f066d80ca1d7e4b5d05b3 # v1 | |
| env: | |
| SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} | |
| with: | |
| channel-id: ${{ vars.SLACK_CHANNEL_RELEASES }} | |
| payload: | | |
| { | |
| "text": ":white_check_mark: helm-charts auto-released ${{ needs.detect.outputs.helm_chart_version }} (Neo4j ${{ needs.detect.outputs.docker_image_version }}). Release: ${{ github.server_url }}/${{ github.repository }}/releases/tag/${{ needs.detect.outputs.helm_chart_version }}" | |
| } |