scriptworker 63.0.0__tar.gz → 63.0.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. {scriptworker-63.0.0 → scriptworker-63.0.1}/HISTORY.rst +7 -0
  2. {scriptworker-63.0.0 → scriptworker-63.0.1}/PKG-INFO +1 -1
  3. {scriptworker-63.0.0 → scriptworker-63.0.1}/pyproject.toml +1 -1
  4. {scriptworker-63.0.0 → scriptworker-63.0.1}/src/scriptworker/utils.py +16 -6
  5. {scriptworker-63.0.0 → scriptworker-63.0.1}/tox.ini +1 -0
  6. {scriptworker-63.0.0 → scriptworker-63.0.1}/.gitignore +0 -0
  7. {scriptworker-63.0.0 → scriptworker-63.0.1}/CONTRIBUTING.rst +0 -0
  8. {scriptworker-63.0.0 → scriptworker-63.0.1}/LICENSE +0 -0
  9. {scriptworker-63.0.0 → scriptworker-63.0.1}/README.rst +0 -0
  10. {scriptworker-63.0.0 → scriptworker-63.0.1}/renovate.json +0 -0
  11. {scriptworker-63.0.0 → scriptworker-63.0.1}/scripts/gen_ed25519_key.py +0 -0
  12. {scriptworker-63.0.0 → scriptworker-63.0.1}/scriptworker.yaml.tmpl +0 -0
  13. {scriptworker-63.0.0 → scriptworker-63.0.1}/src/scriptworker/__init__.py +0 -0
  14. {scriptworker-63.0.0 → scriptworker-63.0.1}/src/scriptworker/artifacts.py +0 -0
  15. {scriptworker-63.0.0 → scriptworker-63.0.1}/src/scriptworker/client.py +0 -0
  16. {scriptworker-63.0.0 → scriptworker-63.0.1}/src/scriptworker/config.py +0 -0
  17. {scriptworker-63.0.0 → scriptworker-63.0.1}/src/scriptworker/constants.py +0 -0
  18. {scriptworker-63.0.0 → scriptworker-63.0.1}/src/scriptworker/context.py +0 -0
  19. {scriptworker-63.0.0 → scriptworker-63.0.1}/src/scriptworker/cot/__init__.py +0 -0
  20. {scriptworker-63.0.0 → scriptworker-63.0.1}/src/scriptworker/cot/generate.py +0 -0
  21. {scriptworker-63.0.0 → scriptworker-63.0.1}/src/scriptworker/cot/verify.py +0 -0
  22. {scriptworker-63.0.0 → scriptworker-63.0.1}/src/scriptworker/data/cot_v1_schema.json +0 -0
  23. {scriptworker-63.0.0 → scriptworker-63.0.1}/src/scriptworker/data/scriptworker_task_schema.json +0 -0
  24. {scriptworker-63.0.0 → scriptworker-63.0.1}/src/scriptworker/ed25519.py +0 -0
  25. {scriptworker-63.0.0 → scriptworker-63.0.1}/src/scriptworker/exceptions.py +0 -0
  26. {scriptworker-63.0.0 → scriptworker-63.0.1}/src/scriptworker/github.py +0 -0
  27. {scriptworker-63.0.0 → scriptworker-63.0.1}/src/scriptworker/log.py +0 -0
  28. {scriptworker-63.0.0 → scriptworker-63.0.1}/src/scriptworker/task.py +0 -0
  29. {scriptworker-63.0.0 → scriptworker-63.0.1}/src/scriptworker/task_process.py +0 -0
  30. {scriptworker-63.0.0 → scriptworker-63.0.1}/src/scriptworker/worker.py +0 -0
@@ -4,6 +4,13 @@ Change Log
4
4
  All notable changes to this project will be documented in this file.
5
5
  This project adheres to `Semantic Versioning <http://semver.org/>`__.
6
6
 
7
+ 63.0.1 - 2026-04-27
8
+
9
+ Fixed
10
+ ~~~~~
11
+
12
+ - File corruption caused by parallel downloads (#792)
13
+
7
14
  63.0.0 - 2026-04-09
8
15
  -------------------
9
16
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: scriptworker
3
- Version: 63.0.0
3
+ Version: 63.0.1
4
4
  Summary: Taskcluster scriptworker
5
5
  Author-email: Mozilla Release Engineering <releng@mozilla.com>
6
6
  License-File: LICENSE
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "scriptworker"
3
- version = "63.0.0"
3
+ version = "63.0.1"
4
4
  description = "Taskcluster scriptworker"
5
5
  authors = [
6
6
  { name = "Mozilla Release Engineering", email = "releng@mozilla.com" },
@@ -16,6 +16,7 @@ import random
16
16
  import re
17
17
  import shutil
18
18
  import time
19
+ import uuid
19
20
  from copy import deepcopy
20
21
  from typing import IO, TYPE_CHECKING, Any, Awaitable, Callable, Dict, Match, Optional, Sequence, Tuple, Type, Union, cast, overload # noqa
21
22
  from urllib.parse import unquote, urlparse
@@ -680,12 +681,21 @@ async def download_file(context, url, abs_filename, session=None, chunk_size=128
680
681
  await _log_download_error(resp, "Failed to download %(url)s: %(status)s; body=%(body)s")
681
682
  raise DownloadError("{} status {} is not 200!".format(loggable_url, resp.status))
682
683
  makedirs(parent_dir)
683
- with open(abs_filename, "wb") as fd:
684
- while True:
685
- chunk = await resp.content.read(chunk_size)
686
- if not chunk:
687
- break
688
- fd.write(chunk)
684
+ tmp_filename = "{}.{}.part".format(abs_filename, uuid.uuid4().hex)
685
+ try:
686
+ with open(tmp_filename, "wb") as fd:
687
+ while True:
688
+ chunk = await resp.content.read(chunk_size)
689
+ if not chunk:
690
+ break
691
+ fd.write(chunk)
692
+ os.replace(tmp_filename, abs_filename)
693
+ except Exception:
694
+ try:
695
+ os.unlink(tmp_filename)
696
+ except OSError:
697
+ pass
698
+ raise
689
699
  log.info("Done")
690
700
 
691
701
 
@@ -66,6 +66,7 @@ commands =
66
66
 
67
67
  [flake8]
68
68
  max-line-length = 160
69
+ extend-ignore = E203
69
70
  # test_github.py ignored because of https://gitlab.com/pycqa/flake8/issues/375
70
71
  exclude = .ropeproject,.tox,sandbox,docs,.eggs,*.egg,*.egg-info,setup.py,build/,tests/test_github.py,.venv
71
72
  per-file-ignores =
File without changes
File without changes
File without changes