Compare commits

...

172 Commits

Author SHA1 Message Date
1878f3bac6 feat(icon): use custom Liquid Glass icon for Emacs.app
Use EmacsLG1 icon from in all builds:
https://github.com/jimeh/emacs-liquid-glass-icons
2025-09-14 21:17:17 +01:00
fb2956c35c chore(deps): update build-emacs-for-macos to 0.6.62 2025-09-14 12:27:23 +01:00
97721f45df chore(readme): update formatting 2025-09-10 19:31:06 +01:00
4142f78ed1 chore(deps): update build-emacs-for-macos to 0.6.61 2025-08-13 01:43:28 +01:00
0bdcc26ff7 docs(readme): update Homebrew Cask section 2025-06-28 16:46:45 +01:00
f77bef8017 chore(deps): update build-emacs-for-macos to 0.6.60 2025-06-27 22:45:03 +01:00
2304c38620 chore(deps): update build-emacs-for-macos to 0.6.59 2025-06-27 15:37:56 +01:00
d8ad016739 Merge pull request #53 from jimeh/upgrade-nix-actions 2025-06-27 15:16:24 +01:00
b8192fb788 fix(release): dmg build step success check 2025-06-27 15:13:35 +01:00
51fba0905b chore(deps): upgarde nix GitHub Actions 2025-06-27 12:34:04 +01:00
f73c57be55 feat(builds): update build-emacs-for-macos to 0.6.58 and add build variant option 2025-06-27 12:23:16 +01:00
d66071efc4 chore(deps): update build-emacs-for-macos to 0.6.57 2024-12-08 14:08:16 +00:00
5f2c9eef19 chore(deps): update build-emacs-for-macos to 0.6.55 2024-12-03 00:20:33 +00:00
b381cba4fa fix(workflow/_prepare): fix typo in default ref logic 2024-12-02 19:54:16 +00:00
d40d900d61 refactor(workflows): simplify default builder_ref setting
Allow the default builder_ref to be set in the a single location, the
_prepare shared workflow. Other workflows essentially have a override
option, and no longer need explicit default values set.
2024-12-02 19:51:29 +00:00
d81f9a1229 fix(nightly): remove supurflous inputs from nightly-master workflow
They're not needed for manual runs, and they were actively causing
things to break when triggered by the schedule.
2024-12-02 19:37:33 +00:00
93ad41d01a chore(deps): update build-emacs-for-macos to 0.6.54 2024-12-01 12:41:17 +00:00
c5db478e64 docs(readme): add update about new Apple Silicon nightly builds 2024-12-01 04:45:34 +00:00
c554cdeb31 chore(deps): update build-emacs-for-macos to 0.6.53 2024-12-01 03:54:14 +00:00
6ef0736067 Merge pull request #41 from jimeh/improve-multi-arch-builds
feat(builds): improve build speeds and use free arm64 runners
2024-12-01 01:44:06 +00:00
d52095babb feat(builds): improve build speeds and use free arm64 runners
Improves a few things:

- Use the free macos-14 runners for arm64 builds. They are not as fast
  the macos-13-xlarge runners used before, but they are free for public
  repositories, meaning we can start doing nightly arm64 builds.
- Use different nix install and cache actions which are faster, and uses
  a single action cache key, which avoids cache rate limit errors
  which was slowing down cache create/restore times.
- Generally refactor and tidy up various bits and pieces in workflows.
2024-12-01 01:42:50 +00:00
bc0082e4a8 Merge pull request #39 from jimeh/use-nix
feat(build/deps): switch from Homebrew to Nix for build dependencies
2024-11-30 18:11:24 +00:00
099c10776a refactor(build): avoid release publishing race conditions
Only run release jobs after all build jobs have completed, ensure only
one release job runs at a time, and also ensure update casks only runs
once after all release jobs have completed.
2024-11-25 02:50:28 +00:00
e0c0d92424 feat(build/deps): switch from Homebrew to Nix for build dependencies 2024-11-25 02:50:27 +00:00
692c58ea35 chore(deps): update build-emacs-for-macos to 0.6.48 2024-08-09 09:12:08 +01:00
ec8c83bd4b chore(build): skip builder script Ruby development dependencies 2024-08-09 09:10:08 +01:00
3967c4ecc8 ci(actions): update all actions to latest versions to avoid deprecation warnings 2024-05-13 01:47:33 +01:00
307f13be0b ci(build/nightly): fix arm64 workflow dispatch event check 2024-05-13 01:37:55 +01:00
92533f2b50 chore(deps): update build-emacs-for-macos to 0.6.47 2024-05-13 01:32:21 +01:00
17e0cb55ac chore(deps): update build-emacs-for-macos to 0.6.46 2024-04-03 09:47:17 +01:00
6acaf3f2cb chore(build/package): disable debug logging 2024-04-03 09:46:22 +01:00
c262274a3d docs(readme): add badge for monthly cask 2023-11-24 21:03:59 +00:00
ca7f04ce6a chore(meta): tweak update-meta workflow
Run once a day only, and pass in cache flag to keep download totals
accurate over time.
2023-11-24 20:39:41 +00:00
202f62454e docs(readme): add News / Recent Changes section 2023-11-22 09:02:25 +00:00
99341c4f19 docs(readme): add details about Apple Silicon monthly and stable builds 2023-11-21 22:10:20 +00:00
b841bc77b9 feat(nightly): do not build arm64 variant by default
For now arm64 builds are only done once per month due to the high cost
of using the M1-based runners.
2023-11-20 09:30:51 +00:00
196270a3f4 fix(build): typo preventing correct info message from displaying 2023-11-20 09:30:31 +00:00
2062378299 chore(deps): update build-emacs-for-macos to 0.6.45 2023-11-20 02:29:12 +00:00
cc7bb92357 chore(builds): upgrade minimum macOS version from 11 to 12
Builds using macOS 11 just takes a stupidly long time as, as Homebrew
seems to have dropped support, meaning all homebrew dependencies are
installed from source, rather than get installed from bottles.

Hence let's try upgrading minimum macOS version from 11 (Big Sur), to
12 (Monteray).
2023-11-20 02:19:26 +00:00
1a36bde31e fix(workflow/nightly): remove errant input references 2023-11-20 01:07:47 +00:00
04d1bbeb71 fix(build): use correct bootstrap make target 2023-11-19 23:34:40 +00:00
3e4d8b1833 chore(deps): update build-emacs-for-macos to 0.6.44 2023-11-19 23:33:12 +00:00
a292b242c4 chore(nightly): temporarily enable arm64 builds
We want one scheduled arm64 build for now, then we'll revert to only
building them on the 1st of the month.
2023-11-19 23:30:02 +00:00
287df6914e fix(workflows): refactor nightly workflows 2023-11-19 23:24:49 +00:00
d2cb4d5905 chore(workflows): rename workflows back 2023-11-19 23:00:34 +00:00
6b4bd441a3 fix(build): pass inputs correctly 2023-11-19 22:54:40 +00:00
6e1af1b83f feat(build): disable emacs-29 branch builds
They are no longer that relevant, as Emacs 29.1 is out, and master is
version 30.
2023-11-19 22:41:32 +00:00
81b0e4a784 fix(build): do not require inputs which have defaults 2023-11-19 22:41:13 +00:00
503023cd53 chore(build): refactor build workflow 2023-11-19 22:27:49 +00:00
a79110c550 feat(build): support multi-arch builds 2023-11-19 22:26:46 +00:00
ff1b573f43 feat(build): allow running build job on separate OS
This should help reduce costs for Apple Silicon builds, as they are not
available on any form of free tier of GitHub Actions at the moment.

The build step that actually runs Emacs' configure script, and compiles
Emacs, is the only step that actually needs to run on the target
hardware architecture. The rest should be architecture agnostic.
2023-11-19 22:26:46 +00:00
e65fc8f4f0 Update nightly-master.yml 2023-11-17 00:47:27 +00:00
f1bd559949 chore(deps): update build-emacs-for-macos to 0.6.43 2023-11-16 14:16:49 +00:00
d169338d88 ci(prepare): fix issue with setup-go cache 2023-11-16 13:30:41 +00:00
d9d8975d98 fix(workflow/build): use brew --prefix instead of hard-coded path 2023-11-15 00:06:21 +00:00
f9ee76857f chore(workflow): upgrade actions and language runtimes 2023-11-14 23:52:05 +00:00
c18f19b60b fix(workflow): use same OS in all jobs 2023-11-14 23:41:24 +00:00
dc1fdc91fc ci(meta): fix workflow 2023-07-31 22:32:38 +01:00
54e3c95ade ci(meta): update workflow to use Go 1.20 and provide GITHUB_TOKEN 2023-07-31 19:50:11 +01:00
f73a9c6c03 chore(deps): update build-emacs-for-macos to 0.6.42 2023-07-31 19:21:22 +01:00
f1e9216ef5 docs(readme): minor fix and update 2023-06-20 01:20:38 +01:00
1dd8a0a863 docs(readme): update description of patches included from emacs-plus 2023-01-25 00:19:09 +00:00
f555605f93 ci(emacs-28): disable nightly builds from emacs-28 branch
Emacs 28.x does no longer receive daily work, as next is 29.x being
worked on in emacs-29.
2023-01-24 23:59:55 +00:00
29e5fad03d docs(readme): update nightly emacs-28 references to emacs-29 2023-01-24 23:58:42 +00:00
11b57f3ed1 ci(build): remove brew env vars potentially causing issues 2023-01-16 23:56:31 +00:00
01805db074 fix(deps): hack to remove system python symlinks interfering with brew 2023-01-16 23:54:03 +00:00
2f408c834e chore(deps): update build-emacs-for-macos to 0.6.40
This should fix nightly build issues caused by homebrew package upgrade
failures.
2023-01-08 22:40:02 +00:00
9e2d7cb592 feat(nightly): add nightly build for emacs-29 branch 2022-12-04 21:28:48 +00:00
d351fb20ce chore(nightly): schedule nightly builds for 23:00 UTC
With nightly runs at midnight, it sometimes takes GitHub Actions over an
hour to start the build. On rare occasion this allows new commits from
the new day sneaking in.

