-
-
Notifications
You must be signed in to change notification settings - Fork 690
Expand file tree
/
Copy pathaction.yml
More file actions
132 lines (111 loc) · 6.75 KB
/
action.yml
File metadata and controls
132 lines (111 loc) · 6.75 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
name: Universal package
description: Create universal Homebrew package which contains x86_64 and arm64
# Instead of using the default binary installed by Homebrew, we need to build our own because third-party libraries are
# statically linked in MacVim, and need to be built against MACOSX_DEPLOYMENT_TARGET to ensure the built binary will
# work on supported macOS versions. Another reason for building our own custom package is to build a unviersal binary
# that has both x86_64 and arm64 arch, as Homebrew's distributed bottles are thin binaries with only one arch.
#
# We still use Homebrew to manage the library because their formulas are up to date and have correct build instructions
# that will work. This way we don't have to manually configure, build, and update the package info.
inputs:
formula:
description: Formula name
required: true
contents:
description: Path for contents in package's keg
required: true
gnuiconv:
description: Use the Homebrew GNU libiconv instead of system one
type: boolean
required: false
runs:
using: 'composite'
steps:
- name: Set up formula
id: setup-formula
shell: bash
run: |
echo '::group::Set up formula'
set -o pipefail
formula=${{ inputs.formula }}
# Need to make sure we get the latest before patching. Otherwise Homebrew may later try to get the latest
# version and stomp what we have here.
brew update
brew cat ${formula} >${formula}.rb
if [[ "${{ inputs.gnuiconv }}" == "true" ]]; then
# Modify formula to build using Homebrew libiconv. Usually just adding "depends_on" is enough, but since we
# override "CC" to use vanilla system clang, we need to manually inject the compilation/link flags to specify
# the locations.
sed -i.bak '/^[[:blank:]]*def install$/i\'$'\n depends_on "libiconv"\n' ${formula}.rb
sed -i.bak '/^[[:blank:]]*def install$/a\'$'\n ENV["CFLAGS"] += " -I'$(brew --prefix)$'/opt/libiconv/include"\n' ${formula}.rb
sed -i.bak '/^[[:blank:]]*def install$/a\'$'\n ENV["LDFLAGS"] += " -L'$(brew --prefix)$'/opt/libiconv/lib"\n' ${formula}.rb
fi
# Patch the official Homebrew formula to explicitly build for min deployment target and a universal binary. We
# also need to explicitly use system Clang because Homebrew's bundled clang script tries to inject -march
# compiler flags that will cause universal builds to fail as Clang does not like that.
sed -i.bak '/^[[:blank:]]*def install$/a\'$'\n ENV["MACOSX_DEPLOYMENT_TARGET"] = "'${MACOSX_DEPLOYMENT_TARGET}$'"\n' ${formula}.rb
sed -i.bak '/^[[:blank:]]*def install$/a\'$'\n ENV["CC"] = "/usr/bin/clang"\n' ${formula}.rb
sed -i.bak '/^[[:blank:]]*def install$/a\'$'\n ENV["CFLAGS"] = "-arch x86_64 -arch arm64"\n' ${formula}.rb
sed -i.bak '/^[[:blank:]]*def install$/a\'$'\n ENV["LDFLAGS"] = "-arch x86_64 -arch arm64"\n' ${formula}.rb
# Homebrew requires formula files to be placed in taps and disallows
# installing from raw paths, so we manually create a taps folder for a
# 'macvim-dev/deps' tap.
FORMULA_DIR="$(brew --repository)/Library/Taps/macvim-dev/homebrew-deps/Formula/"
mkdir -p "$FORMULA_DIR"
cp ${formula}.rb "$FORMULA_DIR"
# Uninstall the already installed formula because we want to build our own
brew uninstall --ignore-dependencies ${formula} || true
# Extract Xcode version to serve as part of the key for caching
xcode_version=$(xcodebuild -version | tail -1 | sed -E 's/Build version (.*)/\1/')
echo "xcode_version=$xcode_version" >> $GITHUB_OUTPUT
# Find Homebrew's install location which could be /usr/local or /opt/homebrew
brew_prefix=$(brew --prefix)
echo "brew_prefix=$brew_prefix" >> $GITHUB_OUTPUT
echo '::endgroup::'
- name: Restore keg cache
id: cache-keg-restore
uses: actions/cache/restore@v5
with:
path: ${{ steps.setup-formula.outputs.brew_prefix }}/Cellar/${{ inputs.formula }}
key: ${{ inputs.formula }}-homebrew-cache-custom-unified-prefix${{ steps.setup-formula.outputs.brew_prefix }}-xcode${{ steps.setup-formula.outputs.xcode_version }}-${{ hashFiles(format('{0}.rb', inputs.formula)) }}
- name: Install formula
id: install-formula
shell: bash
run: |
echo '::group::Install formula'
formula=${{ inputs.formula }}
# We don't want brew to go upgrade all our dependents for now. They are
# time consuming and sometimes cause problems with the CI environment
# where they fail to link in random binaries (e.g. Python's 2to3),
# which cause brew install to return non-zero and fail the build.
export HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1
# This will be a no-op if formula was cached. We check if the package
# exists first just to avoid an "already installed" warning.
brew list ${formula} &>/dev/null || brew install --quiet --formula -s macvim-dev/deps/${formula}
# If formula was cached, this step is necessary to relink it to brew prefix (e.g. /usr/local)
# The "-f" is there to force link keg-only formulas. Homebrew doesn't provide a command to just link in the
# optional /opt/homebrew/opt/... folders, so we have to resort to doing this.
brew unlink ${formula} && brew link -f ${formula}
echo '::endgroup::'
echo '::group::Verify built version'
contents=($(IFS=,; for x in ${{ inputs.contents }}; do echo ${x}; done))
for content in "${contents[@]}"; do
# Print out the archs and verify they are universal fat binary.
lipo -info $(brew --prefix)/${content} | grep 'x86_64 arm64'
# Make sure deployment target is correct. Later macOS versions have a different binary format (just search for
# "minos") but for 10.13 we need to look for LC_VERSION_MIN_MACOSX.
otool -l $(brew --prefix)/${content} | grep -A 2 LC_VERSION_MIN_MACOSX | tail -1 | grep "${MACOSX_DEPLOYMENT_TARGET}"
done
echo '::endgroup::'
- name: Save keg cache
id: cache-keg-save
uses: actions/cache/save@v5
# We always save the generated artifact even if the whole run
# fails due to other issues. This helps debugging build
# failure issues faster if the cache doesn't already exist as
# we want subsequent runs to not have to re-generate this
# artifact again.
if: always() && steps.cache-keg-restore.outputs.cache-hit != 'true' && steps.install-formula.conclusion == 'success'
with:
path: ${{ steps.setup-formula.outputs.brew_prefix }}/Cellar/${{ inputs.formula }}
key: ${{ steps.cache-keg-restore.outputs.cache-primary-key }}