Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 6 additions & 111 deletions .github/workflows/create-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -402,20 +402,7 @@ jobs:
env:
PCAPKIT_TAG: v${{ steps.get_version.outputs.PCAPKIT_VERSION }}
PCAPKIT_RUN_SHA: ${{ github.sha }}
run: |
set -euo pipefail

run_commit="$(git rev-parse --verify "${PCAPKIT_RUN_SHA}^{commit}")"
git fetch --quiet --force origin "refs/tags/${PCAPKIT_TAG}:refs/tags/${PCAPKIT_TAG}" || true
tagged="$(git rev-parse -q --verify "refs/tags/${PCAPKIT_TAG}^{commit}" || true)"
elsewhere=false
if [ -n "$tagged" ] && [ "$tagged" != "$run_commit" ]; then
elsewhere=true
fi

echo "${PCAPKIT_TAG} -> ${tagged:-no commit}; this run's commit is ${run_commit}; released elsewhere: ${elsewhere}"
echo "PCAPKIT_RELEASED_AT=${tagged}" >> "$GITHUB_OUTPUT"
echo "PCAPKIT_RELEASED_ELSEWHERE=${elsewhere}" >> "$GITHUB_OUTPUT"
run: python3 util/release_tags.py owner

outputs:
PCAPKIT_VERSION: ${{ steps.get_version.outputs.PCAPKIT_VERSION }}
Expand Down Expand Up @@ -563,19 +550,7 @@ jobs:
env:
PCAPKIT_TAGS: v${{ needs.version_check.outputs.PCAPKIT_VERSION }}
PCAPKIT_RUN_SHA: ${{ github.sha }}
run: |
set -euo pipefail

run_commit="$(git rev-parse --verify "${PCAPKIT_RUN_SHA}^{commit}")"
for tag in ${PCAPKIT_TAGS}; do
git fetch --quiet --force origin "refs/tags/${tag}:refs/tags/${tag}" || true
tagged="$(git rev-parse -q --verify "refs/tags/${tag}^{commit}" || true)"
if [ "$tagged" != "$run_commit" ]; then
echo "::error title=${tag} is not this run's commit (#1634)::${tag} resolves to '${tagged:-no commit}', but this run was created for ${run_commit}. Refusing to publish this tree under it: every artefact of a release comes from its tag's commit, so finish that release by re-running the run created for that commit."
exit 1
fi
echo "${tag} -> ${run_commit}"
done
run: python3 util/release_tags.py check

# #1634: a refusal is most likely the workflow-file rule quoted at "Mint
# the release App's token", which GitHub's 2023-11-02 changelog words more
Expand Down Expand Up @@ -793,19 +768,7 @@ jobs:
env:
PCAPKIT_TAGS: v${{ needs.version_check.outputs.PCAPKIT_VERSION }}
PCAPKIT_RUN_SHA: ${{ github.sha }}
run: |
set -euo pipefail

run_commit="$(git rev-parse --verify "${PCAPKIT_RUN_SHA}^{commit}")"
for tag in ${PCAPKIT_TAGS}; do
git fetch --quiet --force origin "refs/tags/${tag}:refs/tags/${tag}" || true
tagged="$(git rev-parse -q --verify "refs/tags/${tag}^{commit}" || true)"
if [ "$tagged" != "$run_commit" ]; then
echo "::error title=${tag} is not this run's commit (#1634)::${tag} resolves to '${tagged:-no commit}', but this run was created for ${run_commit}. Refusing to publish this tree under it: every artefact of a release comes from its tag's commit, so finish that release by re-running the run created for that commit."
exit 1
fi
echo "${tag} -> ${run_commit}"
done
run: python3 util/release_tags.py check

- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
id: setup
Expand Down Expand Up @@ -881,35 +844,7 @@ jobs:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PCAPKIT_RELEASE_TAG: v${{ needs.version_check.outputs.PCAPKIT_VERSION }}
PCAPKIT_ASSETS: dist/*
run: |
set -euo pipefail

published="$(gh release view "$PCAPKIT_RELEASE_TAG" --repo "$GITHUB_REPOSITORY" --json assets --jq '.assets[] | [.name, .state] | @tsv')"
while IFS= read -r pattern; do
[ -n "$pattern" ] || continue
for file in $pattern; do
if [ ! -f "$file" ]; then
echo "::error title=Nothing to upload::'${pattern}' matches no file, so ${PCAPKIT_RELEASE_TAG} would go without it."
exit 1
fi
name="${file##*/}"
state=""
while IFS=$'\t' read -r asset asset_state; do
[ "$asset" != "$name" ] || state="$asset_state"
done <<< "$published"
if [ "$state" = uploaded ]; then
echo "::notice title=${name} already on ${PCAPKIT_RELEASE_TAG}::Left as published (#1640): this run's rebuild is not byte-identical to it."
continue
fi
if [ -n "$state" ]; then
echo "::warning title=${name} uploaded again::${PCAPKIT_RELEASE_TAG} holds it in state '${state}', not 'uploaded' -- an upload that failed partway -- so it is deleted and this file uploaded in its place."
gh release upload "$PCAPKIT_RELEASE_TAG" "$file" --repo "$GITHUB_REPOSITORY" --clobber
else
gh release upload "$PCAPKIT_RELEASE_TAG" "$file" --repo "$GITHUB_REPOSITORY"
fi
echo "${name} -> ${PCAPKIT_RELEASE_TAG}"
done
done <<< "$PCAPKIT_ASSETS"
run: python3 util/release_upload.py

# #1633: this KTLO leg's outcome despite ``continue-on-error``, for
# ``release_status``. ``steps.*.outcome`` covers every step with an ``id``:
Expand Down Expand Up @@ -1000,19 +935,7 @@ jobs:
env:
PCAPKIT_TAGS: v${{ needs.version_check.outputs.PCAPKIT_VERSION }} conda-${{ needs.version_check.outputs.PCAPKIT_VERSION }}+0
PCAPKIT_RUN_SHA: ${{ github.sha }}
run: |
set -euo pipefail

run_commit="$(git rev-parse --verify "${PCAPKIT_RUN_SHA}^{commit}")"
for tag in ${PCAPKIT_TAGS}; do
git fetch --quiet --force origin "refs/tags/${tag}:refs/tags/${tag}" || true
tagged="$(git rev-parse -q --verify "refs/tags/${tag}^{commit}" || true)"
if [ "$tagged" != "$run_commit" ]; then
echo "::error title=${tag} is not this run's commit (#1634)::${tag} resolves to '${tagged:-no commit}', but this run was created for ${run_commit}. Refusing to publish this tree under it: every artefact of a release comes from its tag's commit, so finish that release by re-running the run created for that commit."
exit 1
fi
echo "${tag} -> ${run_commit}"
done
run: python3 util/release_tags.py check

# #888: the per-leg correctness fix. Uncached, per ``version_check``'s
# Anaconda check, so this reads the live state.
Expand Down Expand Up @@ -1267,35 +1190,7 @@ jobs:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PCAPKIT_RELEASE_TAG: v${{ needs.version_check.outputs.PCAPKIT_VERSION }}
PCAPKIT_ASSETS: ${{ steps.conda_build.outputs.packages }}
run: |
set -euo pipefail

published="$(gh release view "$PCAPKIT_RELEASE_TAG" --repo "$GITHUB_REPOSITORY" --json assets --jq '.assets[] | [.name, .state] | @tsv')"
while IFS= read -r pattern; do
[ -n "$pattern" ] || continue
for file in $pattern; do
if [ ! -f "$file" ]; then
echo "::error title=Nothing to upload::'${pattern}' matches no file, so ${PCAPKIT_RELEASE_TAG} would go without it."
exit 1
fi
name="${file##*/}"
state=""
while IFS=$'\t' read -r asset asset_state; do
[ "$asset" != "$name" ] || state="$asset_state"
done <<< "$published"
if [ "$state" = uploaded ]; then
echo "::notice title=${name} already on ${PCAPKIT_RELEASE_TAG}::Left as published (#1640): this run's rebuild is not byte-identical to it."
continue
fi
if [ -n "$state" ]; then
echo "::warning title=${name} uploaded again::${PCAPKIT_RELEASE_TAG} holds it in state '${state}', not 'uploaded' -- an upload that failed partway -- so it is deleted and this file uploaded in its place."
gh release upload "$PCAPKIT_RELEASE_TAG" "$file" --repo "$GITHUB_REPOSITORY" --clobber
else
gh release upload "$PCAPKIT_RELEASE_TAG" "$file" --repo "$GITHUB_REPOSITORY"
fi
echo "${name} -> ${PCAPKIT_RELEASE_TAG}"
done
done <<< "$PCAPKIT_ASSETS"
run: python3 util/release_upload.py