Hence we adjust the scheduled build time for now, until the build tool
can be updated to support picking a target commit based on date limits.
2022-12-04 21:22:28 +00:00
1fa1a3be36 chore(deps): update build-emacs-for-macos to 0.6.39 2022-12-04 20:34:50 +00:00
f1a232b18a chore(deps): update build-emacs-for-macos to 0.6.38 2022-12-01 22:35:52 +00:00
86be2a1c30 chore(deps): update build-emacs-for-macos to 0.6.37 2022-12-01 22:15:15 +00:00
c2bba0dc34 chore(ci): use relative references to reusable workflows 2022-12-01 22:15:15 +00:00
5991d0aaf2 fix: resolve dmgbuild installation issue and outdated actions 2022-11-06 23:22:25 +00:00
54ff01d673 chore(deps): update build-emacs-for-macos to 0.6.36 2022-10-08 14:51:04 +01:00
c1c4a03471 fix(nightly): prevent nightly builds without native-comp
By default the build script will enable native-comp if it detects it in
the source tree. This caused recently nightly builds of master to be
built without native-comp due to recent changes in Emacs' configure
script which broke native-comp detection. More details here:

https://github.com/jimeh/build-emacs-for-macos/issues/76

Hence we explicitly enable native-comp now for the nightly master and
emacs-28 builds, which will cause the build script to fail if it cannot
detect native-comp support in the source tree.

Any failure to detect native-comp in master and emacs-28 branches would
at this point be due to a bug/issue with the build script, rather than
Emacs' source tree.
2022-10-08 14:46:14 +01:00
adc48a6492 chore(deps): update build-emacs-for-macos to 0.6.35
Fixes build issues caused by a incompatibility with the libgccjit v12.x
homebrew formula.
2022-08-10 16:49:48 +01:00
14575aa77c chore(deps): update build-emacs-for-macos to 0.6.34 2022-07-27 23:26:51 +01:00
3e3347dbec Merge pull request #23 from jimeh/macos-11
fix(ci): switch to macos-11 (Big Sur) runner
2022-07-27 21:51:19 +01:00
4f2d35c1ac fix(ci): switch to macos-11 (Big Sur) runner
The macos-10.15 runner is now deprecated and no longer usable. Hence all
GitHub Actions workflows using a macOS runner need to upgraded to
macos-11.

As far as I know, this will have a knock-on effect of causing Emacs
builds to require macOS 11.x (Big Sur) or later from now on.
2022-07-27 19:54:01 +01:00
2e80b79110 chore(deps): update build-emacs-for-macos to 0.6.33 2022-04-30 19:45:08 +01:00
88bfa2e603 chore(build): run "brew update" before installing brew deps 2022-04-30 19:45:08 +01:00
9934f47937 docs(readme): minor tweak to stable homebrew cask description 2022-04-07 00:28:26 +01:00
Alec
13e8c9cc9e docs(readme): emacs-app now includes native-comp 2022-04-06 07:44:06 -04:00
4204855346 chore(deps): update build-emacs-for-macos to 0.6.31 2022-02-25 10:35:14 +00:00
11b4492488 chore(deps): update build-emacs-for-macos to 0.6.30 2022-02-08 03:08:35 +00:00
a39895e8f6 docs(readme): add details about pretest builds 2022-02-07 23:17:46 +00:00
27b104d7b7 chore(deps): update build-emacs-for-macos to 0.6.29 2022-02-07 23:17:25 +00:00
0af73aaee1 chore(deps): update build-emacs-for-macos to 0.6.28 2022-01-15 23:21:36 +00:00
16087a80d0 chore(deps): update build-emacs-for-macos to 0.6.27 2021-12-05 13:09:44 +00:00
5835cd9712 docs(readme): update requirements list after gcc fix, minor tweaks 2021-11-30 23:15:36 +00:00
fe10ed4c34 chore(build): remove --no-relink-eln-files option from manual build workflow 2021-11-27 05:07:00 +00:00
9615ab20a6 chore(deps): update build-emacs-for-macos to 0.6.25
Relinking *.eln files has also been fixed, so there's no need to disable
that anymore.
2021-11-27 05:04:46 +00:00
cad73f3555 fix(release): dmg artifact output result check 2021-11-27 03:16:15 +00:00
30f92f734d fix(release): improve handling of no new commit since last build 2021-11-27 01:37:02 +00:00
83b08dc596 feat(build): allow customizing --relink-eln-files arg on custom builds 2021-11-26 02:10:30 +00:00
f3213d9f5a chore(deps): update build-emacs-for-macos to 0.6.25 2021-11-25 23:40:30 +00:00
b40f9e29c8 update build-emacs-for-macos to 0.6.24 2021-11-24 21:54:44 +00:00
e552de3cac fix(builds): use correct path for emacs source tarball artifact upload 2021-11-24 21:54:13 +00:00
9c731dac34 fix(builds/emacs-28): disable posix-patch, it's now in the emacs-28 branch 2021-11-14 02:48:07 +00:00
bf358f42d5 docs(readme): tweak formatting of badges 2021-11-12 13:34:42 +00:00
646d8775fb chore(metadata): run update-metadata workflow every 12 hours
Once an hour was overkill.
2021-11-12 13:31:27 +00:00
7e4ba5a9b8 fix(builds): only use posix-spawn patch on emacs-28 builds
The posix-spawn patch has been added to the master branch, but not the
emacs-28 branch yet.
2021-11-12 13:26:24 +00:00
f82d299015 docs(readme): fix total downloads badge
The release downloads badge from shields.io only checks the first 100
most recent GitHub Releases to calculate the download totals. This
obviously yields invalid values if a repository has more than 100
releases.

Hence we're switching the badge to source it's data from a custom JSON
file in the meta branch, which is updated once an hour but a scheduled
GitHub Actions workflow which runs a Go file that checks all releases
from all pages for downloads counts.
2021-11-11 01:40:51 +00:00
fe0972217f chore(metadata): add update-metadata GitHub Actions Workflow 2021-11-11 01:36:10 +00:00
a61807dea3 feat(builds): enable new posix-spawn patch 2021-11-10 22:24:19 +00:00
d1e14bb59b chore(deps): update build-emacs-for-macos to 0.6.23 2021-11-10 22:24:09 +00:00
06c6c2dbf2 chore(deps): update build-emacs-for-macos to 0.6.22 2021-11-10 02:04:23 +00:00
4561c9d4ce feat(workflows): add builder args option for Build workflow 2021-11-10 02:03:15 +00:00
ebc4626270 chore(deps): update build-emacs-for-macos to 0.6.21 2021-10-27 21:48:18 +01:00
1e45868817 chore(deps): update build-emacs-for-macos to 0.6.20 2021-10-23 20:36:11 +01:00
8e6aa813f9 docs(readme): fix links in badges 2021-10-23 17:38:31 +01:00
f8bf0870a7 docs(readme): add badge for emacs-28 nightly builds 2021-10-23 17:36:08 +01:00
b84115f251 chore(deps): update build-emacs-for-macos to 0.6.19
Fixes an issue with patches for Emacs 29.x.
2021-10-23 17:30:13 +01:00
ffd1f41e19 docs(readme): add mention of emacs-app-nightly-28 Homebrew Cask 2021-10-23 16:39:15 +01:00
195a5f9775 chore(build): upload emacs source tarball as build artifact 2021-10-23 16:32:12 +01:00
31172c47c3 chore(deps): update build-emacs-for-macos to 0.6.18 2021-10-23 16:25:22 +01:00
482bde4c00 fix(workflows): use correct artifact name for build-plan
Also rename build-plan artifact from "build-plan.yml" to "build-plan".
2021-10-11 02:25:50 +01:00
aab02b7454 chore(workflows): tweak re-usable workflow names, again 2021-10-11 00:20:45 +01:00
a8d3b9d473 fix(workflows): remove left-over debug push event from nightly workflows 2021-10-11 00:18:18 +01:00
82353b98c5 chore(workflows): tweak names of re-usable workflows 2021-10-11 00:17:58 +01:00
5b48a4ac70 feat(nightly): add nightly builds for the emacs-28 release branch 2021-10-11 00:06:04 +01:00
2c06f2c0c8 refactor(workflows): switch to re-usable GitHub Actions workflows
This makes the workflow setup more flexible, and less copy/pasting
between workflows. And also makes the process of adding nightly builds
for non-master branches easier too.
2021-10-11 00:03:33 +01:00
1f67047d8d fix(build): add missing --no-archive flag to build script 2021-08-05 10:36:18 +01:00
9809dd349e fix(test-build): build plan is needed by package job 2021-08-05 10:35:55 +01:00
a4b07f609d chore(deps): update build-emacs-for-macos to 0.6.15 2021-08-05 02:39:18 +01:00
1049006024 chore(deps): update build-emacs-for-macos to 0.6.14 2021-08-05 01:22:09 +01:00
1ba8aaecfd chore(test-build): fix builder sha lookup, remove caching
The caching idea is somewhat flawed, as there's a lot of things that
cane effect the outcome, and they're difficult to boil down into a
single unique key.
2021-08-05 01:21:02 +01:00
6561dc4a02 chore(test-build): cache unsigned app based on builder git sha and build-plan.yml hash 2021-08-05 00:44:40 +01:00
dae8939b35 fix(build): disable relinking shared libs in *.eln files
Relinking the libgcc shared lib within bundled *.eln files seems to
prevent code signing from having enough space to add a signature to the
files. So for now it looks like we have to disable it.
2021-08-05 00:11:17 +01:00
baea14c975 chore(deps): update build-emacs-for-macos to 0.6.13 2021-08-05 00:08:00 +01:00
ee9e58b873 chore(deps): update build-emacs-for-macos to 0.6.12
Should resolve code signing issue which has been preventing new nightly
builds.
2021-08-03 00:20:40 +01:00
04d20d42a4 chore(deps): update build-emacs-for-macos to 0.6.11
Fixes issue with code signing *.eln files.
2021-07-17 13:10:18 +01:00
259b0ac92b chore(deps): update build-emacs-for-macos to 0.6.9
Fixes:

- native-comp: *.eln files were not being found during shared lib
  embedding
