diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 984556a03..749ea7fa1 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,8 +1,8 @@ ## Pull Request Checklist - [ ] The Certbot team has recently expressed interest in reviewing a PR for this. If not, this PR may be closed due our limited resources and need to prioritize how we spend them. -- [ ] If you used AI to create this PR, you have done a self-review of all AI-generated code and disclosed that your contribution was AI-generated per [EFF's AI-generated contribution policy](https://www.eff.org/about/opportunities/volunteer/coding-with-eff). You assert you have thoroughly understood, reviewed, and tested your entire submission. +- [ ] If you used AI to create this PR, you have done a self-review of all AI-generated code and disclosed that your contribution was AI-generated per [EFF's AI-generated contribution policy](https://www.eff.org/about/opportunities/volunteer/coding-with-eff#ai-policy). You assert you have thoroughly understood, reviewed, and tested your entire submission. - [ ] If the change being made is to a [distributed component](https://certbot.eff.org/docs/contributing.html#code-components-and-layout), add a description of your change to the `newsfragments` directory. This should be a file called `.<type>`, where `<title>` is either a GitHub issue number or some other unique name starting with `+`, and `<type>` is either `changed`, `fixed`, or `added`. * For example, if you fixed a bug for issue number 42, create a file called `42.fixed` and put a description of your change in that file. - [ ] Add or update any documentation as needed to support the changes in this PR. -- [ ] Include your name in `AUTHORS.md` if you like. \ No newline at end of file +- [ ] Include your name in `AUTHORS.md` if you like. diff --git a/.github/workflows/notify_weekly.yaml b/.github/workflows/notify_weekly.yaml deleted file mode 100644 index 6d55a43d0..000000000 --- a/.github/workflows/notify_weekly.yaml +++ /dev/null @@ -1,29 +0,0 @@ -name: Weekly Github Update - -on: - schedule: - # Every week on Thursday @ 10:00 - - cron: "0 10 * * 4" - workflow_dispatch: -permissions: {} # let's not use any permissions we don't need here -jobs: - send-mattermost-message: - runs-on: ubuntu-latest - - steps: - - name: Create Mattermost Message - run: | - DATE=$(date --date="7 days ago" +"%Y-%m-%d") - echo "ASSIGNED_PRS=https://github.com/pulls?q=is%3Apr+is%3Aopen+updated%3A%3E%3D${DATE}+assignee%3A*+user%3Acertbot" >> $GITHUB_ENV - echo "UPDATED_URL=https://github.com/issues?q=is%3Aissue+is%3Aopen+sort%3Acomments-desc+updated%3A%3E%3D${DATE}+user%3Acertbot" >> $GITHUB_ENV - # we pin this action to a version tested and audited by certbot's - # maintainers for extra security. the full hash is used as doing so is - # recommended by zizmor - - uses: mattermost/action-mattermost-notify@ae31bb6f9e26a54336e79696f108a2c91cf55b4e - with: - MATTERMOST_WEBHOOK_URL: ${{ secrets.MATTERMOST_WEBHOOK_URL }} - MATTERMOST_CHANNEL: private-certbot - TEXT: | - ## Updates In the Past Week - - Most commented in the last week: [link](${{ env.UPDATED_URL }}) - - Updated (assigned) PRs in the last week: [link](${{ env.ASSIGNED_PRS }}) diff --git a/.github/workflows/snap_packaging_jobs.yml b/.github/workflows/snap_packaging_jobs.yml index 58d2bb75f..5cebb9f9d 100644 --- a/.github/workflows/snap_packaging_jobs.yml +++ b/.github/workflows/snap_packaging_jobs.yml @@ -46,7 +46,7 @@ jobs: persist-credentials: false - id: set-dns-dirs run: | - DNS_NAMES="$(echo certbot-dns-* | jq -R -s -c 'split(" ")[:-1]')" + DNS_NAMES="$(echo certbot-dns-* | jq -R -s -c 'gsub("\n"; "") | split(" ")')" echo "dns-dirs=$DNS_NAMES" >> "$GITHUB_OUTPUT" gha_build_dns_snaps: name: Build ${{ matrix.dns-dir }} ${{ matrix.build-for }} diff --git a/acme/setup.py b/acme/setup.py index c36a455ac..11fc858b9 100644 --- a/acme/setup.py +++ b/acme/setup.py @@ -1,6 +1,6 @@ from setuptools import setup -version = '5.7.0.dev0' +version = '5.8.0.dev0' setup( version=version, diff --git a/certbot-apache/setup.py b/certbot-apache/setup.py index dc99a4b1c..ce89349b7 100644 --- a/certbot-apache/setup.py +++ b/certbot-apache/setup.py @@ -1,6 +1,6 @@ from setuptools import setup -version = '5.7.0.dev0' +version = '5.8.0.dev0' install_requires = [ # We specify the minimum certbot version as the current plugin diff --git a/certbot-ci/setup.py b/certbot-ci/setup.py index c36a455ac..11fc858b9 100644 --- a/certbot-ci/setup.py +++ b/certbot-ci/setup.py @@ -1,6 +1,6 @@ from setuptools import setup -version = '5.7.0.dev0' +version = '5.8.0.dev0' setup( version=version, diff --git a/certbot-compatibility-test/setup.py b/certbot-compatibility-test/setup.py index c36a455ac..11fc858b9 100644 --- a/certbot-compatibility-test/setup.py +++ b/certbot-compatibility-test/setup.py @@ -1,6 +1,6 @@ from setuptools import setup -version = '5.7.0.dev0' +version = '5.8.0.dev0' setup( version=version, diff --git a/certbot-dns-cloudflare/setup.py b/certbot-dns-cloudflare/setup.py index f6055686f..6d8ec386d 100644 --- a/certbot-dns-cloudflare/setup.py +++ b/certbot-dns-cloudflare/setup.py @@ -2,7 +2,7 @@ import os from setuptools import setup -version = '5.7.0.dev0' +version = '5.8.0.dev0' install_requires = [ 'cloudflare>=4.0', diff --git a/certbot-dns-digitalocean/setup.py b/certbot-dns-digitalocean/setup.py index 70ac37eeb..0925986d4 100644 --- a/certbot-dns-digitalocean/setup.py +++ b/certbot-dns-digitalocean/setup.py @@ -2,7 +2,7 @@ import os from setuptools import setup -version = '5.7.0.dev0' +version = '5.8.0.dev0' install_requires = [ 'python-digitalocean>=1.15.0', # 1.15.0 or newer is recommended for TTL support diff --git a/certbot-dns-dnsimple/setup.py b/certbot-dns-dnsimple/setup.py index 475972dfc..8e16f34db 100644 --- a/certbot-dns-dnsimple/setup.py +++ b/certbot-dns-dnsimple/setup.py @@ -2,7 +2,7 @@ import os from setuptools import setup -version = '5.7.0.dev0' +version = '5.8.0.dev0' install_requires = [ # This version of lexicon is required to address the problem described in diff --git a/certbot-dns-dnsmadeeasy/setup.py b/certbot-dns-dnsmadeeasy/setup.py index 2d32dacbd..e17fd5066 100644 --- a/certbot-dns-dnsmadeeasy/setup.py +++ b/certbot-dns-dnsmadeeasy/setup.py @@ -2,7 +2,7 @@ import os from setuptools import setup -version = '5.7.0.dev0' +version = '5.8.0.dev0' install_requires = [ 'dns-lexicon>=3.14.1', diff --git a/certbot-dns-gehirn/setup.py b/certbot-dns-gehirn/setup.py index 2d32dacbd..e17fd5066 100644 --- a/certbot-dns-gehirn/setup.py +++ b/certbot-dns-gehirn/setup.py @@ -2,7 +2,7 @@ import os from setuptools import setup -version = '5.7.0.dev0' +version = '5.8.0.dev0' install_requires = [ 'dns-lexicon>=3.14.1', diff --git a/certbot-dns-google/setup.py b/certbot-dns-google/setup.py index 0fa111ae8..c20f69072 100644 --- a/certbot-dns-google/setup.py +++ b/certbot-dns-google/setup.py @@ -2,7 +2,7 @@ import os from setuptools import setup -version = '5.7.0.dev0' +version = '5.8.0.dev0' install_requires = [ 'google-api-python-client>=1.6.5', diff --git a/certbot-dns-linode/setup.py b/certbot-dns-linode/setup.py index 2d32dacbd..e17fd5066 100644 --- a/certbot-dns-linode/setup.py +++ b/certbot-dns-linode/setup.py @@ -2,7 +2,7 @@ import os from setuptools import setup -version = '5.7.0.dev0' +version = '5.8.0.dev0' install_requires = [ 'dns-lexicon>=3.14.1', diff --git a/certbot-dns-luadns/setup.py b/certbot-dns-luadns/setup.py index 2d32dacbd..e17fd5066 100644 --- a/certbot-dns-luadns/setup.py +++ b/certbot-dns-luadns/setup.py @@ -2,7 +2,7 @@ import os from setuptools import setup -version = '5.7.0.dev0' +version = '5.8.0.dev0' install_requires = [ 'dns-lexicon>=3.14.1', diff --git a/certbot-dns-nsone/setup.py b/certbot-dns-nsone/setup.py index 2d32dacbd..e17fd5066 100644 --- a/certbot-dns-nsone/setup.py +++ b/certbot-dns-nsone/setup.py @@ -2,7 +2,7 @@ import os from setuptools import setup -version = '5.7.0.dev0' +version = '5.8.0.dev0' install_requires = [ 'dns-lexicon>=3.14.1', diff --git a/certbot-dns-ovh/setup.py b/certbot-dns-ovh/setup.py index 0673d5bcc..0f91af742 100644 --- a/certbot-dns-ovh/setup.py +++ b/certbot-dns-ovh/setup.py @@ -2,7 +2,7 @@ import os from setuptools import setup -version = '5.7.0.dev0' +version = '5.8.0.dev0' install_requires = [ 'dns-lexicon>=3.15.1', diff --git a/certbot-dns-rfc2136/setup.py b/certbot-dns-rfc2136/setup.py index 5dece69aa..271c75fcc 100644 --- a/certbot-dns-rfc2136/setup.py +++ b/certbot-dns-rfc2136/setup.py @@ -2,7 +2,7 @@ import os from setuptools import setup -version = '5.7.0.dev0' +version = '5.8.0.dev0' install_requires = [ # This version was chosen because it is the version packaged in RHEL 9 and Debian unstable. It diff --git a/certbot-dns-route53/setup.py b/certbot-dns-route53/setup.py index ac93625ab..1893beacc 100644 --- a/certbot-dns-route53/setup.py +++ b/certbot-dns-route53/setup.py @@ -2,7 +2,7 @@ import os from setuptools import setup -version = '5.7.0.dev0' +version = '5.8.0.dev0' install_requires = [ 'boto3>=1.20.34', diff --git a/certbot-dns-sakuracloud/setup.py b/certbot-dns-sakuracloud/setup.py index 2d32dacbd..e17fd5066 100644 --- a/certbot-dns-sakuracloud/setup.py +++ b/certbot-dns-sakuracloud/setup.py @@ -2,7 +2,7 @@ import os from setuptools import setup -version = '5.7.0.dev0' +version = '5.8.0.dev0' install_requires = [ 'dns-lexicon>=3.14.1', diff --git a/certbot-nginx/setup.py b/certbot-nginx/setup.py index 8ae070825..876a39197 100644 --- a/certbot-nginx/setup.py +++ b/certbot-nginx/setup.py @@ -1,6 +1,6 @@ from setuptools import setup -version = '5.7.0.dev0' +version = '5.8.0.dev0' install_requires = [ # We specify the minimum certbot version as the current plugin diff --git a/certbot/CHANGELOG.md b/certbot/CHANGELOG.md index eb8a2bc42..f020c279d 100644 --- a/certbot/CHANGELOG.md +++ b/certbot/CHANGELOG.md @@ -4,6 +4,13 @@ Certbot adheres to [Semantic Versioning](https://semver.org/). <!-- towncrier release notes start --> +## 5.7.0 - 2026-07-15 + +### Fixed + +- Fixed nginx configuration parsing when comments appear between tokens of a multi-line directive. ([#10598](https://github.com/certbot/certbot/issues/10598)) + + ## 5.6.0 - 2026-05-11 ### Changed diff --git a/certbot/docs/cli-help.txt b/certbot/docs/cli-help.txt index 053716b4b..bc55950d8 100644 --- a/certbot/docs/cli-help.txt +++ b/certbot/docs/cli-help.txt @@ -147,7 +147,7 @@ options: case, and to know when to deprecate support for past Python versions and flags. If you wish to hide this information from the Let's Encrypt server, set this to - "". (default: CertbotACMEClient/5.6.0 (certbot; + "". (default: CertbotACMEClient/5.7.0 (certbot; OS_NAME OS_VERSION) Authenticator/XXX Installer/YYY (SUBCOMMAND; flags: FLAGS) Py/major.minor.patchlevel). The flags encoded in the user agent are: --duplicate, diff --git a/certbot/docs/using.rst b/certbot/docs/using.rst index e64fcf9cb..9350b0f04 100644 --- a/certbot/docs/using.rst +++ b/certbot/docs/using.rst @@ -336,6 +336,7 @@ pkcs12_ N Y Install certificates as PKCS#12 archives dns-hetzner-cloud_ Y N DNS Authentication for Hetzner Cloud DNS dns-czechia_ Y N DNS Authentication for czechia.com dns-eurodns_ Y N DNS Authentication for EuroDNS +dns-dnscale_ Y N DNS Authenticator for DNScale ======================= ==== ==== ================================================================= .. _haproxy: https://github.com/greenhost/certbot-haproxy @@ -373,6 +374,7 @@ dns-eurodns_ Y N DNS Authentication for EuroDNS .. _dns-hetzner-cloud: https://github.com/rolschewsky/certbot-dns-hetzner-cloud .. _dns-czechia: https://github.com/CZECHIA-COM/certbot-dns-czechia .. _dns-eurodns: https://pypi.org/project/certbot-dns-eurodns/ +.. _dns-dnscale: https://github.com/dnscaleou/certbot-dns-dnscale If you're interested, you can also :ref:`write your own plugin <dev-plugin>`. diff --git a/certbot/src/certbot/__init__.py b/certbot/src/certbot/__init__.py index b467db186..8da3222d9 100644 --- a/certbot/src/certbot/__init__.py +++ b/certbot/src/certbot/__init__.py @@ -1,4 +1,4 @@ """Certbot client.""" # version number like 1.2.3a0, must have at least 2 parts, like 1.2 -__version__ = '5.7.0.dev0' +__version__ = '5.8.0.dev0' diff --git a/letstest/setup.py b/letstest/setup.py index c36a455ac..11fc858b9 100644 --- a/letstest/setup.py +++ b/letstest/setup.py @@ -1,6 +1,6 @@ from setuptools import setup -version = '5.7.0.dev0' +version = '5.8.0.dev0' setup( version=version, diff --git a/newsfragments/10598.fixed b/newsfragments/10598.fixed deleted file mode 100644 index f0a68b533..000000000 --- a/newsfragments/10598.fixed +++ /dev/null @@ -1 +0,0 @@ -Fixed nginx configuration parsing when comments appear between tokens of a multi-line directive. diff --git a/tools/_release.sh b/tools/_release.sh index 95f722f00..82e15924e 100755 --- a/tools/_release.sh +++ b/tools/_release.sh @@ -103,6 +103,7 @@ tools/pip_install.py build towncrier uv virtualenv root_without_le="$version.$$" root="$RELEASE_DIR/le.$root_without_le" +REPO_ROOT="$(pwd)" echo "Cloning into fresh copy at $root" # clean repo = no artifacts git clone . $root @@ -215,5 +216,10 @@ git commit -m "Remove built packages from git" if [ "$RELEASE_BRANCH" = candidate-"$version" ] ; then SetVersion "$nextversion".dev0 + # If this message changes, it should also be changed in tools/finish_release.py git commit -m "Bump version to $nextversion" fi + +cd $REPO_ROOT +git remote rm temp || : +git remote add temp $root && git fetch temp diff --git a/tools/finish_release.py b/tools/finish_release.py index 4b2e3e32c..23858e412 100755 --- a/tools/finish_release.py +++ b/tools/finish_release.py @@ -1,24 +1,38 @@ #!/usr/bin/env python """ -Post-release script to publish artifacts created from GitHub Actions. +Post-release script to publish artifacts created from GitHub Actions, synchronize the repo + on Github, and print a formatted changelog for the latest release. This currently includes: * Moving snaps from the beta channel to the stable channel +* Pushing the candidate branch to GitHub +* Creating a minor release branch if it's not a point release +* Opening PR(s) to merge the release changes back into `main` and/or the minor release branch +* Printing a formmated changelog for the latest release for distribution Setup: - - Install the snapcraft command line tool and log in to a privileged account. + - Install the `snapcraft` command line tool and log in to a privileged account. - https://snapcraft.io/docs/installing-snapcraft - Use the command `snapcraft login` to log in. + - Install the `gh` command line tool and log in to a privileged account. + - https://github.com/cli/cli#installation + - Use the command `gh auth login` to log in. Run: -python tools/finish_release.py +python tools/finish_release.py [--skip-snaps] [--skip-github-sync] [--test version <VERSION_NUM>] Testing: This script can be safely run between releases. When this is done, the script -should execute successfully. +should execute successfully, if it has not run before. Promoting snaps from beta +and printing the changelog are idempotent, but synchronizing the github repo is not. + +To skip syncing with github, use the `--skip-github-sync` flag. +To skip promoting snaps, use the `--skip-snaps` flag. +To test with a version other than the latest release, use the `--test-version <VERSION_NUM>` flag + with a version number formatted as <A.B.C>. """ @@ -45,6 +59,8 @@ ALL_SNAPS = ['certbot'] + PLUGIN_SNAPS # This is the count of the architectures currently supported by our snaps used # for sanity checking. SNAP_ARCH_COUNT = 3 +SKIP_SYNC_MESSAGE = ('To skip pushing updated branches to GitHub and creating PRs, ' + 'run this script with the `--skip-github-sync` flag.') def parse_args(args): @@ -61,6 +77,12 @@ def parse_args(args): # Use the file's docstring for the help text and don't let argparse reformat it. parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) + parser.add_argument('--test-version', type=str, default=None, + help='version in the form of 1.2.3, mainly for testing') + parser.add_argument('--skip-snaps', action='store_true', + help='don\'t promote snaps; used for testing') + parser.add_argument('--skip-github-sync', action='store_true', + help='don\'t synchronize branches to GitHub or create PRs') return parser.parse_args(args) @@ -171,6 +193,145 @@ def fetch_version_number(): assert len(version.split('.')) == 3 return version + +def _run_silent_except_error(cmd: list[str], message: str = None) -> subprocess.CompletedProcess: + # For some reason, git prints a bunch of non-error output to stderr. Let's keep this script + # quiet by capturing it and only printing it if we hit an error. + try: + process = subprocess.run(cmd, check=True, universal_newlines=True, capture_output=True) + except subprocess.CalledProcessError as e: + print(f'Error running `{" ".join(cmd)}`') + if message is not None: + print(message) + print(e.output) + print(e.stderr) + print(SKIP_SYNC_MESSAGE) + raise e + else: + return process + + +def _create_pr(title: str, body: str, description: str, other_opts: list[str] | None = None) -> str: + cmd = ['gh', 'pr', 'create', '--title', title, '--body', body] + if other_opts is not None: + cmd = cmd + other_opts + try: + proc = subprocess.run(cmd, check=True, universal_newlines=True, capture_output=True) + except subprocess.CalledProcessError as e: + if 'already exists' in e.stderr: + print(f'{description} already exists...skipping creation. ' + 'To create a new PR, delete the old one on GitHub.') + # The error message looks like: + # a pull request for branch "candidate-4.24.0" into branch "main" already exists: + # https://github.com/certbot/certbot/pull/10698 + last_e_word = e.stderr.split()[-1] + if 'https' in last_e_word: + output = last_e_word + else: + print(e.stderr) + print(SKIP_SYNC_MESSAGE) + raise e + else: + output = proc.stdout.rstrip() + return output + + +def _sync_candidate_from_temp_to_origin(version: str) -> None: + command_str = f'git pull temp candidate-{version}' + message = ('To run successfully, stash any changes you\'ve made to this branch. ' + 'Do not attempt to merge and continue, as that will fail.') + _run_silent_except_error(command_str.split(), message) + command_str = f'git push origin candidate-{version}' + message = ('To delete the branch on GitHub, run ' + f'`git push origin --delete candidate-{version}`.') + _run_silent_except_error(command_str.split(), message) + + +def _create_release_pr_to_main(version: str) -> None: + print(f'Creating PR to merge candidate-{version} into main...') + title = f'update files from {version} release' + body = 'this PR only needs 1 review and should be merged, not squashed' + result = _create_pr(title, body, 'PR to merge release changes into main') + print(f'PR location: {result}') + + +def _create_release_pr_to_minor_branch( + version: str, + branch_name:str, + point_x_branch_name: str) -> None: + print(f'Creating PR to merge {branch_name} into {point_x_branch_name}...') + title = f'update files from {version} release' + body = 'this PR only needs 1 review and should be merged, not squashed' + pr_opts = [ '--head', branch_name, + '--base', point_x_branch_name] + result = _create_pr(title, body, 'PR to merge release changes into .x branch', pr_opts) + print(f'PR location: {result}') + + +def _create_and_push_branch_without_version_bump(version: str, branch_name: str) -> None: + # Usually a branch of form 1.2.x + # When it's a point release, it'll be any name, and then merged back into 1.2.x + print(f'Creating branch without version bump commit named {branch_name}...') + # Check if there are uncommited changes, since reset will blow them away + + try: + msg = (f'Branch {branch_name} already exists. Delete it using ' + f'`git branch -D {branch_name}`.') + _run_silent_except_error(f'git branch {branch_name}'.split(), msg) + + _run_silent_except_error(f'git switch {branch_name}'.split()) + + # Make sure the last commit message is 'Bump version to {next version}' + output = _run_silent_except_error('git log -1 --pretty=%B'.split()).stdout + assert_msg = 'The most recent commit message should start with "Bump version to"' + assert output.startswith('Bump version to'), assert_msg + + _run_silent_except_error('git reset --hard HEAD~1'.split()) + + msg = ('You shouldn\'t be trying to re-push a minor version branch. If you really want ' + 'to, go into GitHub, turn off branch deletion protection, and delete it there. ') + _run_silent_except_error(f'git push origin {branch_name}'.split(), msg) + finally: + # Switching to the current branch exits 0 + _run_silent_except_error(f'git switch candidate-{version}'.split()) + print('Created.') + + +def _check_branch_matches_version(version: str) -> None: + # This function assumes we're on a branch like `candidate-1.2.0` or `candidate-1.2.3` + # where the number after candidate should be equal to the version number + process = _run_silent_except_error('git branch --show'.split()) + current_branch = process.stdout.rstrip() + if current_branch != f'candidate-{version}': + print(f'Unexpected branch name found. The current branch should be candidate-{version}.') + print(SKIP_SYNC_MESSAGE) + sys.exit(1) + + +def synchronize_github_repo(version: str): + _check_branch_matches_version(version) + message = ('You have uncommitted changes that will be deleted. ' + 'Stash your changes before rerunning this script.') + _run_silent_except_error('git diff --quiet HEAD'.split(), message) + + _sync_candidate_from_temp_to_origin(version) + _create_release_pr_to_main(version) + + # Check the last element of the version number to see if this is a point release + point_version = version.split('.')[-1] + point_release = point_version != '0' + point_x_branch_name = '.'.join(version.split('.')[:-1]) + '.x' + if not point_release: + branch_name = point_x_branch_name + else: + branch_name = f'point-candidate-{version}' + + _create_and_push_branch_without_version_bump(version, branch_name) + + if point_release: + _create_release_pr_to_minor_branch(version, branch_name, point_x_branch_name) + + def generate_community_forum_post(version: str): print('Generating announcement text for community forum post') @@ -196,8 +357,13 @@ def generate_community_forum_post(version: str): def main(args): parsed_args = parse_args(args) - version = fetch_version_number() - promote_snaps(ALL_SNAPS, 'beta', version) + version = parsed_args.test_version + if not version: + version = fetch_version_number() + if not parsed_args.skip_snaps: + promote_snaps(ALL_SNAPS, 'beta', version) + if not parsed_args.skip_github_sync: + synchronize_github_repo(version) generate_community_forum_post(version) if __name__ == "__main__": diff --git a/tools/requirements.txt b/tools/requirements.txt index 8760aa8ce..2c972e6ec 100644 --- a/tools/requirements.txt +++ b/tools/requirements.txt @@ -90,7 +90,7 @@ matplotlib-inline==0.2.2 ; python_version >= "3.10" and python_version < "4.0" mccabe==0.7.0 ; python_version >= "3.10" and python_version < "4.0" mdurl==0.1.2 ; python_version >= "3.10" and python_version < "4.0" more-itertools==11.1.0 ; python_version >= "3.10" and python_version < "4.0" -msgpack==1.1.2 ; python_version >= "3.10" and python_version < "4.0" +msgpack==1.2.1 ; python_version >= "3.10" and python_version < "4.0" mypy-extensions==1.1.0 ; python_version >= "3.10" and python_version < "4.0" mypy==1.9.0 ; python_version >= "3.10" and python_version < "4.0" nh3==0.3.5 ; python_version >= "3.10" and python_version < "4.0" diff --git a/tools/snap/build_remote.py b/tools/snap/build_remote.py index 5ed9f0e05..ba6f562eb 100755 --- a/tools/snap/build_remote.py +++ b/tools/snap/build_remote.py @@ -144,14 +144,17 @@ def _build_snap( for arch in archs: snap_path_list = glob.glob(join(workspace, f'{target}_*_{arch}.snap')) assert len(snap_path_list) == 1 - with open(snap_path_list[0], 'r') as f: + with open(snap_path_list[0], 'rb') as f: + first_block = f.read(10) + # 'hsqs' is the magic number that SquashFS files start with + if first_block.startswith(b'hsqs'): + continue + failed_archs.add(arch) try: - first_line = f.readline().rstrip() + first_block_str = first_block.decode() except UnicodeDecodeError: - first_line = '' - if first_line == "<!DOCTYPE html>": - failed_archs.add(arch) - print(f'The {target} {arch} snap file contains html instead of a snap') + first_block_str = first_block.hex(sep=',') + print(f'The {target} {arch} snap file began with invalid data: {first_block_str}') dump_output = bool(failed_archs) if not dump_output: