Builds can, and must in normal operation be run automatically from GitHub Actions. For more information on that process see Automatic Builds. This allows us to state that the files we distribute never touched anything but GitHub servers before a user downloaded them, which means no possibility of malware on a developer's machine infecting the resulting files.
Obviously you might still need to run a manual build on your own hardware in order to test changes and/or diagnose build issues. As such this document aims to enable anyone to quickly get up to speed on how to:
- Build a Windows .exe for the application
- Package that .exe into an .msi file for distribution
- Handle the files generated so the application automatically detects new available versions and asks the user to upgrade.
Note that for Windows only a 32-bit application is supported at this time.
This is principally due to the Windows Registry handling in
config/windows.py
.
You will need several pieces of software installed, or the files from their .zip archives, in order to build the .exe and generate the .msi
-
WinSparkle:
winsparkle.dll
andwinsparkle.pdb
from the release's .zip file. v0.7.0 is the most recently tested version. Copy the two files, found at<zip file>\<version>\Release
, into your checkout of the EDMC git files. -
Windows SDK. This is needed for the internationalisation support in EDMC. Windows 10 SDK, version 2004 (10.0.19041.0) is the most recently tested version. Technically you only need the following components:
MSI Tools
,Windows SDK for Desktop C++ x86 Apps
(which will auto-select some others). NB: If you have need to uninstall this it's "Windows Software Development Kit - Windows 10.0.19041.1" in "Apps & Features", not "Windows SDK AddOn". -
Python: 32-bit version of Python 3.10 for Windows. v3.10.3 is the most recently tested version. You need the
Windows x86 executable installer
file, for the 32-bit version. Double-check the version against the.python.version
file, as it should always contain the intended version. -
py2exe - Now available via PyPi, so will be picked up with the
pip install
below. Latest tested as perrequirements-dev.txt
. -
You'll now need to 'pip install' several python modules.
- Ensure you have
pip
installed. If needs be see Installing pip - The easiest way is to utilise the
requirements-dev.txt
file:python -m pip install --user -r requirements-dev.txt
. This will install all dependencies plus anything required for development. - Else check the contents of both
requirements.txt
andrequirements-dev.txt
, and ensure the modules listed there are installed as per the version requirements.
- Ensure you have
If you are using different versions of any of these tools then please ensure
that the paths where they're installed match the associated lines in
build.py
. i.e. if you're using later Windows SDK kit you might need to edit
the SDKPATH line.
This project now uses strict Semantic Version version strings.
-
Version strings should always be referred to as, e.g.
Major.Minor.Patch
not the oldA.BC
scheme, nor the pre-Semantic VersionA.B.C.D
scheme. -
Any stable release should have a version of only
Major.Minor.Patch
, correctly incrementing depending on the changes since the last stable release. -
For any pre-release again increment the
Major.Minor.Patch
as fits the changes since the last stable release. -
Any pre-release should have a component of either:
-beta<serial>
, i.e.-beta1
. This should be used when first asking a wider audience to test forthcoming changes.-rc<serial>
, i.e.-rc1
. This is used when testing has shown this code should be ready for full release, but you want even wider testing.
In both these cases simply increment
<serial>
for each new release. Do start from1
again when beginning-rc
releases.
There are some things that you should always change before running your own version of EDMC
- The Frontier CAPI client ID. This is hardcoded in companion.py, but can be overridden by setting a CLIENT_ID environment variable.
There are other things that you should probably change, but can get away with leaving at the upstream values, especially if you only you are going to use the resulting .exe and/or .msi files. But realise that the resulting program will still try to check for new versions at the main URL unless you change that.
-
Company is set in
build.py
. Search forcompany_name
. This is what appears in the EXE properties, and is also used as the location of WinSparkle registry entries on Windows. -
Application names, version and URL of the file with latest release information. These are all in the
config/__init__.py
file. See thefrom config import ...
lines inbuild.py
:appname
: The short appname, e.g. 'EDMarketConnector'applongname
: The long appname, e.g. 'E:D Market Connector'appcmdname
: The CLI appname, e.g. 'EDMC'_static_appversion
: The current version, e.g.4.0.2
. You MUST make this something like4.0.2+<myversion>
to differentiate it from upstream. Whatever is in this field is what will be reported if sending messages to EDDN, or any of the third-party website APIs. This is utilising the 'build metadata' part of a Semantic version.copyright
: The Copyright string.update_feed
: The URL where the application looks for current latest version information. This URL should be hosting a renamed (so the full URL doesn't change over application versions) version of the appcast_win_.xml file. The original upstream value ishttps://raw.githubusercontent.com/EDCD/EDMarketConnector/releases/edmarketconnector.xml
.
-
Location of release files. This needs to be cited correctly in the
edmarketconnector.xml
file, which is what the application queries to see if there is a newer version. Look for theurl="...
line in the<enclosure ...
that is like:<enclosure url="https://github.com/EDCD/EDMarketConnector/releases/download/Release/4.2.3/EDMarketConnector_win_4.2.3.msi" sparkle:os="windows" sparkle:installerArguments="/passive LAUNCH=yes" sparkle:version="4.2.3" length="11382784" type="application/octet-stream" />
If you add a new file to the program that needs to be distributed to users as well then you will need to properly add it to the build process.
You'll need to add it in build.py
so that py2exe includes it in
the build. Add the file to the DATA_FILES statement.
Before you create a new install each time you should:
- Ensure the data sourced from coriolis.io is up to date and works:
- Update the
coriolis-data
repo. NB: You will need 'npm' installed for this.cd coriolis-data
git pull
npm install
- to check it's worked.
- Run
coriolis-update-files.py
to updatemodules.json
andships.json
. NB: The submodule might have been updated by a GitHub workflow/PR/merge, so be sure to perform this step for every build. - XXX: Test ?
git commit
the changes to the repo and the.p
files.- Ensure translations are up to date, see Translations.md.
We'll use an old version string, 4.0.2
, as an example throughout the
following.
-
You should by this time know what changes are going into the release, and which branch (stable or beta) you'll be ultimately updating.
-
So as to make backing out any mistakes easier create a new branch for this release, using a name like
release-4.0.2
. Do not use the tagRelease/4.0.2
form, that could cause confusion.git checkout stable
# Or whichever other branch is appropriate.git pull origin
# Ensures local branch is up to date.git checkout -b release-4.0.2
-
Get all the relevant code changes into this branch. This might mean merging from another branch, such as an issue-specific one, or possibly cherry-picking commits. See Contributing Guidelines for how such branches should be named.
-
You should have already decided on the new Version String, as it's specified in
config/__init__.py
. You'll need to redo the.msi
build if you forgot. Remember to do a fresh git commit for this change. -
Prepare a changelog text for the release. You'll need this both for the GitHub release and the contents of the
edmarketconnector.xml
file if making astable
release, as well as any social media posts you make.- The primary location of the changelog is Changelog.md - update this first.
- To be sure you include all the changes look at the git log since the prior appropriate (pre-)release.
- As you're working in a version-specific branch,
release-4.0.2
, you can safely commit these changes and push to GitHub. Do not merge the branch withreleases
until the GitHub release is in place.
If you're wondering, you needed to get the changelog prepared before building the .exe and .msi because ChangeLog.md is bundled with the install.
If anything in this new release addresses a bug that causes, e.g. bad data
to be sent over EDDN, then you should add an appropriate entry to the
killswitches.json file in the releases
branch. That file must only ever
be committed to the releases
branch!!! See docs/Killswitches.md.
Killswitch files can and should be verified using the killswitch_test.py
script in the scripts
directory
You'll want to do the .exe and .msi generation in a cmd.exe
window, not e.g.
a 'Git bash' window. The 'Terminal' tab of PyCharm works fine.
Assuming the correct python.exe is associated with .py files then simply run:
build.py
else you might need this, which assumes correct python.exe is in your PATH:
python.exe build.py
else you'll have to specify the path to python.exe, e.g.:
"C:\Program Files \(x86)\Python38-32\python.exe" build.py
Output will be something like (...
denoting parts elided for brevity):
Git short hash: 993f946b.DIRTY
INFO:runtime:Analyzing the code
INFO:runtime:Found 695 modules, 60 are missing, 0 may be missing
...
Building 'dist.win32\EDMC.exe'.
Building 'dist.win32\EDMarketConnector.exe'.
Do check the output for things like not properly specifying extra files
to be included in the install. If they're not picked up by current rules in
build.py
then you will need to add them to the win32
DATA_FILES
array.
You should now have one new/updated folder dist.win32
and two new files
(version string dependent): EDMarketConnector_win_4.0.2.msi
and
appcast_win_4.0.2.xml
.
Check that the EDMarketConnector.exe
in the dist.win32
folder does run
without errors.
Finally, uninstall your current version of ED Market Connector and re-install
using the newly generated EDMarketConnector_installer_4.0.2.exe
file. Check the
resulting installation does work (the installer will run the program for you).
Update edmarketconnector.xml
once more to set the length=
attribute of the
enclosure to match the file size of the EDMarketConnector_installer_4.0.2.exe
file.
The git commit for this should end up being the release tag as below.
Whether you built it manually or automatically you MUST test the .exe
installer file prior to making the release live.
Once that is done then for manually built installers:
-
Add a git tag for the release, which you'll refer to when actually creating the release: 1. This should be named
Release/A.B.C
, e.g.Release/4.0.2.
as per the version string.Do NOT add this tag until you're sure you're ready. Pushing a tag to GitHub that matches the pattern
Release/*
(double-check this in the GitHub Windows Build Action file) will cause an auto-build and creation of a draft release.Yes, this does mean you should really just be using this auto-build setup when creating an installer for release to users. You'll at least need to edit the draft release that it creates:
-
Swap out its
.msi
for the one that you built. -
Create a matching
hashes.sum
file for your.msi
file:sha256sum EDMarketConnector_win*.msi > ./hashes.sum
and replace the one in the draft release with this.
But, again, you should just be using the auto-build mechanism.
-
-
Now push the release-specific branch to GitHub.
- Check which of your remotes is for github with
git remotes -v
. It should really beorigin
and the following assumes that. git push --set-upstream --tags origin release-4.0.2
- Check which of your remotes is for github with
-
Merge the release-specific branch into the appropriate
stable
orbeta
branch. You can either do this locally and push the changes, or do it on GitHub. You'll want to referencestable
orbeta
in the next step, not the release-4.0.2 branch, as it's temporary. -
You should no longer need to manually create a release, due to auto-building of any release tag, but you'll probably still need to edit in the ChangeLog, so...
Craft a new github Release,
- Use the new tag so as to reference the correct commit, along with the
appropriate
stable
orbeta
branch as the 'Target'. - Use the changelog text you already prepared to fill in the 'Release title' and description.
- Attach the
EDMarketConnector_win_<version>.msi
file for Windows (the Source Code files are added by github based on the release tag). - If you are making a
beta
or otherwise pre-release you MUST tick the[ ] This is a pre-release
box. Not doing so will cause this release to be pointed to by the 'latest' URL. - We always create a discussion for any new release, so tick the
Create a discussion for this release
box, and check it's targeted at theAnnouncement
category.
- Use the new tag so as to reference the correct commit, along with the
appropriate
Once the release is created, then only if making a stable
release
update edmarketconnector.xml
in the releases
branch only to add this
changelog text to the correct section(s):
-
git checkout releases
-
git merge stable
- You should have merged the new release branch intostable
above. -
Use the following to generate HTML from the MarkDown (
pip install grip
first if you need to):grip --export ChangeLog.md
-
Open
edmarketconnector.xml
in your editor. -
If there's still a Mac OS section croll down past it to the Windows section.
-
You'll need to change the
<title>
and<description>
texts to reflect the latest version and the additional changelog. -
Update the
url
andsparkle:version
elements of the<enclosure>
section.-
The
url
needs to match what GitHub created in the Release for the.msi
file. Check it!If, for instance, you fail to update this URL then upon running the 'new' installer it will silently fail, because you made people try to install the old version over the old version.
-
Yes,
sparkle:version
should be the Semantic Version string, not the Windows A.B.C.D form.
-
-
git push origin
This is the final step that fully publishes the release for running EDMC instances to pick up on 'Check for Updates'. The WinSparkle check for updates specifically targets:
https://raw.githubusercontent.com/EDCD/EDMarketConnector/releases/edmarketconnector.xml
as per
config/__init__.py
update_feed
.NB: It can take some time for GitHub to show the changed edmarketconnector.xml contents to all users.
You should now update Known Issues to reflect anything now fixed in latest release.
If you are making a pre-release then:
- DO NOT Edit
edmarketconnector.xml
at all. No, not even if you think you won't accidentally merge it intoreleases
. Just don't change it at all. - DO NOT merge into
releases
. - DO NOT merge into
stable
. - Do merge the code into
beta
after you have made a 'pre-release' on GitHub.
When changing the Python version (Major.Minor.Patch) used:
-
Change the contents of
.python-version
so that pyenv notices. All of the GitHub workflows now reference this via thesetup-python
python-version-file
directive. -
Any version change:
ChangeLog.md
- TheWe now test against, and package with, Python M.m.P.
line.
-
Major or Minor level changes:
build.py
will need its version check updating..pre-commit-config.yaml
will need thedefault_language_version
section updated to the appropriate version.