GitHub Actions workflow for Windows EXE
This commit is contained in:
parent
b2acbcf0e0
commit
dc289024c8
47
.github/workflows/windows_exe.yml
vendored
Normal file
47
.github/workflows/windows_exe.yml
vendored
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
name: Windows EXE build
|
||||||
|
|
||||||
|
on: [push, pull_request]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: windows-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout Instaloader repository
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
- name: Setup Python
|
||||||
|
uses: actions/setup-python@v1
|
||||||
|
with:
|
||||||
|
python-version: 3.8
|
||||||
|
architecture: x64
|
||||||
|
- name: Get the tagged version
|
||||||
|
id: get_version
|
||||||
|
env:
|
||||||
|
GITHUB_REF: ${{ github.ref }}
|
||||||
|
run: echo ::set-output name=VERSION::${GITHUB_REF/refs\/tags\/v/}
|
||||||
|
shell: bash
|
||||||
|
- name: Run custom python script for EXE creation
|
||||||
|
env:
|
||||||
|
VERSION_TAG: v${{ steps.get_version.outputs.VERSION }}
|
||||||
|
run: python deploy/windows/create_exe.py
|
||||||
|
- name: Create draft release
|
||||||
|
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
|
||||||
|
id: create_release
|
||||||
|
uses: actions/create-release@v1
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
with:
|
||||||
|
tag_name: v${{ steps.get_version.outputs.VERSION }}
|
||||||
|
release_name: Version ${{ steps.get_version.outputs.VERSION }}
|
||||||
|
draft: true
|
||||||
|
prerelease: contains(steps.get_version.outputs.VERSION, 'a') || contains(steps.get_version.outputs.VERSION, 'b') || contains(steps.get_version.outputs.VERSION, 'c')
|
||||||
|
- name: Upload EXE as release asset
|
||||||
|
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
|
||||||
|
id: upload-release-asset
|
||||||
|
uses: actions/upload-release-asset@v1
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
with:
|
||||||
|
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||||
|
asset_path: ./instaloader-v${{ steps.get_version.outputs.VERSION }}-windows-standalone.zip
|
||||||
|
asset_name: instaloader-v${{ steps.get_version.outputs.VERSION }}-windows-standalone.zip
|
||||||
|
asset_content_type: application/zip
|
4
Pipfile
4
Pipfile
@ -7,6 +7,10 @@ verify_ssl = true
|
|||||||
pylint = "*"
|
pylint = "*"
|
||||||
mypy = "*"
|
mypy = "*"
|
||||||
sphinx = "*"
|
sphinx = "*"
|
||||||
|
pyinstaller = "*"
|
||||||
|
pefile = "*"
|
||||||
|
pywin32-ctypes = "*"
|
||||||
|
psutil = "*"
|
||||||
|
|
||||||
[packages]
|
[packages]
|
||||||
requests = "*"
|
requests = "*"
|
||||||
|
60
Pipfile.lock
generated
60
Pipfile.lock
generated
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"_meta": {
|
"_meta": {
|
||||||
"hash": {
|
"hash": {
|
||||||
"sha256": "dfbaa1642735b07bdcc118cb0c9328817b1d558af626b696593db099df863b39"
|
"sha256": "33408a60fda1a56bf680462fad21643ae0159bc13f3b85d8f10ebf3eef7d8725"
|
||||||
},
|
},
|
||||||
"pipfile-spec": 6,
|
"pipfile-spec": 6,
|
||||||
"requires": {},
|
"requires": {},
|
||||||
@ -59,6 +59,13 @@
|
|||||||
],
|
],
|
||||||
"version": "==0.7.12"
|
"version": "==0.7.12"
|
||||||
},
|
},
|
||||||
|
"altgraph": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:1f05a47122542f97028caf78775a095fbe6a2699b5089de8477eb583167d69aa",
|
||||||
|
"sha256:c623e5f3408ca61d4016f23a681b9adb100802ca3e3da5e718915a9e4052cebe"
|
||||||
|
],
|
||||||
|
"version": "==0.17"
|
||||||
|
},
|
||||||
"astroid": {
|
"astroid": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:71ea07f44df9568a75d0f354c49143a4575d90645e9fead6dfb52c26a85ed13a",
|
"sha256:71ea07f44df9568a75d0f354c49143a4575d90645e9fead6dfb52c26a85ed13a",
|
||||||
@ -94,6 +101,12 @@
|
|||||||
],
|
],
|
||||||
"version": "==0.16"
|
"version": "==0.16"
|
||||||
},
|
},
|
||||||
|
"future": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:b1bead90b70cf6ec3f0710ae53a525360fa360d306a86583adc6bf83a4db537d"
|
||||||
|
],
|
||||||
|
"version": "==0.18.2"
|
||||||
|
},
|
||||||
"idna": {
|
"idna": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407",
|
"sha256:c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407",
|
||||||
@ -117,10 +130,10 @@
|
|||||||
},
|
},
|
||||||
"jinja2": {
|
"jinja2": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:74320bb91f31270f9551d46522e33af46a80c3d619f4a4bf42b3164d30b5911f",
|
"sha256:93187ffbc7808079673ef52771baa950426fd664d3aad1d0fa3e95644360e250",
|
||||||
"sha256:9fe95f19286cfefaa917656583d020be14e7859c6b0252588391e47db34527de"
|
"sha256:b0eaf100007721b5c16c1fc1eecb87409464edc10469ddc9a22a27a99123be49"
|
||||||
],
|
],
|
||||||
"version": "==2.10.3"
|
"version": "==2.11.1"
|
||||||
},
|
},
|
||||||
"lazy-object-proxy": {
|
"lazy-object-proxy": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
@ -227,6 +240,30 @@
|
|||||||
],
|
],
|
||||||
"version": "==20.1"
|
"version": "==20.1"
|
||||||
},
|
},
|
||||||
|
"pefile": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:a5d6e8305c6b210849b47a6174ddf9c452b2888340b8177874b862ba6c207645"
|
||||||
|
],
|
||||||
|
"index": "pypi",
|
||||||
|
"version": "==2019.4.18"
|
||||||
|
},
|
||||||
|
"psutil": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:094f899ac3ef72422b7e00411b4ed174e3c5a2e04c267db6643937ddba67a05b",
|
||||||
|
"sha256:10b7f75cc8bd676cfc6fa40cd7d5c25b3f45a0e06d43becd7c2d2871cbb5e806",
|
||||||
|
"sha256:1b1575240ca9a90b437e5a40db662acd87bbf181f6aa02f0204978737b913c6b",
|
||||||
|
"sha256:21231ef1c1a89728e29b98a885b8e0a8e00d09018f6da5cdc1f43f988471a995",
|
||||||
|
"sha256:28f771129bfee9fc6b63d83a15d857663bbdcae3828e1cb926e91320a9b5b5cd",
|
||||||
|
"sha256:70387772f84fa5c3bb6a106915a2445e20ac8f9821c5914d7cbde148f4d7ff73",
|
||||||
|
"sha256:b560f5cd86cf8df7bcd258a851ca1ad98f0d5b8b98748e877a0aec4e9032b465",
|
||||||
|
"sha256:b74b43fecce384a57094a83d2778cdfc2e2d9a6afaadd1ebecb2e75e0d34e10d",
|
||||||
|
"sha256:e85f727ffb21539849e6012f47b12f6dd4c44965e56591d8dec6e8bc9ab96f4a",
|
||||||
|
"sha256:fd2e09bb593ad9bdd7429e779699d2d47c1268cbde4dda95fcd1bd17544a0217",
|
||||||
|
"sha256:ffad8eb2ac614518bbe3c0b8eb9dffdb3a8d2e3a7d5da51c5b974fb723a5c5aa"
|
||||||
|
],
|
||||||
|
"index": "pypi",
|
||||||
|
"version": "==5.6.7"
|
||||||
|
},
|
||||||
"pygments": {
|
"pygments": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:2a3fe295e54a20164a9df49c75fa58526d3be48e14aceba6d6b1e8ac0bfd6f1b",
|
"sha256:2a3fe295e54a20164a9df49c75fa58526d3be48e14aceba6d6b1e8ac0bfd6f1b",
|
||||||
@ -234,6 +271,13 @@
|
|||||||
],
|
],
|
||||||
"version": "==2.5.2"
|
"version": "==2.5.2"
|
||||||
},
|
},
|
||||||
|
"pyinstaller": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:3730fa80d088f8bb7084d32480eb87cbb4ddb64123363763cf8f2a1378c1c4b7"
|
||||||
|
],
|
||||||
|
"index": "pypi",
|
||||||
|
"version": "==3.6"
|
||||||
|
},
|
||||||
"pylint": {
|
"pylint": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:3db5468ad013380e987410a8d6956226963aed94ecb5f9d3a28acca6d9ac36cd",
|
"sha256:3db5468ad013380e987410a8d6956226963aed94ecb5f9d3a28acca6d9ac36cd",
|
||||||
@ -256,6 +300,14 @@
|
|||||||
],
|
],
|
||||||
"version": "==2019.3"
|
"version": "==2019.3"
|
||||||
},
|
},
|
||||||
|
"pywin32-ctypes": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:24ffc3b341d457d48e8922352130cf2644024a4ff09762a2261fd34c36ee5942",
|
||||||
|
"sha256:9dc2d991b3479cc2df15930958b674a48a227d5361d413827a4cfd0b5876fc98"
|
||||||
|
],
|
||||||
|
"index": "pypi",
|
||||||
|
"version": "==0.2.0"
|
||||||
|
},
|
||||||
"requests": {
|
"requests": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:11e007a8a2aa0323f5a921e9e6a2d7e4e67d9877e85773fba9ba6419025cbeb4",
|
"sha256:11e007a8a2aa0323f5a921e9e6a2d7e4e67d9877e85773fba9ba6419025cbeb4",
|
||||||
|
86
deploy/windows/create_exe.py
Normal file
86
deploy/windows/create_exe.py
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
import hashlib
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import shutil
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
|
||||||
|
# copy the required files into repo root
|
||||||
|
shutil.copy('docs/favicon.ico', '.')
|
||||||
|
shutil.copy('deploy/windows/instaloader.spec', '.')
|
||||||
|
shutil.unpack_archive('deploy/windows/ps', '.', 'xztar')
|
||||||
|
|
||||||
|
code = """
|
||||||
|
import psutil
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
def __main():
|
||||||
|
grandparentpid = psutil.Process(os.getppid()).ppid()
|
||||||
|
grandparentpidsearchstring = ' ' + str(grandparentpid) + ' '
|
||||||
|
if hasattr(sys, "_MEIPASS"):
|
||||||
|
ps = os.path.join(sys._MEIPASS, 'tasklist.exe')
|
||||||
|
else:
|
||||||
|
ps = 'tasklist'
|
||||||
|
popen = subprocess.Popen(ps, stdout=subprocess.PIPE, universal_newlines=True)
|
||||||
|
for examine in iter(popen.stdout.readline, ""):
|
||||||
|
if grandparentpidsearchstring in examine:
|
||||||
|
pname = examine
|
||||||
|
break
|
||||||
|
popen.stdout.close()
|
||||||
|
return_code = popen.wait()
|
||||||
|
if return_code:
|
||||||
|
raise subprocess.CalledProcessError(return_code, ps)
|
||||||
|
if pname[0:12] == 'explorer.exe':
|
||||||
|
subprocess.Popen("cmd /K \\\"{0}\\\"".format(os.path.splitext(os.path.basename(sys.argv[0]))[0]))
|
||||||
|
else:
|
||||||
|
main()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
__main()
|
||||||
|
"""
|
||||||
|
|
||||||
|
with open('instaloader/__main__.py', 'r') as f:
|
||||||
|
# adjust imports for changed file structure
|
||||||
|
regex = re.compile(r'from (?:(\.[^ ]+ )|\.( ))import')
|
||||||
|
lines = [regex.sub(r'from instaloader\1\2import', line) for line in f.readlines()]
|
||||||
|
|
||||||
|
# insert code for magic exe behavior
|
||||||
|
index = lines.index('if __name__ == "__main__":\n')
|
||||||
|
code_lines = [cl + '\n' for cl in code.splitlines()]
|
||||||
|
for i, code_line in enumerate(code_lines):
|
||||||
|
if i + index < len(lines):
|
||||||
|
lines[i + index] = code_line
|
||||||
|
else:
|
||||||
|
lines.extend(code_lines[i:])
|
||||||
|
break
|
||||||
|
|
||||||
|
with open('__main__.py', 'w+') as f:
|
||||||
|
f.writelines(lines)
|
||||||
|
|
||||||
|
# install dependencies and invoke PyInstaller
|
||||||
|
commands = ["pip install pipenv==2018.11.26",
|
||||||
|
"pipenv sync --dev",
|
||||||
|
"pipenv run pyinstaller --log-level=DEBUG instaloader.spec"]
|
||||||
|
|
||||||
|
for command in commands:
|
||||||
|
print()
|
||||||
|
print('#' * (len(command) + 6))
|
||||||
|
print('## {} ##'.format(command))
|
||||||
|
print('#' * (len(command) + 6))
|
||||||
|
print(flush=True)
|
||||||
|
err = subprocess.Popen(command).wait()
|
||||||
|
if err != 0:
|
||||||
|
sys.exit(err)
|
||||||
|
|
||||||
|
# calculate and store MD5 hash for created executable
|
||||||
|
hash_md5 = hashlib.md5()
|
||||||
|
with open('dist/instaloader.exe', 'rb') as f:
|
||||||
|
for chunk in iter(lambda: f.read(4096), b''):
|
||||||
|
hash_md5.update(chunk)
|
||||||
|
|
||||||
|
with open('dist/instaloader.exe.md5', 'w+') as f:
|
||||||
|
f.write('{} *instaloader.exe\n'.format(hash_md5.hexdigest()))
|
||||||
|
|
||||||
|
# Create ZIP file
|
||||||
|
shutil.make_archive('instaloader-{}-windows-standalone'.format(os.getenv('VERSION_TAG')), 'zip', 'dist')
|
28
deploy/windows/instaloader.spec
Normal file
28
deploy/windows/instaloader.spec
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
# -*- mode: python -*-
|
||||||
|
|
||||||
|
block_cipher = None
|
||||||
|
|
||||||
|
|
||||||
|
a = Analysis(['__main__.py'],
|
||||||
|
binaries=[],
|
||||||
|
datas=[('tasklist.exe', '.'), ('framedyn.dll', '.')],
|
||||||
|
hiddenimports=[],
|
||||||
|
hookspath=[],
|
||||||
|
runtime_hooks=[],
|
||||||
|
excludes=[],
|
||||||
|
win_no_prefer_redirects=False,
|
||||||
|
win_private_assemblies=False,
|
||||||
|
cipher=block_cipher)
|
||||||
|
pyz = PYZ(a.pure, a.zipped_data,
|
||||||
|
cipher=block_cipher)
|
||||||
|
exe = EXE(pyz,
|
||||||
|
a.scripts,
|
||||||
|
a.binaries,
|
||||||
|
a.zipfiles,
|
||||||
|
a.datas,
|
||||||
|
name='instaloader',
|
||||||
|
debug=False,
|
||||||
|
strip=False,
|
||||||
|
upx=False,
|
||||||
|
runtime_tmpdir=None,
|
||||||
|
console=True , icon='favicon.ico')
|
BIN
deploy/windows/ps
Normal file
BIN
deploy/windows/ps
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user