You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by ru...@apache.org on 2023/12/14 16:48:59 UTC

(superset) 01/01: feat(releasing): adding a SHA512 and

This is an automated email from the ASF dual-hosted git repository.

rusackas pushed a commit to branch release-validator-script
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 93156b20804befeedc742435db60826c4cce78da
Author: Evan Rusackas <ev...@rusackas.com>
AuthorDate: Thu Dec 14 09:48:46 2023 -0700

    feat(releasing): adding a SHA512 and
---
 RELEASING/README.md         | 14 +++++++
 RELEASING/verify_release.py | 91 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 105 insertions(+)

diff --git a/RELEASING/README.md b/RELEASING/README.md
index b007a89170..0f2668ddf1 100644
--- a/RELEASING/README.md
+++ b/RELEASING/README.md
@@ -388,8 +388,22 @@ The script will generate the email text that should be sent to dev@superset.apac
 
 ## Validating a release
 
+Official instructions:
 https://www.apache.org/info/verification.html
 
+We now have a handy script for anyone validating a release to use. It's in this very folder, `verify_release.py`
+
+Just make sure you have all three release files in the directory (`{some version}.tar.gz`, `{some version}.tar.gz.asc` and `{some version}tar.gz.sha512`). Then run the script with the path to the `.tar.gz` file like so:
+
+`python verify_release.py ~/path/tp/apache-superset-{version/candidate}-source.tar.gz`
+
+If all goes well, you will see this result in your terminal:
+
+```bash
+SHA-512 verified
+RSA key verified
+```
+
 ## Publishing a successful release
 
 Upon a successful vote, you'll have to copy the folder into the non-"dev/" folder.
diff --git a/RELEASING/verify_release.py b/RELEASING/verify_release.py
new file mode 100644
index 0000000000..c49f8230ba
--- /dev/null
+++ b/RELEASING/verify_release.py
@@ -0,0 +1,91 @@
+import subprocess
+import sys
+import re
+import requests
+
+# Part 1: Verify SHA512 hash - this is the same as running `shasum -a 512 {release}` and comparing it against `{release}.sha512`
+
+def get_sha512_hash(filename):
+    """Run the shasum command on the file and return the SHA512 hash."""
+    result = subprocess.run(['shasum', '-a', '512', filename], stdout=subprocess.PIPE)
+    sha512_hash = result.stdout.decode().split()[0]
+    return sha512_hash
+
+def read_sha512_file(filename):
+    """Read the corresponding .sha512 file and process its contents."""
+    sha_filename = filename + '.sha512'
+    with open(sha_filename, 'r') as file:
+        lines = file.readlines()
+        processed_sha = ''.join(lines[1:]).replace(' ', '').replace('\n', '').lower()
+    return processed_sha
+
+def verify_sha512(filename):
+    """Verify if the SHA512 hash of the file matches with the hash in the .sha512 file."""
+    sha512_hash = get_sha512_hash(filename)
+    sha512_file_content = read_sha512_file(filename)
+
+    if sha512_hash == sha512_file_content:
+        return "SHA verified"
+    else:
+        return "SHA failed"
+
+# Part 2: Verify RSA key - this is the same as running `gpg --verify {release}.asc {release}` and comparing the RSA key and email address against the KEYS file
+
+def get_gpg_info(filename):
+    """Run the GPG verify command and extract RSA key and email address."""
+    asc_filename = filename + '.asc'
+    result = subprocess.run(['gpg', '--verify', asc_filename, filename], stderr=subprocess.PIPE, stdout=subprocess.PIPE)
+    output = result.stderr.decode()
+
+    rsa_key = re.search(r'RSA key ([0-9A-F]+)', output)
+    email = re.search(r'issuer "([^"]+)"', output)
+
+    rsa_key_result = rsa_key.group(1) if rsa_key else None
+    email_result = email.group(1) if email else None
+
+    # Debugging: print warnings if rsa_key or email is not found
+    if rsa_key_result is None:
+        print("Warning: No RSA key found in GPG verification output.")
+    if email_result is None:
+        print("Warning: No email address found in GPG verification output.")
+
+    return rsa_key_result, email_result
+
+
+def verify_rsa_key(rsa_key, email):
+    """Fetch the KEYS file and verify if the RSA key and email match."""
+    url = 'https://downloads.apache.org/superset/KEYS'
+    response = requests.get(url)
+    if response.status_code == 200:
+        if rsa_key not in response.text:
+            return "RSA key not found on KEYS page"
+
+        # Check if email is None or not in response.text
+        if email and email in response.text:
+            return "RSA key and email verified against Apache KEYS file"
+        elif email:
+            return "RSA key verified, but Email not found on KEYS page"
+        else:
+            return "RSA key verified, but Email not available for verification"
+    else:
+        return "Failed to fetch KEYS file"
+
+
+def verify_sha512_and_rsa(filename):
+    """Verify SHA512 hash and RSA key."""
+    sha_result = verify_sha512(filename)
+    print(sha_result)
+
+    rsa_key, email = get_gpg_info(filename)
+    if rsa_key:
+        rsa_result = verify_rsa_key(rsa_key, email)
+        print(rsa_result)
+    else:
+        print("GPG verification failed: RSA key or email not found")
+
+if __name__ == "__main__":
+    if len(sys.argv) != 2:
+        print("Usage: python script.py <filename>")
+    else:
+        filename = sys.argv[1]
+        verify_sha512_and_rsa(filename)