2021-07-17 00:27:58 +01:00
162f9ad529 docs(readme): update requirements to mention M1-based macs 2021-07-13 21:36:42 +01:00
a6324b58c9 docs(readme): add link to homebrew tap 2021-07-10 21:21:11 +01:00
9be0607ee5 chore(deps): update build-emacs-for-macos to 0.6.9 2021-07-04 23:29:43 +01:00
18f753e476 docs(readme): update version badges 2021-07-04 18:32:28 +01:00
9e71a079a9 docs(readme): fix typo 2021-07-03 02:55:49 +01:00
8e92655b4b docs(readme): add information about stable builds 2021-07-03 02:54:32 +01:00
1782d42a7d docs(readme): add stable/nightly badges 2021-07-03 02:11:51 +01:00
ac5ff5d3c2 docs(readme): update nightly badge to include pre-releases 2021-07-03 00:37:46 +01:00
13410e3977 feat(builds): add support for building stable Emacs releases
As of build-emacs-for-macos v0.6.8, the emacs-builder tool supports
handling stable Emacs release differently, so we can easily separate
them from the regular nightly builds.
2021-07-03 00:21:55 +01:00
88f47746e4 fix(cask): trigger cask update in homebrew tap after publishing release 2021-07-02 00:13:17 +01:00
4ffe25022c chore(deps): update build-emacs-for-macos to 0.6.5 2021-07-01 23:42:20 +01:00
00094c131c docs(readme): improve formatting of Installation section 2021-06-29 02:58:04 +01:00
26b12fac27 docs(readme): update readme about homebrew cask installation method 2021-06-29 02:42:02 +01:00
25e2a41b22 chore(deps): update build-emacs-for-macos to 0.6.2
Should fix startup error about missing *.eln files.
2021-06-29 01:31:51 +01:00
1b2cc6e676 feat(cask): add workflow to trigger homebrew cask formula update on new release
This triggers the update formulas workflow in the
jimeh/homebrew-emacs-builds repo whenever a release or pre-release is
created in jimeh/emacs-builds.

This allows the cask formulas to automatically stay up to date with
latest nightly builds.
2021-06-29 00:28:47 +01:00
376125273b chore(deps): update build-emacs-for-macos to 0.6.1 2021-06-29 00:28:32 +01:00
832a6ffe75 ci(github): cache god modules to speed up emacs-builder compile time 2021-06-29 00:27:38 +01:00
72fc6962a7 chore(deps): update build-emacs-for-macos to 0.5.2
Should fix the recent build and signing issues with nightly builds.
2021-06-27 12:35:32 +01:00
d2d9494a44 chore(deps): update build-emacs-for-macos to 0.5.1 2021-06-27 02:36:42 +01:00
8d84df095a docs(readme): update with info about signing and notarization 2021-06-22 03:10:47 +01:00
6883fd0f12 Merge pull request #10 from jimeh/sign-and-notarize
feat(signing)!: sign, notarize and staple Emacs.app and disk image
2021-06-22 00:57:23 +01:00
ca4e7e2c44 feat(signing)!: sign, notarize and staple Emacs.app and disk image
Update the build-emacs-for-macos to v0.5.0, which includes a new
emacs-builder CLI tool written in Go, which handles signing, dmg
packaging, notarizing and stapling of Emacs builds. The main build
process is still handled by the old Ruby script for now however.

emacs-builder also includes plan and release commands, negating the need
for the our custom github-release CLI tool.

BREAKING CHANGE: Release assets are now signed *.dmg files instead
of *.tbz archives.
2021-06-22 00:55:31 +01:00
ffad4f21d2 docs(readme): update CLI usage section 2021-06-20 18:37:18 +01:00
b94cb495ae chore(deps): update build-emacs-for-macos to 0.4.16
- fix(compiling): improve portability of builds
- fix(native_comp): crash on launch when gcc homebrew package was not
  installed
2021-06-07 23:45:49 +01:00
d6fb7efc3a chore(deps): update build-emacs-for-macos to 0.4.15
Makes build script itself perform authenticated GitHub API calls when
GITHUB_TOKEN environment variable is set.
2021-05-31 23:27:59 +01:00
cf0c1d0d07 chore(deps): update build-emacs-for-macos to 0.4.14
Adds a "emacs" CLI launcher script next to the "emacsclient" executable
in Emacs.app/Contents/MacOS/bin.
2021-05-22 21:11:14 +01:00
4ce0cf69d5 chore(deps): update build-emacs-for-macos to 0.4.13
Nothing new from a user-point of view. But this introduces the first
changes to the build script required to sign and notarize builds.
2021-05-22 18:54:29 +01:00
831bb394af docs(readme): add CLI usage section 2021-05-21 11:40:49 +01:00
7a6e5b52ef docs(readme): Minor tweaks to features list 2021-05-18 01:53:04 +01:00
7ffbd12e87 docs(readme): update features list and badges 2021-05-18 01:47:55 +01:00
4e22cf33ee chore(deps): update build-emacs-for-macos to 0.4.12
This fixes the issues with SVG rendering, and re-enables librsvg
support, meaning builds can render SVG images finally.
2021-05-17 23:17:21 +01:00
628092755e docs(readme): update release badge 2021-05-17 12:38:32 +01:00
27bcad6052 fix(dylib-tree): command name in help output had the old link-tree name 2021-05-17 01:22:59 +01:00
ff22622f87 chore(deps): fix Go module path in go.mod 2021-05-17 01:19:14 +01:00
ee642683c4 feat(tools): add dylib-tree tool to list/filter linked dynamic libraries 2021-05-17 01:14:46 +01:00
56d9178919 ci(test-builds): fix workflow name 2021-05-16 17:36:27 +01:00
29f5577efe ci(test-builds): add test builds GitHub Actions workflow
This will allow creating test builds using any branch of
build-emacs-for-macos or emacs-builds repos, so experimental changes can
be verified without affecting the nightly builds.
2021-05-16 17:34:13 +01:00
8544a650ab test(builds): add test build options to github-release tool
This will allow me to run test builds against experimental branches of
the build-emacs-for-macos build script, and publish them under a
pre-release "Test Builds" GitHub Release, rather than a normal nightly
release.
2021-05-16 17:33:57 +01:00
21 changed files with 1103 additions and 708 deletions

151
.github/workflows/_build.yml vendored Normal file
View File

@@ -0,0 +1,151 @@
---
name: _build
on:
workflow_call:
inputs:
git_ref:
description: Emacs git ref to build
required: true
type: string
git_sha:
description: Override Emacs git commit SHA to build
required: false
type: string
builder_ref:
description: "Git ref to checkout of build-emacs-for-macos"
required: false
type: string
builder_args:
description: Custom arguments passed to build script
required: false
default: ""
type: string
build_variant:
description: "Optional build number used as version suffix"
required: false
type: string
test_build_name:
description: "Test build name"
required: false
default: ""
type: string
test_release_type:
description: "prerelease or draft"
required: false
default: ""
type: string
x86_64:
description: "Build x86_64 version of Emacs"
required: false
default: true
type: boolean
arm64:
description: "Build arm64 version of Emacs"
required: false
default: true
type: boolean
jobs:
prepare:
name: Prepare
uses: ./.github/workflows/_prepare.yml
with:
builder_ref: ${{ inputs.builder_ref }}
# ----------------------------------------------------------------------------
# Build x86_64 version of Emacs
# ----------------------------------------------------------------------------
build_x86_64:
name: Build (x86_64)
if: inputs.x86_64
uses: ./.github/workflows/_build_emacs.yml
needs: [prepare]
with:
builder_ref: ${{ needs.prepare.outputs.builder_sha }}
os: "macos-13"
build_os: "macos-13" # Only macos-13 and earlier are x86_64.
artifact_prefix: "x86_64-"
git_ref: ${{ inputs.git_ref }}
git_sha: ${{ inputs.git_sha }}
build_args: ${{ inputs.builder_args }}
build_variant: ${{ inputs.build_variant }}
test_build_name: ${{ inputs.test_build_name }}
test_release_type: ${{ inputs.test_release_type }}
secrets: inherit
release_x86_64:
name: Release (x86_64)
uses: ./.github/workflows/_release.yml
# Depend on both build_x86_64 and build_arm64, but only run if build_x86_64
# was successful and a package was created. This ensure wait for all builds
# to complete before running any release jobs.
needs: [prepare, build_x86_64, build_arm64]
if: |
always() &&
needs.build_x86_64.result == 'success' &&
needs.build_x86_64.outputs.package_created &&
needs.build_arm64.result != 'failure'
with:
builder_ref: ${{ needs.prepare.outputs.builder_sha }}
os: "macos-13" # Only macos-13 and earlier are x86_64.
plan_artifact: x86_64-build-plan
dmg_artifact: x86_64-dmg
# ----------------------------------------------------------------------------
# Build arm64 version of Emacs
# ----------------------------------------------------------------------------
build_arm64:
name: Build (arm64)
if: inputs.arm64
uses: ./.github/workflows/_build_emacs.yml
needs: [prepare]
with:
builder_ref: ${{ needs.prepare.outputs.builder_sha }}
os: "macos-14"
build_os: "macos-14" # Only macos-14 and later are ARM64.
artifact_prefix: "arm64-"
git_ref: ${{ inputs.git_ref }}
git_sha: ${{ inputs.git_sha }}
build_args: ${{ inputs.builder_args }}
build_variant: ${{ inputs.build_variant }}
test_build_name: ${{ inputs.test_build_name }}
test_release_type: ${{ inputs.test_release_type }}
secrets: inherit
release_arm64:
name: Release (arm64)
uses: ./.github/workflows/_release.yml
# Depend on both build_arm64 and build_x86_64, but only run if build_arm64
# was successful and a package was created. This ensure wait for all builds
# to complete before running any release jobs.
needs: [prepare, build_arm64, build_x86_64]
if: |
always() &&
needs.build_arm64.result == 'success' &&
needs.build_arm64.outputs.package_created &&
needs.build_x86_64.result != 'failure'
with:
builder_ref: ${{ needs.prepare.outputs.builder_sha }}
os: "macos-14" # Only macos-14 and later are ARM64.
plan_artifact: arm64-build-plan
dmg_artifact: arm64-dmg
# ----------------------------------------------------------------------------
# Trigger update casks workflow in homebrew tap
# ----------------------------------------------------------------------------
update_casks:
name: Update Casks
uses: ./.github/workflows/_update-casks.yml
# Depend on both release jobs, but only run if either of them was
# successful. This ensures we only run this job once all release jobs have
# been completed.
needs: [release_x86_64, release_arm64]
if: >-
always() &&
inputs.test_build_name == '' &&
contains(needs.*.result, 'success') &&
!contains(needs.*.result, 'failure')
secrets: inherit

253
.github/workflows/_build_emacs.yml vendored Normal file
View File

