2222 options :
2323 - test
2424 - prod
25+ nightly-stale-after-days :
26+ type : string
27+ description : After how many days should nightlies be considered stale
28+ required : true
29+ default : 3
2530 store-s3 :
2631 type : boolean
2732 description : Also store test packages in S3 (always true for prod)
4146 duckdb-sha : ${{ inputs.duckdb-sha }}
4247 set-version : ${{ inputs.stable-version }}
4348
49+ submodule_pr :
50+ name : Create or update PR to bump submodule to given SHA
51+ needs : build_sdist
52+ uses : ./.github/workflows/submodule_auto_pr.yml
53+ with :
54+ duckdb-python-sha : ${{ inputs.duckdb-python-sha }}
55+ duckdb-sha : ${{ inputs.duckdb-sha }}
56+ secrets :
57+ # reusable workflows and secrets are not great: https://github.com/actions/runner/issues/3206
58+ DUCKDBLABS_BOT_TOKEN : ${{ secrets.DUCKDBLABS_BOT_TOKEN }}
59+
4460 workflow_state :
4561 name : Set state for the release workflow
4662 needs : build_sdist
@@ -51,23 +67,36 @@ jobs:
5167 runs-on : ubuntu-latest
5268 steps :
5369 - id : index_check
54- name : Check ${{ needs.build_sdist.outputs.package- version }} on PyPI
70+ name : Check version on PyPI
5571 run : |
56- set -eu
57- # Check PyPI whether the release we're building is already present
72+ set -ex
5873 pypi_hostname=${{ inputs.pypi-index == 'test' && 'test.' || '' }}pypi.org
59- pkg_version=${{ needs.build_sdist.outputs.package-version }}
60- url=https://${pypi_hostname}/pypi/duckdb/${pkg_version}/json
61- http_status=$( curl -s -o /dev/null -w "%{http_code}" $url || echo $? )
62- if [[ $http_status == "200" ]]; then
63- echo "::warning::Package version ${pkg_version} is already present on ${pypi_hostname}"
64- pypi_state=VERSION_FOUND
65- elif [[ $http_status == 000* ]]; then
66- echo "::error::Error checking PyPI at ${url}: curl exit code ${http_status#'000'}"
67- pypi_state=UNKNOWN
68- else
69- echo "::notice::Package version ${pkg_version} not found on ${pypi_hostname} (http status: ${http_status})"
74+ # install duckdb
75+ curl https://install.duckdb.org | sh
76+ # query pypi
77+ result=$(cat <<EOF | ${HOME}/.duckdb/cli/latest/duckdb | xargs
78+ ---- Output lines
79+ .mode line
80+ ---- Query that fetches the given version's age, if the version already exists
81+ SELECT
82+ today() - (file.value->>'upload_time_iso_8601')::DATE AS age,
83+ FROM read_json('https://${pypi_hostname}/pypi/duckdb/json') AS jd
84+ CROSS JOIN json_each(jd.releases) AS rel(key, value)
85+ CROSS JOIN unnest(FROM_JSON(rel.value, '["JSON"]')) AS file(value)
86+ WHERE rel.key='${{ needs.build_sdist.outputs.package-version }}'
87+ LIMIT 1;
88+ EOF
89+ )
90+ if [ -z "$result" ]; then
7091 pypi_state=VERSION_NOT_FOUND
92+ else
93+ pypi_state=VERSION_FOUND
94+ fi
95+ if [[ -z "${{ inputs.stable-version }}" ]]; then
96+ age=${result#age = }
97+ if [ "${age}" -ge "${{ inputs.nightly-stale-after-days }}" ]; then
98+ echo "::warning title=Stale nightly for ${{ github.ref_name }}::Nightly is ${age} days old (max=${{ inputs.nightly-stale-after-days }})"
99+ fi
71100 fi
72101 echo "pypi_state=${pypi_state}" >> $GITHUB_OUTPUT
73102
96125 echo "::notice::S3 upload disabled in inputs, not generating S3 URL"
97126 exit 0
98127 fi
99- if [[ VERSION_FOUND = = "${{ steps.index_check.outputs.pypi_state }}" ]]; then
128+ if [[ VERSION_NOT_FOUND ! = "${{ steps.index_check.outputs.pypi_state }}" ]]; then
100129 echo "::warning::S3 upload disabled because package version already uploaded to PyPI"
101130 exit 0
102131 fi
@@ -110,7 +139,7 @@ jobs:
110139 build_wheels :
111140 name : Build and test releases
112141 needs : workflow_state
113- if : ${{ needs.workflow_state.outputs.pypi_state != 'VERSION_FOUND ' }}
142+ if : ${{ needs.workflow_state.outputs.pypi_state == 'VERSION_NOT_FOUND ' }}
114143 uses : ./.github/workflows/packaging_wheels.yml
115144 with :
116145 minimal : false
@@ -132,14 +161,12 @@ jobs:
132161 path : artifacts/
133162 merge-multiple : true
134163
135- - name : Authenticate with AWS
136- uses : aws-actions/configure-aws-credentials@v4
137- with :
138- aws-region : ' us-east-2'
139- aws-access-key-id : ${{ secrets.S3_DUCKDB_STAGING_ID }}
140- aws-secret-access-key : ${{ secrets.S3_DUCKDB_STAGING_KEY }}
141-
142164 - name : Upload Artifacts
165+ env :
166+ AWS_ENDPOINT_URL : ${{ secrets.S3_DUCKDB_STAGING_ENDPOINT }}
167+ AWS_ACCESS_KEY_ID : ${{ secrets.S3_DUCKDB_STAGING_ID }}
168+ AWS_SECRET_ACCESS_KEY : ${{ secrets.S3_DUCKDB_STAGING_KEY }}
169+
143170 run : |
144171 aws s3 cp artifacts ${{ needs.workflow_state.outputs.s3_url }} --recursive
145172
0 commit comments