# #888: a run that released nothing says why, in one place. ``version_check``
# can skip before any evidence exists, and ``unit-tests`` can fail or skip
Expand Down
16 changes: 16 additions & 0 deletions docs/source/contributing/workflows.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1234,6 +1234,16 @@ does; each has tests under :file:`tests/project/` that run it.
* - :file:`util/codeql_report.py`
- ``Write the report`` in ``codeql-analysis.yml``'s ``discussion`` (see `CI
Reports`_).
* - :file:`util/release_tags.py`
- ``Check the release tags name this run's commit`` in ``create-release.yml``'s
``github``, ``pypi`` and ``conda``, as ``release_tags.py check``, and ``Check
which commit the version's tag names`` in its ``version_check``, as
``release_tags.py owner`` (`#1634
<https://github.com/JarryShaw/PyPCAPKit/issues/1634>`__, `#1748
<https://github.com/JarryShaw/PyPCAPKit/issues/1748>`__).
* - :file:`util/release_upload.py`
- ``Upload package to GitHub Release`` in ``create-release.yml``'s ``pypi`` and
``conda`` (`#1640 <https://github.com/JarryShaw/PyPCAPKit/issues/1640>`__).

The summaries run on the image's ``/usr/bin/python3`` rather than the leg's
interpreter, which may have failed to set up or be too broken to run anything, so
Expand All @@ -1257,6 +1267,12 @@ could not signal. Both ``changes`` jobs check out on every event, since the scri
tree. ``create-release.yml``'s ``pypi`` job keeps its own copy of
the KTLO summary's shell until its shell moves to scripts too; a project pin runs
that copy and the script on the same steps and requires the same output.
The release scripts run as ``python3``, from a checkout of the whole tree, and are
standard library only: :file:`util/release_tags.py` on the image's
own, since ``github`` has no setup-python and ``pypi`` and ``conda`` run the check
before theirs, and :file:`util/release_upload.py` on the leg's, after it. A project
pin runs each on the cases the shell it replaced handled and requires the same
status, output and calls.
:file:`util/_actions.py` is standard library only, and keeps to 3.7's syntax,
since the scripts on ``/usr/bin/python3`` and on every leg's interpreter import it.

Expand Down
5 changes: 4 additions & 1 deletion tests/project/test_actions_helper_2047.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@
HELPER = ROOT / 'util' / '_actions.py'
#: The scripts that import the helper.
SCRIPTS = ('apt_packages', 'ci_timing', 'classify_changes', 'codeql_report', 'coverage_report', 'leg_summary',
'pip_install', 'regenerate_samples', 'vendor_code_changed', 'vendor_test_gate')
'pip_install', 'regenerate_samples', 'release_tags', 'release_upload', 'vendor_code_changed',
'vendor_test_gate')
#: The top-level modules the helper may import, each in Python 3.7's standard
#: library: the running interpreter's :data:`sys.stdlib_module_names` would
#: pass ``tomllib``, which 3.7 lacks.
Expand All @@ -56,6 +57,8 @@
'leg_summary': (['ktlo'], {'LEG': 'Python 3.8 (KTLO, non-blocking)', 'STEPS': '{}'}),
'pip_install': (['--help'], {}),
'regenerate_samples': (['--help'], {}),
'release_tags': (['--help'], {}),
'release_upload': (['--help'], {}),
'vendor_code_changed': (['--help'], {}),
'vendor_test_gate': (['--help'], {}),
}
Expand Down
5 changes: 3 additions & 2 deletions tests/project/test_release_gates.py
Original file line number Diff line number Diff line change
Expand Up @@ -278,8 +278,9 @@
# anaconda-client binary by path; a bare ``anaconda`` on ``PATH`` is not matched.
'/bin/anaconda"': 'uploads a package to anaconda.org with the anaconda-client CLI',
'softprops/action-gh-release': 'creates a public GitHub Release, and the tag it names',
# ``pypi`` and ``conda`` attach their files this way since #1634.
'gh release upload': 'attaches a file to a public GitHub Release',
# ``pypi`` and ``conda`` attach their files with ``gh release upload`` since
# #1634, which util/release_upload.py runs since #1967.
'util/release_upload.py': 'attaches a file to a public GitHub Release',
'git push': 'pushes a commit or a tag to the repository',
}

Expand Down
Loading
Loading