@@ -0,0 +1,253 @@
---
# Requires _prepare.yml re-usable workflow to have run.
name: _build_emacs
on:
workflow_call:
inputs:
builder_ref:
description: Git ref of build-emacs-for-macos to use
type: string
required: true
os:
description: GitHub Actions runner OS
type: string
required: false
default: "macos-13"
build_os:
description: Target OS to build for
type: string
required: false
default: "macos-13"
artifact_prefix:
description: Artifact prefix for build_os
type: string
required: false
git_ref:
description: Git ref to build
type: string
required: true
git_sha:
description: Override git SHA to build
type: string
required: false
build_args:
description: Custom arguments passed to build script
type: string
required: false
build_variant:
description: "Optional build number used as version suffix"
type: string
required: false
test_build_name:
description: "Test build name"
type: string
required: false
test_release_type:
description: "prerelease or draft"
type: string
required: false
default: "prerelease"
outputs:
package_created:
description: "Whether or not a package was created"
value: ${{ jobs.package.result == 'success' }}
jobs:
plan:
runs-on: ${{ inputs.build_os }}
outputs:
check: ${{ steps.check.outputs.result }}
steps:
- name: Checkout build-emacs-for-macos repo
uses: actions/checkout@v4
with:
repository: jimeh/build-emacs-for-macos
ref: ${{ inputs.builder_ref }}
- name: Download pre-built emacs-builder artifact
uses: actions/download-artifact@v4
with:
name: emacs-builder-${{ runner.arch }}
path: bin
- name: Ensure emacs-builder is executable
run: chmod +x bin/emacs-builder
- uses: nixbuild/nix-quick-install-action@v32
- uses: nix-community/cache-nix-action@v6
with:
primary-key: nix-${{ runner.arch }}-${{ hashFiles('**/flake.*') }}
- name: Install dependencies
run: nix develop --command nix flake metadata
- name: Prepare plan test args
id: test_plan_args
if: inputs.test_build_name != ''
run: >-
echo "args=--test-build '${{ inputs.test_build_name }}' --test-release-type '${{ inputs.test_release_type }}'" >> "$GITHUB_OUTPUT"
- name: Prepare build variant args
id: build_variant_args
if: inputs.build_variant != ''
run: >-
echo "args=--build-variant ${{ inputs.build_variant }}" >> "$GITHUB_OUTPUT"
- name: Set git SHA override
id: emacs_sha
if: inputs.git_sha != ''
run: >-
echo "sha=--sha '${{ inputs.git_sha }}'" >> "$GITHUB_OUTPUT"
- name: Plan build
run: >-
nix develop --command
bin/emacs-builder -l debug plan --output build-plan.yml
--output-dir '${{ github.workspace }}/builds'
${{ steps.build_variant_args.outputs.args }}
${{ steps.test_plan_args.outputs.args }}
${{ steps.emacs_sha.outputs.sha }}
'${{ inputs.git_ref }}'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Show plan
run: cat build-plan.yml
- name: Upload build-plan artifact
uses: actions/upload-artifact@v4
with:
name: ${{ inputs.artifact_prefix }}build-plan
path: build-plan.yml
if-no-files-found: error
- name: Check if planned release and asset already exist
id: check
continue-on-error: true
run: |
echo "result=$((bin/emacs-builder -l debug release --plan build-plan.yml check && echo 'ok') || echo 'fail')" >> "$GITHUB_OUTPUT"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- run: echo 'Planned release already seems to exist.'
if: steps.check.outputs.result == 'ok'
build:
runs-on: ${{ inputs.build_os }}
needs: [plan]
# Only run if check for existing release and asset failed.
if: needs.plan.outputs.check == 'fail'
steps:
- name: Checkout build-emacs-for-macos repo
uses: actions/checkout@v4
with:
repository: jimeh/build-emacs-for-macos
ref: ${{ inputs.builder_ref }}
path: builder
- uses: nixbuild/nix-quick-install-action@v32
- uses: nix-community/cache-nix-action@v6
with:
primary-key: nix-${{ runner.arch }}-${{ hashFiles('**/flake.*') }}
- name: Download build-plan artifact
uses: actions/download-artifact@v4
with:
name: ${{ inputs.artifact_prefix }}build-plan
path: ./builder/
- name: Install dependencies
run: nix develop --command nix flake metadata
working-directory: builder
- name: Install Ruby dependencies
run: >-
nix develop --command make bootstrap-ruby
working-directory: builder
env:
BUNDLE_WITHOUT: "development"
- name: Build Emacs
run: >-
nix develop
--command ./build-emacs-for-macos
--log-level debug
--plan build-plan.yml
--native-full-aot
--no-self-sign
--icon-uri 'https://github.com/jimeh/emacs-liquid-glass-icons/releases/download/v1.0.1/EmacsLG1-Default.icns'
--tahoe-icon-uri 'https://github.com/jimeh/emacs-liquid-glass-icons/releases/download/v1.0.1/Assets.car'
--tahoe-icon-name EmacsLG1
${{ inputs.build_args }}
working-directory: builder
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Upload unsigned app artifact
uses: actions/upload-artifact@v4
with:
name: ${{ inputs.artifact_prefix }}unsigned-app
path: builds/*.tbz
if-no-files-found: error
- name: Upload Emacs source artifact
uses: actions/upload-artifact@v4
with:
name: ${{ inputs.artifact_prefix }}emacs-source
path: builder/tarballs/*.tgz
package:
runs-on: ${{ inputs.os }}
needs: [plan, build]
steps:
- name: Download pre-built emacs-builder artifact
uses: actions/download-artifact@v4
with:
name: emacs-builder-${{ runner.arch }}
path: bin
- name: Ensure emacs-builder is executable
run: chmod +x bin/emacs-builder
- uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Install dmgbuild
run: |
$(command -v pip3 || command -v pip) install --upgrade dmgbuild
- name: Download build-plan artifact
uses: actions/download-artifact@v4
with:
name: ${{ inputs.artifact_prefix }}build-plan
path: ./
- name: Download unsigned app artifact
uses: actions/download-artifact@v4
with:
name: ${{ inputs.artifact_prefix }}unsigned-app
path: builds
- name: Extract unsigned app archive
run: |
find * -name '*.tbz' -exec tar xvjf "{}" \;
working-directory: builds
- name: Install the Apple signing certificate
run: |
# create variables
CERTIFICATE_PATH="$RUNNER_TEMP/build_certificate.p12"
KEYCHAIN_PATH="$RUNNER_TEMP/app-signing.keychain-db"
# import certificate and provisioning profile from secrets
echo -n "$CERT_BASE64" | base64 --decode > "$CERTIFICATE_PATH"
# create temporary keychain
security create-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
security set-keychain-settings -lut 21600 "$KEYCHAIN_PATH"
security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
# import certificate to keychain
security import "$CERTIFICATE_PATH" -P "$CERT_PASSWORD" -A \
-t cert -f pkcs12 -k "$KEYCHAIN_PATH"
security list-keychain -d user -s "$KEYCHAIN_PATH"
env:
CERT_BASE64: ${{ secrets.APPLE_DEVELOPER_CERTIFICATE_P12_BASE64 }}
CERT_PASSWORD: ${{ secrets.APPLE_DEVELOPER_CERTIFICATE_PASSWORD }}
KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
- name: Sign, package and notarize build
run: >-
bin/emacs-builder package -v --plan build-plan.yml
--sign --remove-source-dir
env:
AC_USERNAME: ${{ secrets.AC_USERNAME }}
AC_PASSWORD: ${{ secrets.AC_PASSWORD }}
AC_PROVIDER: ${{ secrets.AC_PROVIDER }}
AC_SIGN_IDENTITY: ${{ secrets.AC_SIGN_IDENTITY }}
- name: Upload disk image artifacts
uses: actions/upload-artifact@v4
with:
name: ${{ inputs.artifact_prefix }}dmg
path: |
builds/*.dmg
builds/*.sha*
if-no-files-found: error
- name: Clean up keychain used for signing certificate
if: always()
run: |
security delete-keychain "$RUNNER_TEMP/app-signing.keychain-db"

91
.github/workflows/_prepare.yml vendored Normal file
View File

@@ -0,0 +1,91 @@
---
name: _prepare
on:
workflow_call:
inputs:
builder_ref:
description: Git ref to checkout of build-emacs-for-macos
required: false
type: string
default: ""
outputs:
builder_ref:
description: Git ref of build-emacs-for-macos at builder_ref
value: ${{ jobs.builder-sha.outputs.ref }}
builder_sha:
description: Git commit SHA of build-emacs-for-macos at builder_ref
value: ${{ jobs.builder-sha.outputs.sha }}
jobs:
builder-sha:
runs-on: "macos-13"
outputs:
ref: ${{ steps.ref.outputs.ref }}
sha: ${{ steps.sha.outputs.sha }}
steps:
- name: Default git ref check
id: ref
run: |
DEFAULT_BUILDER_REF="v0.6.63"
BUILDER_REF="${{ inputs.builder_ref }}"
echo "ref=${BUILDER_REF:-$DEFAULT_BUILDER_REF}" >> "$GITHUB_OUTPUT"
- name: Checkout build-emacs-for-macos repo
uses: actions/checkout@v4
with:
repository: jimeh/build-emacs-for-macos
ref: ${{ steps.ref.outputs.ref }}
- name: Store builder Git SHA
id: sha
run: |
BUILDER_SHA="$(git rev-parse HEAD)"
echo "$BUILDER_SHA" > build-emacs-for-macos-git-sha.txt
echo "sha=$BUILDER_SHA" >> "$GITHUB_OUTPUT"
echo "Builder ref ${{ inputs.builder_ref }} resolved to" \
"commit SHA: $BUILDER_SHA"
- name: Upload builder git SHA artifact
uses: actions/upload-artifact@v4
with:
name: build-emacs-for-macos-git-sha
path: build-emacs-for-macos-git-sha.txt
if-no-files-found: error
emacs-builder:
needs: [builder-sha]
strategy:
matrix:
os:
- macos-13 # Only macos-13 and earlier are x86_64.
- macos-14 # Only macos-14 and later are ARM64.
runs-on: ${{ matrix.os }}
steps:
- name: Cache emacs-builder (${{ runner.arch }})
id: cache
uses: actions/cache@v4
with:
path: bin/emacs-builder
key: emacs-builder-${{ runner.arch }}-${{ needs.builder-sha.outputs.sha }}-bin
- name: Checkout build-emacs-for-macos repo
if: steps.cache.outputs.cache-hit != 'true'
uses: actions/checkout@v4
with:
repository: jimeh/build-emacs-for-macos
ref: ${{ needs.builder-sha.outputs.ref }}
fetch-depth: 0
- name: Setup Go
if: steps.cache.outputs.cache-hit != 'true'
uses: actions/setup-go@v5
with:
go-version: "1.23"
- name: Build emacs-builder tool
if: steps.cache.outputs.cache-hit != 'true'
run: make build
- name: Ensure emacs-builder is executable
if: steps.cache.outputs.cache-hit != 'true'
run: chmod +x bin/emacs-builder
- run: bin/emacs-builder --version
- name: Upload emacs-builder artifact
uses: actions/upload-artifact@v4
with:
name: emacs-builder-${{ runner.arch }}
path: bin/emacs-builder
if-no-files-found: error

59
.github/workflows/_release.yml vendored Normal file
View File

@@ -0,0 +1,59 @@
---
# Requires _prepare.yml and _build.yml re-usable workflows to have run.
name: _release
concurrency:
group: _release
cancel-in-progress: false
on:
workflow_call:
inputs:
builder_ref:
description: Git ref of build-emacs-for-macos to use
type: string
required: true
os:
description: GitHub Actions runner OS
type: string
required: false
default: "macos-13"
plan_artifact:
description: Name of artifact containing a emacs-builder plan yaml file
type: string
required: true
dmg_artifact:
description: Name of artifact containing a *.dmg files to release
type: string
required: true
jobs:
github:
runs-on: ${{ inputs.os }}
steps:
- name: Download pre-built emacs-builder artifact
uses: actions/download-artifact@v4
with:
name: emacs-builder-${{ runner.arch }}
path: bin
- name: Ensure emacs-builder is executable
run: chmod +x bin/emacs-builder
- name: Download build-plan.yml artifact
uses: actions/download-artifact@v4
with:
name: ${{ inputs.plan_artifact }}
path: ./
- name: Download disk image artifacts
id: dmg
continue-on-error: true
uses: actions/download-artifact@v4
with:
name: ${{ inputs.dmg_artifact }}
path: builds
- name: Publish disk images to a GitHub Release
if: steps.dmg.outcome != 'failure'
run: >-
bin/emacs-builder -l debug release --plan build-plan.yml publish
$(find builds -name '*.dmg' -or -name '*.sha256')
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- run: echo 'No DMG artifact available, was there a new commit to build?'
if: steps.dmg.outcome == 'failure'

23
.github/workflows/_update-casks.yml vendored Normal file
View File

@@ -0,0 +1,23 @@
---
name: _update-casks
concurrency:
group: _update-casks
cancel-in-progress: false
on:
workflow_call:
inputs:
os:
description: GitHub Actions runner OS
type: string
required: false
default: "ubuntu-latest"
jobs:
emacs-builds:
runs-on: ${{ inputs.os }}
steps:
- name: Trigger update casks workflow in homebrew tap
run: >-
gh workflow run --repo jimeh/homebrew-emacs-builds update-casks.yml
env:
GITHUB_TOKEN: ${{ secrets.TAP_REPO_TOKEN }}

View File

@@ -1,84 +1,58 @@
---
name: Build
on:
schedule:
- cron: "0 0 * * *"
workflow_dispatch:
inputs:
gitRef:
description: "Emacs git ref to build"
git_ref:
description: Emacs git ref to build
required: true
default: "master"
extraPlanArgs:
Description: "Extra plan args"
git_sha:
description: Override Emacs git commit SHA to build
required: false
builder_ref:
description: "Override git ref to checkout of build-emacs-for-macos"
required: false
default: ""
extraBuildArgs:
Description: "Extra build args"
builder_args:
description: Custom arguments passed to build script
required: false
default: ""
extraReleaseArgs:
Description: "Extra release args"
test_build_name:
description: "Test build name"
required: false
default: ""
test_release_type:
description: "prerelease or draft"
required: false
default: ""
build_variant:
description: "Optional build number used as version suffix"
required: false
type: string
x86_64:
description: "Build x86_64 version of Emacs"
required: false
default: true
type: boolean
arm64:
description: "Build arm64 version of Emacs"
required: false
default: true
type: boolean
jobs:
build-and-publish:
runs-on: macos-10.15
steps:
- name: Checkout emacs-builds repo
uses: actions/checkout@v2
with:
path: releaser
- name: Checkout build-emacs-for-macos repo
uses: actions/checkout@v2
with:
repository: jimeh/build-emacs-for-macos
ref: "0.4.11"
path: builder
- uses: ruby/setup-ruby@v1
with:
ruby-version: 2.7
- uses: actions/setup-go@v2
with:
go-version: 1.16
- name: Compile github-release tool
run: >-
go build -o ./github-release ./cmd/github-release
working-directory: releaser
- name: Plan build
run: >-
./releaser/github-release --plan plan.yml plan
--work-dir '${{ github.workspace }}'
${{ github.event.inputs.extraPlanArgs }}
${{ github.event.inputs.gitRef }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Show plan
run: >-
cat plan.yml
- name: Check if planned release and asset already exist
id: check
continue-on-error: true
run: >-
./releaser/github-release --plan plan.yml check
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Install dependencies
if: steps.check.outcome == 'failure'
run: >-
brew bundle --file=builder/Brewfile
- name: Build Emacs
if: steps.check.outcome == 'failure'
run: >-
./builder/build-emacs-for-macos --plan=plan.yml
--work-dir '${{ github.workspace }}'
--native-full-aot
${{ github.event.inputs.extraReleaseArgs }}
- name: Publish release
if: steps.check.outcome == 'failure'
run: >-
./releaser/github-release --plan plan.yml publish
${{ github.event.inputs.extraReleaseArgs }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
build:
name: Build
uses: ./.github/workflows/_build.yml
with:
git_ref: ${{ inputs.git_ref }}
git_sha: ${{ inputs.git_sha }}
builder_ref: ${{ inputs.builder_ref }}
builder_args: ${{ inputs.builder_args }}
build_variant: ${{ inputs.build_variant }}
test_build_name: ${{ inputs.test_build_name }}
test_release_type: ${{ inputs.test_release_type }}
x86_64: ${{ inputs.x86_64 }}
arm64: ${{ inputs.arm64 }}
secrets: inherit

19
.github/workflows/nightly-master.yml vendored Normal file
View File

@@ -0,0 +1,19 @@
---
name: Nightly (master)
on:
schedule:
- cron: "0 23 * * *"
workflow_dispatch:
inputs:
git_sha:
description: Override Emacs git commit SHA to build
required: false
jobs:
build:
name: Build
uses: ./.github/workflows/_build.yml
with:
git_ref: "master"
git_sha: ${{ inputs.git_sha }}
secrets: inherit

35
.github/workflows/update-metadata.yml vendored Normal file
View File

@@ -0,0 +1,35 @@
---
name: Update Metadata
concurrency: jimeh/emacs-builds/update-metadata
on:
schedule:
- cron: "0 0 * * *"
workflow_dispatch:
jobs:
update-metadata:
runs-on: ubuntu-latest
steps:
- name: Checkout meta branch
uses: actions/checkout@v4
with:
ref: meta
- uses: actions/setup-go@v5
with:
go-version: "1.23"
- name: update total downloads shield JSON
run: >-
go run . badges downloads
--output total-downloads/shield.json
--cache total-downloads/.cache.json
env:
GITHUB_TOKEN: ${{ github.token }}
- name: commit and push changes to meta branch
uses: stefanzweifel/git-auto-commit-action@v5
with:
commit_message: "chore(meta): update metadata files"
commit_user_name: github-actions[bot]
commit_user_email: github-actions[bot]@users.noreply.github.com
commit_author: >-
github-actions[bot] <github-actions[bot]@users.noreply.github.com>
skip_dirty_check: false

232
README.md
View File

@@ -1,105 +1,219 @@
<p align="center">
<img width="192px" src="https://github.com/emacs-mirror/emacs/raw/emacs-27.2/etc/images/icons/hicolor/scalable/apps/emacs.svg" alt="Logo">
</p>
<div align="center">
<h1 align="center">
Emacs Builds
</h1>
<img width="196px" src="https://raw.githubusercontent.com/jimeh/emacs-liquid-glass-icons/main/Icons/Exports/EmacsLG1-Default.iconset/icon_512x512.png" alt="Logo">
<p align="center">
<a href="https://github.com/jimeh/emacs-builds/releases">
<img src="https://img.shields.io/github/v/tag/jimeh/emacs-builds?label=nightly" alt="GitHub tag (latest SemVer)">
</a>
<a href="https://github.com/jimeh/emacs-builds/issues">
<img src="https://img.shields.io/github/issues-raw/jimeh/emacs-builds.svg?style=flat&logo=github&logoColor=white"
alt="GitHub issues">
</a>
<a href="https://github.com/jimeh/emacs-builds/pulls">
<img src="https://img.shields.io/github/issues-pr-raw/jimeh/emacs-builds.svg?style=flat&logo=github&logoColor=white" alt="GitHub pull requests">
</a>
</p>
# Emacs Builds
<p align="center">
<strong>
Nightly binary builds of Emacs for macOS as a self-contained Emacs.app,
with native-compilation.
</strong>
</p>
[![GitHub release (stable)](https://img.shields.io/endpoint?url=https%3A%2F%2Fraw.githubusercontent.com%2Fjimeh%2Fhomebrew-emacs-builds%2Fmeta%2FCasks%2Femacs-app%2Fshield.json)](https://github.com/jimeh/emacs-builds/releases/latest)
[![GitHub release (pretest)](https://img.shields.io/endpoint?url=https%3A%2F%2Fraw.githubusercontent.com%2Fjimeh%2Fhomebrew-emacs-builds%2Fmeta%2FCasks%2Femacs-app-pretest%2Fshield.json)](https://github.com/jimeh/emacs-builds/releases?q=pretest&expanded=true)
[![GitHub release (nightly)](https://img.shields.io/endpoint?url=https%3A%2F%2Fraw.githubusercontent.com%2Fjimeh%2Fhomebrew-emacs-builds%2Fmeta%2FCasks%2Femacs-app-nightly%2Fshield.json)](https://github.com/jimeh/emacs-builds/releases?q=master&expanded=true)
[![GitHub release (monthly)](https://img.shields.io/endpoint?url=https%3A%2F%2Fraw.githubusercontent.com%2Fjimeh%2Fhomebrew-emacs-builds%2Fmeta%2FCasks%2Femacs-app-monthly%2Fshield.json)](https://github.com/jimeh/emacs-builds/releases?q=master&expanded=true)
[![GitHub release (known good nightly)](https://img.shields.io/endpoint?url=https%3A%2F%2Fraw.githubusercontent.com%2Fjimeh%2Fhomebrew-emacs-builds%2Fmeta%2FCasks%2Femacs-app-good%2Fshield.json)](https://github.com/jimeh/emacs-builds/issues/7)
[![GitHub issues](https://img.shields.io/github/issues-raw/jimeh/emacs-builds?style=flat&logo=github&logoColor=white)](https://github.com/jimeh/emacs-builds/issues)
[![GitHub pull requests](https://img.shields.io/github/issues-pr-raw/jimeh/emacs-builds?style=flat&logo=github&logoColor=white)](https://github.com/jimeh/emacs-builds/pulls)
[![GitHub all releases](https://img.shields.io/endpoint?url=https%3A%2F%2Fraw.githubusercontent.com%2Fjimeh%2Femacs-builds%2Fmeta%2Ftotal-downloads%2Fshield.json)](https://github.com/jimeh/emacs-builds/releases)
**Self-contained Emacs.app builds for macOS, with native-compilation support.**
</div>
## Features
- Self-contained Emacs.app application bundle, with no external dependencies,
built with the [jimeh/build-emacs-for-macos][] build script.
- Native-compilation is enabled in nightly builds from the `master` branch of
Emacs, and should just work without the need to install GCC, libgccjit, or any
other dependencies.
- Includes the [fix-window-role][] and [system-appearance][] patches from the
excellent [emacs-plus][] project.
- Self-contained Emacs.app application bundle, with no external dependencies.
- Native compilation ([gccemacs][]).
- Native JSON parsing.
- SVG rendering via librsvg.
- Various image formats are supported via macOS native image APIs.
- Xwidget-webkit support, allowing access to a embedded WebKit-based browser
with `M-x xwidget-webkit-browse-url`.
- Native XML parsing via libxml2.
- Dynamic module loading.
- Includes the [fix-window-role][], [system-appearance][], and
[round-undecorated-frame][] patches from the excellent [emacs-plus][] project.
- Emacs source is fetched from the [emacs-mirror/emacs][] GitHub repository.
- Build creation is transparent and public through the use of GitHub Actions,
allowing anyone to inspect git commit SHAs, full source code, and exact
commands used to produce a build. This is especially important right now as
builds are not yet signed and notarized.
commands used to produce a build.
- Emacs.app is signed with a developer certificate and notarized by Apple.
- Uses [build-emacs-for-macos][] to build the self-contained application bundle.
[jimeh/build-emacs-for-macos]: https://github.com/jimeh/build-emacs-for-macos
[build-emacs-for-macos]: https://github.com/jimeh/build-emacs-for-macos
[gccemacs]: https://www.emacswiki.org/emacs/GccEmacs
[fix-window-role]:
https://github.com/d12frosted/homebrew-emacs-plus/blob/master/patches/emacs-28/fix-window-role.patch
[system-appearance]:
https://github.com/d12frosted/homebrew-emacs-plus/blob/master/patches/emacs-28/system-appearance.patch
[round-undecorated-frame]:
https://github.com/d12frosted/homebrew-emacs-plus/blob/master/patches/emacs-29/round-undecorated-frame.patch
[emacs-plus]: https://github.com/d12frosted/homebrew-emacs-plus
[emacs-mirror/emacs]: https://github.com/emacs-mirror/emacs
## System Requirements
- Intel-based Mac running macOS 10.15.x or later.
- Builds produced after 2024-11-30:
- macOS 11 or later.
- Builds produced before 2024-11-30:
- macOS 13 Ventura or later for Apple Silicon builds.
- macOS 12 Monterey or later for Intel builds.
- Xcode Command Line Tools to use native compilation in Emacs, available since
Emacs 28.x builds.
## Downloads
## Installation
See the [Releases][] page to download latest builds.
### Manual Download
Nightly builds of Emacs are for the part just fine, but if you don't like living
too close to the edge, see issue [#7 Known Good Nightly Builds][7] for a list of
recent nightly builds which have been actively used by a living being without
any issues.
See the [Releases][] page to download latest builds, or [here][latest] for the
latest stable release.
Nightly builds of Emacs are for the most part just fine, but if you don't like
living too close to the edge, see issue [#7 Known Good Nightly Builds][7] for a
list of recent nightly builds which have been actively used by a living being
for at least a day or two without any obvious issues.
[releases]: https://github.com/jimeh/emacs-builds/releases
[latest]: https://github.com/jimeh/emacs-builds/releases/latest
[7]: https://github.com/jimeh/emacs-builds/issues/7
### Homebrew Cask
The [`jimeh/emacs-builds`](https://github.com/jimeh/homebrew-emacs-builds)
Homebrew Tap provides the following casks:
- `jimeh/emacs-builds/emacs-app` — Latest stable release of Emacs.
```bash
brew install --cask jimeh/emacs-builds/emacs-app
```
- `jimeh/emacs-builds/emacs-app-pretest` — Latest pretest build of Emacs.
```bash
brew install --cask jimeh/emacs-builds/emacs-app-pretest
```
- `jimeh/emacs-builds/emacs-app-nightly` — Build of Emacs from the `master`
branch, updated every night.
```bash
brew install --cask jimeh/emacs-builds/emacs-app-nightly
```
- `jimeh/emacs-builds/emacs-app-monthly` — Build of Emacs from the `master`
branch, updated on the 1st of each month.
```bash
brew install --cask jimeh/emacs-builds/emacs-app-monthly
```
- `jimeh/emacs-builds/emacs-app-good` for the latest known good nightly build
listed on [#7][7]:
```bash
brew install --cask jimeh/emacs-builds/emacs-app-good
```
## Apple Silicon
As of 2024-11-30, all builds include both Apple Silicon (arm64) and Intel
(x86_64) artifacts.
## Use Emacs.app as `emacs` CLI Tool
### Installed via Homebrew Cask
The cask installation method sets up CLI usage automatically by exposing a
`emacs` command. However it will launch Emacs into GUI mode. To instead have
`emacs` in your terminal open a terminal instance of Emacs, add the following
alias to your shell setup:
```bash
alias emacs="emacs -nw"
```
### Installed Manually
Builds come with a custom `emacs` shell script launcher for use from the command
line, located next to `emacsclient` in `Emacs.app/Contents/MacOS/bin`.
The custom `emacs` script makes sure to use the main
`Emacs.app/Contents/MacOS/Emacs` executable from the correct path, ensuring it
finds all the relevant dependencies within the Emacs.app bundle, regardless of
if it's exposed via `PATH` or symlinked from elsewhere.
To use it, simply add `Emacs.app/Contents/MacOS/bin` to your `PATH`. For
example, if you place Emacs.app in `/Applications`:
```bash
if [ -d "/Applications/Emacs.app/Contents/MacOS/bin" ]; then
export PATH="/Applications/Emacs.app/Contents/MacOS/bin:$PATH"
alias emacs="emacs -nw" # Always launch "emacs" in terminal mode.
fi
```
If you want `emacs` in your terminal to launch a GUI instance of Emacs, don't
use the alias from the above example.
## Build Process
Building Emacs is done using the [jimeh/build-emacs-for-macos][] build script,
executed within a GitHub Actions [workflow][]. This is why macOS 10.15.x or
later is required, as it's the oldest version of macOS available in GitHub
Actions.
[workflow]:
https://github.com/jimeh/emacs-builds/blob/main/.github/workflows/build.yml
Full history for all builds is available on GitHub Actions [here][actions].
executed within a GitHub Actions [workflow][].
[jimeh/build-emacs-for-macos]: https://github.com/jimeh/build-emacs-for-macos
[workflow]:
https://github.com/jimeh/emacs-builds/blob/main/.github/workflows/nightly-master.yml
Full history for all builds is available on GitHub Actions [here][actions].
Build logs are only retained by GitHub for 90 days though.
[actions]: https://github.com/jimeh/emacs-builds/actions
Nightly builds are scheduled for 0:00 UTC every night, based on the latest
Nightly builds are scheduled for 23:00 UTC every night, based on the latest
commit from the `master` branch of the [emacs-mirror/emacs][] repository. This
means a nightly build will only be produced if there have been new commits since
the last nightly build.
[emacs-mirror/emacs]: https://github.com/emacs-mirror/emacs
## Application Signing / Trust
## Untrusted Application
As of June 21st, 2021, all builds are fully signed and notarized. The signing
certificate used is: `Developer ID Application: Jim Myhrberg (5HX66GF82Z)`
Currently builds are not signed or notarized, meaning macOS cannot verify
Emacs.app came from a trusted developer, and by default you are not given an
option to trust the app and open it.
To verify the application signature and notarization, you can use `spctl`:
Simplest way around this is to right-click (or control-click) on the Emacs app
in Finder and select "Open". You will then be given the same warning as before,
but with a "Open" button now available to trust and open the app. After that you
can open the application like normal without any warnings.
```bash
$ spctl -vvv --assess --type exec /Applications/Emacs.app
/Applications/Emacs.app: accepted
source=Notarized Developer ID
origin=Developer ID Application: Jim Myhrberg (5HX66GF82Z)
```
All builds also come with a SHA256 checksum file, which itself can be double
checked against the SHA256 checksum log output from the packaging step of the
GitHub Actions workflow run which produced the build.
## Issues / To-Do
Please see [Issues][] for details of things to come, or to report issues.
[issues]: https://github.com/jimeh/emacs-builds/issues
## News / Recent Changes
### 2024-12-01 — Apple Silicon builds all the time, more stability via Nix
GitHub's standard runner for macOS 14 and later runs on Apple Silicon, and are
free to use for public repositories. As such we now use `runs-on: macos-13` for
Intel builds, and `runs-on: macos-14` for Apple Silicon builds. And we do so on
all builds, nightlies, pretests, and stable.
Additionally, macOS 11 Big Sur is now the minimum required version again, for
both Intel and Apple Silicon builds. This is due to switching from Homebrew to
Nix for managing build-time dependencies. And it supports easily switching
between different macOS SDK versions, meaning we can target an SDK that is older
than the OS we are creating the builds on.
### 2023-11-22 — Apple Silicon builds, drop macOS 11 support
Apple Silicon builds are now available, but limited to stable releases, and
nightly builds on the 1st of each month due to the cost of using M1-based
runners on GitHub Actions. Apple Silicon builds also require macOS 13 Ventura,
as that is the oldest macOS version available on M1-based runners.
Additionally, Intel builds minimum required macOS version has been increased
from macOS 11 Big Sur, to macOS 12 Monterey. This was needed as Homebrew no
longer supports Big Sur, leading to very lengthy and error prone builds as all
Homebrew dependencies had to be installed from source.
If dropping support for macOS 11 turns out to be a big issue, it may be possible
to offer macOS 11 compatible builds on a less frequent schedule similar to what
we're doing with Apple Silicon.

248
cmd/dylib-tree/main.go Normal file
View File

@@ -0,0 +1,248 @@
package main
import (
"debug/macho"
"fmt"
"os"
"path/filepath"
"regexp"
"strings"
"github.com/urfave/cli/v2"
"github.com/xlab/treeprint"
)
var app = &cli.App{
Name: "dylib-tree",
Usage: "recursive list shared-libraries as a tree",
UsageText: "dylib-tree [options] <binary-file> [<binary-file>]",
Flags: []cli.Flag{
&cli.IntFlag{
Name: "depth",
Usage: "max depth of tree (default: 0 = unlimited)",
Value: 0,
},
&cli.StringSliceFlag{
Name: "ignore",
Usage: "path patterns to ignore",
},
&cli.BoolFlag{
Name: "ignore-system",
Usage: "ignore system libraries",
},
&cli.BoolFlag{
Name: "real-path",
Usage: "show resolved full paths instead of @executable_path " +
"and @rpath",
},
},
Action: actionHandler(LinkTreeCmd),
}
type Context struct {
Root string
ExecutablePath string
Depth int
MaxDepth int
RealPath bool
Ignore []string
RPaths []string
}
func (s *Context) WithFile(filename string) *Context {
ctx := *s
ctx.Root = filename
ctx.ExecutablePath = filepath.Dir(filename)
return &ctx
}
func (s *Context) WithDepth(depth int) *Context {
ctx := *s
ctx.Depth = depth
return &ctx
}
func (s *Context) WithIgnore(ignore []string) *Context {
ctx := *s
ctx.Ignore = append(ctx.Ignore, ignore...)
return &ctx
}
func (s *Context) WithRpaths(rpaths []string) *Context {
ctx := *s
ctx.RPaths = append(ctx.RPaths, rpaths...)
return &ctx
}
func actionHandler(
f func(*cli.Context, *Context) error,
) func(*cli.Context) error {
return func(c *cli.Context) error {
ignore := c.StringSlice("ignore")
if c.Bool("ignore-system") {
ignore = append(
ignore,
"/System/Library/*",
"*/libSystem.*.dylib",
"*/libobjc.*.dylib",
)
}
ctx := &Context{
Ignore: ignore,
MaxDepth: c.Int("depth"),
RealPath: c.Bool("real-path"),
}
return f(c, ctx)
}
}
func LinkTreeCmd(c *cli.Context, ctx *Context) error {
for _, filename := range c.Args().Slice() {
ctx := ctx.WithFile(filename)
treeRoot := treeprint.New()
tree := treeRoot.AddBranch(filename)
err := processBinary(&tree, ctx, filename)
if err != nil {
return err
}
fmt.Println(treeRoot.String())
}
return nil
}
func processBinary(
parent *treeprint.Tree,
ctx *Context,
filename string,
) error {
f, err := macho.Open(filename)
if err != nil {
return err
}
ctx = ctx.WithDepth(ctx.Depth + 1).WithRpaths(getRpaths(f))
if ctx.MaxDepth > 0 && ctx.Depth > ctx.MaxDepth {
return nil
}
libs, err := f.ImportedLibraries()
if err != nil {
return err
}
for _, lib := range libs {
skip, err := ignoreLib(ctx, lib)
if err != nil {
return err
}
if skip {
continue
}
filename, err := resolveLibFilename(ctx, lib)
if err != nil {
(*parent).AddBranch(lib)
continue
}
skip, err = ignoreLib(ctx, filename)
if err != nil {
return err
}
if skip {
continue
}
displayName := lib
if ctx.RealPath {
displayName = filename
}
tree := (*parent).AddBranch(displayName)
err = processBinary(&tree, ctx, filename)
if err != nil {
return err
}
}
return nil
}
func ignoreLib(ctx *Context, lib string) (bool, error) {
for _, pattern := range ctx.Ignore {
m, err := ignoreRegexp(pattern)
if err != nil {
return false, err
}
if m.MatchString(lib) {
return true, nil
}
}
return false, nil
}
func ignoreRegexp(p string) (*regexp.Regexp, error) {
rp := "^" + regexp.QuoteMeta(p) + "$"
rp = strings.ReplaceAll(rp, `\*`, ".*")
rp = strings.ReplaceAll(rp, `\?`, ".")
return regexp.Compile(rp)
}
func resolveLibFilename(ctx *Context, lib string) (string, error) {
filename := lib
if strings.HasPrefix(lib, "@executable_path") {
filename = filepath.Join(ctx.ExecutablePath, lib[16:])
} else if strings.HasPrefix(lib, "@rpath") {
for _, r := range ctx.RPaths {
if strings.HasPrefix(r, "@executable_path") {
r = filepath.Join(ctx.ExecutablePath, r[16:])
}
rfile := filepath.Join(r, lib[6:])
_, err := os.Stat(rfile)
if err != nil {
continue
}
return rfile, nil
}
return "", fmt.Errorf("could not find %s", lib)
}
_, err := os.Stat(filename)
return filename, err
}
func getRpaths(f *macho.File) []string {
paths := []string{}
for _, i := range f.Loads {
if r, ok := i.(*macho.Rpath); ok {
paths = append(paths, r.Path)
}
}
return paths
}
func main() {
err := app.Run(os.Args)
if err != nil {
fmt.Fprintf(os.Stderr, "ERROR: %s\n", err.Error())
os.Exit(1)
}
}

