Browse Source

Generate and upload checksums for released ZIPs to GitHub

When generating an Electron release, create a `sha256sum`-compatible
file for each ZIP file, and upload them to the corresponding GitHub release.
This is primarily to confirm that the download of a given ZIP completed
successfully, as opposed to verifying that an Electron team member uploaded
the given ZIP files (which would require using a trusted GPG key).
Mark Lee 8 years ago
parent
commit
5b07154b8e
2 changed files with 29 additions and 6 deletions
  1. 14 0
      script/lib/util.py
  2. 15 6
      script/upload.py

+ 14 - 0
script/lib/util.py

@@ -3,6 +3,7 @@
 import atexit
 import contextlib
 import errno
+import hashlib
 import platform
 import re
 import shutil
@@ -129,6 +130,19 @@ def make_zip(zip_file_path, files, dirs):
         for f in filenames:
           zip_file.write(os.path.join(root, f))
     zip_file.close()
+  make_zip_sha256_checksum(zip_file_path)
+
+
+def make_zip_sha256_checksum(zip_file_path):
+  checksum_path = '{}.sha256sum'.format(zip_file_path)
+  safe_unlink(checksum_path)
+  sha256 = hashlib.sha256()
+  with open(zip_file_path, 'rb') as f:
+    sha256.update(f.read())
+
+  zip_basename = os.path.basename(zip_file_path)
+  with open(checksum_path, 'w') as checksum:
+    checksum.write('{} *{}'.format(sha256.hexdigest(), zip_basename))
 
 
 def rm_rf(path):

+ 15 - 6
script/upload.py

@@ -203,20 +203,29 @@ def create_release_draft(github, tag):
 
 
 def upload_electron(github, release, file_path):
-  # Delete the original file before uploading in CI.
+  checksum_path = '{}.sha256sum'.format(file_path)
+  # Delete the original file & its checksum before uploading in CI.
+  filename = os.path.basename(file_path)
+  checksum_filename = os.path.basename(checksum_path)
   if os.environ.has_key('CI'):
     try:
       for asset in release['assets']:
-        if asset['name'] == os.path.basename(file_path):
+        if asset['name'] in [filename, checksum_filename]:
           github.repos(ELECTRON_REPO).releases.assets(asset['id']).delete()
-          break
     except Exception:
       pass
 
   # Upload the file.
-  params = {'name': os.path.basename(file_path)}
-  headers = {'Content-Type': 'application/zip'}
-  with open(file_path, 'rb') as f:
+  upload_asset_to_github(github, release, file_path, 'application/zip')
+
+  # Upload the file's checksum.
+  upload_asset_to_github(github, release, checksum_path, 'text/plain')
+
+
+def upload_asset_to_github(github, release, asset_path, content_type):
+  params = {'name': os.path.dirname(asset_path)}
+  headers = {'Content-Type': content_type}
+  with open(asset_path) as f:
     github.repos(ELECTRON_REPO).releases(release['id']).assets.post(
         params=params, headers=headers, data=f, verify=False)