View File

@@ -1,57 +0,0 @@
package main
import (
"fmt"
"net/http"
"path/filepath"
"github.com/urfave/cli/v2"
)
func checkCmd() *cli.Command {
return &cli.Command{
Name: "check",
Usage: "Check if GitHub release and asset exists",
UsageText: "github-release [global options] check [options]",
Action: actionHandler(checkAction),
}
}
func checkAction(c *cli.Context, opts *globalOptions) error {
gh := opts.gh
repo := opts.repo
plan, err := LoadPlan(opts.plan)
if err != nil {
return err
}
fmt.Printf(
"==> Checking github.com/%s for release: %s\n",
repo.String(), plan.Release,
)
release, resp, err := gh.Repositories.GetReleaseByTag(
c.Context, repo.Owner, repo.Name, plan.Release,
)
if err != nil {
if resp.StatusCode == http.StatusNotFound {
return fmt.Errorf("release %s does not exist", plan.Release)
} else {
return err
}
}
fmt.Println(" -> Release exists")
filename := filepath.Base(plan.Archive)
fmt.Printf("==> Checking release for asset: %s\n", filename)
for _, a := range release.Assets {
if a.Name != nil && filename == *a.Name {
fmt.Println(" -> Asset exists")
return nil
}
}
return fmt.Errorf("release does contain asset: %s", filename)
}

View File

@@ -1,46 +0,0 @@
package main
import (
"fmt"
"time"
"github.com/google/go-github/v35/github"
)
type Commit struct {
Repo *Repo `yaml:"repo"`
Ref string `yaml:"ref"`
SHA string `yaml:"sha"`
Date *time.Time `yaml:"date"`
Author string `yaml:"author"`
Committer string `yaml:"committer"`
Message string `yaml:"message"`
}
func NewCommit(repo *Repo, ref string, rc *github.RepositoryCommit) *Commit {
return &Commit{
Repo: repo,
Ref: ref,
SHA: rc.GetSHA(),
Date: rc.GetCommit().GetCommitter().Date,
Author: fmt.Sprintf(
"%s <%s>",
rc.GetCommit().GetAuthor().GetName(),
rc.GetCommit().GetAuthor().GetEmail(),
),
Committer: fmt.Sprintf(
"%s <%s>",
rc.GetCommit().GetCommitter().GetName(),
rc.GetCommit().GetCommitter().GetEmail(),
),
Message: rc.GetCommit().GetMessage(),
}
}
func (s *Commit) ShortSHA() string {
return s.SHA[0:7]
}
func (s *Commit) DateString() string {
return s.Date.Format("2006-01-02")
}

View File

@@ -1,22 +0,0 @@
package main
import (
"context"
"net/http"
"github.com/google/go-github/v35/github"
"golang.org/x/oauth2"
)
func NewGitHubClient(ctx context.Context, token string) *github.Client {
var tc *http.Client
if token != "" {
ts := oauth2.StaticTokenSource(
&oauth2.Token{AccessToken: token},
)
tc = oauth2.NewClient(ctx, ts)
}
return github.NewClient(tc)
}

View File

@@ -1,74 +0,0 @@
package main
import (
"fmt"
"os"
"github.com/google/go-github/v35/github"
"github.com/urfave/cli/v2"
)
var app = &cli.App{
Name: "github-release",
Usage: "manage GitHub releases",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "github-token",
Aliases: []string{"t"},
Usage: "GitHub API Token (read from GITHUB_TOKEN if set)",
},
&cli.StringFlag{
Name: "release-repo",
Aliases: []string{"r"},
Usage: "Owner/name of GitHub repo to publish releases to",
EnvVars: []string{"GITHUB_REPOSITORY"},
Value: "jimeh/emacs-builds",
},
&cli.PathFlag{
Name: "plan",
Aliases: []string{"p"},
Usage: "Load plan from `FILE`",
EnvVars: []string{"BUILD_PLAN"},
Required: true,
TakesFile: true,
},
},
Commands: []*cli.Command{
checkCmd(),
publishCmd(),
planCmd(),
},
}
type globalOptions struct {
gh *github.Client
repo *Repo
plan string
}
func actionHandler(
f func(*cli.Context, *globalOptions) error,
) func(*cli.Context) error {
return func(c *cli.Context) error {
token := c.String("github-token")
if t := os.Getenv("GITHUB_TOKEN"); t != "" {
token = t
}
opts := &globalOptions{
gh: NewGitHubClient(c.Context, token),
repo: NewRepo(c.String("release-repo")),
plan: c.String("plan"),
}
return f(c, opts)
}
}
func main() {
err := app.Run(os.Args)
if err != nil {
fmt.Fprintf(os.Stderr, "ERROR: %s\n", err.Error())
os.Exit(1)
}
}

View File

@@ -1,40 +0,0 @@
package main
import (
"os/exec"
"strings"
)
type OSInfo struct {
Name string `yaml:"name"`
Version string `yaml:"version"`
Arch string `yaml:"arch"`
}
func NewOSInfo() (*OSInfo, error) {
version, err := exec.Command("sw_vers", "-productVersion").CombinedOutput()
if err != nil {
return nil, err
}
arch, err := exec.Command("uname", "-m").CombinedOutput()
if err != nil {
return nil, err
}
return &OSInfo{
Name: "macOS",
Version: strings.TrimSpace(string(version)),
Arch: strings.TrimSpace(string(arch)),
}, nil
}
func (s *OSInfo) ShortVersion() string {
parts := strings.Split(s.Version, ".")
max := len(parts)
if max > 2 {
max = 2
}
return strings.Join(parts[0:max], ".")
}

View File

@@ -1,26 +0,0 @@
package main
import (
"os"
"gopkg.in/yaml.v3"
)
type Plan struct {
Commit *Commit `yaml:"commit"`
OS *OSInfo `yaml:"os"`
Release string `yaml:"release"`
Archive string `yaml:"archive"`
}
func LoadPlan(filename string) (*Plan, error) {
b, err := os.ReadFile(filename)
if err != nil {
return nil, err
}
plan := &Plan{}
err = yaml.Unmarshal(b, plan)
return plan, err
}

View File

@@ -1,110 +0,0 @@
package main
import (
"bytes"
"fmt"
"os"
"path/filepath"
"regexp"
"github.com/urfave/cli/v2"
"gopkg.in/yaml.v3"
)
var nonAlphaNum = regexp.MustCompile(`[^\w-_]+`)
func planCmd() *cli.Command {
wd, err := os.Getwd()
if err != nil {
wd = ""
}
return &cli.Command{
Name: "plan",
Usage: "Plan if GitHub release and asset exists",
UsageText: "github-release [global options] plan [<branch/tag>]",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "emacs-mirror-repo",
Usage: "Github owner/repo to get Emacs commit info from",
Aliases: []string{"e"},
EnvVars: []string{"EMACS_MIRROR_REPO"},
Value: "emacs-mirror/emacs",
},
&cli.StringFlag{
Name: "work-dir",
Usage: "Github owner/repo to get Emacs commit info from",
Value: wd,
},
&cli.StringFlag{
Name: "sha",
Usage: "Override commit SHA of specified git branch/tag",
},
},
Action: actionHandler(planAction),
}
}
func planAction(c *cli.Context, opts *globalOptions) error {
gh := opts.gh
planFile := opts.plan
repo := NewRepo(c.String("emacs-mirror-repo"))
buildsDir := filepath.Join(c.String("work-dir"), "builds")
ref := c.Args().Get(0)
if ref == "" {
ref = "master"
}
lookupRef := ref
if s := c.String("sha"); s != "" {
lookupRef = s
}
repoCommit, _, err := gh.Repositories.GetCommit(
c.Context, repo.Owner, repo.Name, lookupRef,
)
if err != nil {
return err
}
commit := NewCommit(repo, ref, repoCommit)
osInfo, err := NewOSInfo()
if err != nil {
return err
}
cleanRef := sanitizeString(ref)
cleanOS := sanitizeString(osInfo.Name + "-" + osInfo.ShortVersion())
cleanArch := sanitizeString(osInfo.Arch)
releaseName := fmt.Sprintf(
"Emacs.%s.%s.%s",
commit.DateString(), commit.ShortSHA(), cleanRef,
)
archiveName := fmt.Sprintf(
"Emacs.%s.%s.%s.%s.%s.tbz",
commit.DateString(), commit.ShortSHA(), cleanRef, cleanOS, cleanArch,
)
plan := &Plan{
Commit: commit,
OS: osInfo,
Release: releaseName,
Archive: filepath.Join(buildsDir, archiveName),
}
buf := bytes.Buffer{}
enc := yaml.NewEncoder(&buf)
enc.SetIndent(2)
err = enc.Encode(plan)
if err != nil {
return err
}
return os.WriteFile(planFile, buf.Bytes(), 0666)
}
func sanitizeString(s string) string {
return nonAlphaNum.ReplaceAllString(s, "-")
}

View File

@@ -1,178 +0,0 @@
package main
import (
"crypto/sha256"
"fmt"
"io"
"net/http"
"os"
"path/filepath"
"github.com/google/go-github/v35/github"
"github.com/urfave/cli/v2"
)
func publishCmd() *cli.Command {
return &cli.Command{
Name: "publish",
Usage: "publish a release",
UsageText: "github-release [global-options] publish [options]",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "release-sha",
Aliases: []string{"s"},
Usage: "Git SHA of repo to create release on",
EnvVars: []string{"GITHUB_SHA"},
},
&cli.BoolFlag{
Name: "prerelease",
Usage: "Git SHA of repo to create release on",
EnvVars: []string{"RELEASE_PRERELEASE"},
Value: false,
},
},
Action: actionHandler(publishAction),
}
}
func publishAction(c *cli.Context, opts *globalOptions) error {
gh := opts.gh
repo := opts.repo
plan, err := LoadPlan(opts.plan)
if err != nil {
return err
}
releaseSHA := c.String("release-sha")
prerelease := c.Bool("prerelease")
assetBaseName := filepath.Base(plan.Archive)
assetSumFile := plan.Archive + ".sha256"
if _, err := os.Stat(assetSumFile); os.IsNotExist(err) {
fmt.Printf("==> Generating SHA256 sum for %s\n", assetBaseName)
assetSum, err := fileSHA256(plan.Archive)
if err != nil {
return err
}
content := fmt.Sprintf("%s %s", assetSum, assetBaseName)
err = os.WriteFile(assetSumFile, []byte(content), 0666)
if err != nil {
return err
}
fmt.Printf(" -> Done: %s\n", assetSum)
}
fmt.Printf("==> Checking release %s\n", plan.Release)
release, resp, err := gh.Repositories.GetReleaseByTag(
c.Context, repo.Owner, repo.Name, plan.Release,
)
if err != nil {
if resp.StatusCode == http.StatusNotFound {
fmt.Println(" -> Release not found, creating...")
release, _, err = gh.Repositories.CreateRelease(
c.Context, repo.Owner, repo.Name, &github.RepositoryRelease{
Name: &plan.Release,
TagName: &plan.Release,
TargetCommitish: &releaseSHA,
Prerelease: &prerelease,
},
)
if err != nil {
return err
}
} else {
return err
}
}
if release.GetPrerelease() != prerelease {
release.Prerelease = &prerelease
release, _, err = gh.Repositories.EditRelease(
c.Context, repo.Owner, repo.Name, release.GetID(), release,
)
if err != nil {
return err
}
}
assetFiles := []string{plan.Archive, assetSumFile}
for _, fileName := range assetFiles {
fileIO, err := os.Open(fileName)
if err != nil {
return err
}
defer fileIO.Close()
fileInfo, err := fileIO.Stat()
if err != nil {
return err
}
fileBaseName := filepath.Base(fileName)
assetExists := false
fmt.Printf("==> Checking asset %s\n", fileBaseName)
for _, a := range release.Assets {
if a.GetName() != fileBaseName {
continue
}
if a.GetSize() == int(fileInfo.Size()) {
fmt.Println(" -> Asset already exists")
assetExists = true
} else {
fmt.Println(
" -> Asset exists with wrong file size, deleting...",
)
_, err := gh.Repositories.DeleteReleaseAsset(
c.Context, repo.Owner, repo.Name, a.GetID(),
)
if err != nil {
return err
}
fmt.Println(" -> Done")
}
}
if !assetExists {
fmt.Println(" -> Asset missing, uploading...")
_, _, err = gh.Repositories.UploadReleaseAsset(
c.Context, repo.Owner, repo.Name, release.GetID(),
&github.UploadOptions{Name: fileBaseName},
fileIO,
)
if err != nil {
return err
}
fmt.Println(" -> Done")
}
}
fmt.Printf("==> Release available at: %s\n", release.GetHTMLURL())
return nil
}
func fileSHA256(filename string) (string, error) {
f, err := os.Open(filename)
if err != nil {
return "", err
}
defer f.Close()
h := sha256.New()
if _, err := io.Copy(h, f); err != nil {
return "", err
}
return fmt.Sprintf("%x", h.Sum(nil)), nil
}

View File

@@ -1,26 +0,0 @@
package main
import (
"fmt"
"strings"
)
type Repo struct {
URL string `yaml:"url"`
Owner string `yaml:"owner"`
Name string `yaml:"name"`
}
func NewRepo(ownerAndRepo string) *Repo {
parts := strings.SplitN(ownerAndRepo, "/", 2)
return &Repo{
URL: fmt.Sprintf("https://github.com/%s/%s", parts[0], parts[1]),
Owner: parts[0],
Name: parts[1],
}
}
func (s *Repo) String() string {
return s.Owner + "/" + s.Name
}

3
go.mod
View File

@@ -1,10 +1,11 @@
module github.com/jimeh/build-emacs
module github.com/jimeh/emacs-builds
go 1.16
require (
github.com/google/go-github/v35 v35.1.0
github.com/urfave/cli/v2 v2.3.0
github.com/xlab/treeprint v1.1.0
golang.org/x/oauth2 v0.0.0-20210427180440-81ed05c6b58c
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
)

6
go.sum
View File

@@ -41,6 +41,7 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
@@ -121,8 +122,12 @@ github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5I
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M=
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
github.com/xlab/treeprint v1.1.0 h1:G/1DjNkPpfZCFt9CSh6b5/nY4VimlbHF3Rh4obvtzDk=
github.com/xlab/treeprint v1.1.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
@@ -368,6 +373,7 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=