11
11
pull_request :
12
12
branches : [master]
13
13
workflow_dispatch :
14
+ inputs :
15
+ make_release :
16
+ default : false
17
+ description : Make a forced release
18
+ required : false
19
+ type : boolean
20
+ workflow_call :
14
21
15
22
jobs :
16
23
build :
17
24
name : Build Magisk artifacts
18
25
runs-on : macos-15
19
- strategy :
20
- fail-fast : false
21
26
steps :
22
27
- name : Check out
23
28
uses : actions/checkout@v4
24
29
with :
30
+ fetch-depth : 0
25
31
submodules : " recursive"
26
32
27
33
- name : Setup environment
28
34
uses : ./.github/actions/setup
29
35
with :
30
36
is-asset-build : true
31
37
38
+ - name : Setup keystores
39
+ run : |
40
+ cat > config.prop<< EOF
41
+ keyStore=key.jks
42
+ keyStorePass=${{ secrets.KEYSTORE_ALIAS_PASSWORD }}
43
+ keyAlias=${{ secrets.KEYSTORE_ALIAS_NAME }}
44
+ keyPass=${{ secrets.KEYSTORE_PASSWORD }}
45
+ EOF
46
+
47
+ echo '${{ secrets.KEYSTORE_FILE }}' > keystore.jks.asc
48
+ gpg -d --passphrase '${{ secrets.KEYSTORE_PASSWORD_GPG }}' --batch keystore.jks.asc > key.jks
49
+
32
50
- name : Build release
33
51
run : ./build.py -vr all
34
52
@@ -45,6 +63,129 @@ jobs:
45
63
path : out
46
64
compression-level : 9
47
65
66
+ - name : Check for Release
67
+ id : check_release
68
+ run : |
69
+ git fetch --all --tags
70
+ DO_RELEASE=false
71
+ IS_PRERELEASE=true
72
+ RELEASE_COMMIT_HASH=""
73
+ COMMIT_RANGE_TO_SCAN=""
74
+
75
+ # Handle forced releases from workflow_dispatch first
76
+ if [[ "${{ inputs.make_release }}" == "true" ]]; then
77
+ DO_RELEASE=true
78
+ RELEASE_COMMIT_HASH=${{ github.sha }}
79
+ echo "Forcing a pre-release due to workflow input for commit $RELEASE_COMMIT_HASH."
80
+ # Handle push and scheduled events
81
+ elif [[ "${{ github.event_name }}" == "push" || "${{ github.event_name }}" == "schedule" ]]; then
82
+ # On a new branch or a force-push, the before..after range is often invalid.
83
+ # In these cases, we fall back to scanning the last N commits from HEAD.
84
+ if [[ "${{ github.event.created }}" == "true" || "${{ github.event.forced }}" == "true" || "${{ github.event_name }}" == "schedule" ]]; then
85
+ if [[ "${{ github.event.created }}" == "true" ]]; then
86
+ echo "New branch detected. Scanning recent commits for a release."
87
+ elif [[ "${{ github.event.forced }}" == "true" ]]; then
88
+ echo "Force push detected. Scanning recent commits for a release."
89
+ else
90
+ echo "Scheduled run detected. Scanning recent commits for missed releases."
91
+ fi
92
+ # Scan the history of the current HEAD. Limit to 20 to be safe.
93
+ COMMIT_RANGE_TO_SCAN="--max-count=20 ${{ github.sha }}"
94
+ else
95
+ # For a normal push to an existing branch, the range is reliable.
96
+ COMMIT_RANGE_TO_SCAN="${{ github.event.before }}..${{ github.sha }}"
97
+ echo "Scanning commit range: $COMMIT_RANGE_TO_SCAN"
98
+ fi
99
+
100
+ # The `|| true` prevents the script from exiting if git log returns a non-zero status (e.g., invalid range)
101
+ # Search for both "Release Magisk" and "Release new canary build" commits
102
+ RELEASE_COMMIT_HASH=$(git log $COMMIT_RANGE_TO_SCAN --grep="Release Magisk" --grep="Release new canary build" -E --max-count=1 --pretty=%H || true)
103
+
104
+ if [[ -n "$RELEASE_COMMIT_HASH" ]]; then
105
+ DO_RELEASE=true
106
+ echo "Found release-triggering commit: $RELEASE_COMMIT_HASH"
107
+ fi
108
+ fi
109
+
110
+ if [[ "$DO_RELEASE" == "true" ]]; then
111
+ LATEST_TAG=$(git describe --tags --exact-match $RELEASE_COMMIT_HASH 2>/dev/null || true)
112
+
113
+ # Determine if this is a stable release based on tag format
114
+ if [[ -n "$LATEST_TAG" && "$LATEST_TAG" =~ ^v[0-9]+\.[0-9]+(\.[0-9]+)?$ ]]; then
115
+ # Major version release (e.g., v28.1, v29.0) - not a pre-release
116
+ IS_PRERELEASE=false
117
+ echo "Detected stable release tag: $LATEST_TAG"
118
+ else
119
+ # Canary, beta, or forced releases are pre-releases
120
+ IS_PRERELEASE=true
121
+ echo "Detected pre-release tag: $LATEST_TAG (or untagged forced release)"
122
+ fi
123
+
124
+ echo "DO_RELEASE=true" >> $GITHUB_ENV
125
+ echo "IS_PRERELEASE=$IS_PRERELEASE" >> $GITHUB_ENV
126
+ echo "RELEASE_COMMIT_HASH=$RELEASE_COMMIT_HASH" >> $GITHUB_ENV
127
+ echo "RELEASE_TAG=$LATEST_TAG" >> $GITHUB_ENV
128
+ else
129
+ echo "No release-triggering commit or input found."
130
+ echo "DO_RELEASE=false" >> $GITHUB_ENV
131
+ fi
132
+
133
+ - name : Setup Git
134
+ if : ${{ env.DO_RELEASE == 'true' }}
135
+ run : git config --global user.email ${{ secrets.EMAIL }} && git config --global user.name PiX
136
+
137
+ - name : Fetch Release Info
138
+ if : ${{ env.DO_RELEASE == 'true' }}
139
+ id : fetch_info
140
+ run : |
141
+ COMMIT_HASH=$(git rev-parse --short $RELEASE_COMMIT_HASH)
142
+ MAGISK_VERSION=$(grep 'magisk.versionCode=' app/gradle.properties | awk -F= '{print $2}')
143
+ echo "COMMIT_HASH=$COMMIT_HASH" >> $GITHUB_ENV
144
+ echo "MAGISK_VERSION=$MAGISK_VERSION" >> $GITHUB_ENV
145
+
146
+ # Use the tag found in the previous step, or create a fallback for untagged forced releases
147
+ RELEASE_TAG=${{ env.RELEASE_TAG }}
148
+ if [[ -z "$RELEASE_TAG" ]]; then
149
+ RELEASE_TAG="canary-$MAGISK_VERSION"
150
+ fi
151
+ echo "RELEASE_TAG=$RELEASE_TAG" >> $GITHUB_ENV
152
+
153
+ # Construct a release title
154
+ if [[ "$RELEASE_TAG" == v* ]]; then
155
+ RELEASE_TITLE="Magisk $RELEASE_TAG"
156
+ else
157
+ RELEASE_TITLE="Magisk ($COMMIT_HASH) ($MAGISK_VERSION)"
158
+ fi
159
+ echo "RELEASE_TITLE=$RELEASE_TITLE" >> $GITHUB_ENV
160
+
161
+ - name : Create Release Notes
162
+ if : ${{ env.DO_RELEASE == 'true' }}
163
+ run : |
164
+ # Try to extract notes from the annotated git tag of the release commit
165
+ if [[ -n "${{ env.RELEASE_TAG }}" ]]; then
166
+ git tag -l --format='%(contents)' "${{ env.RELEASE_TAG }}" > notes.md
167
+ fi
168
+ # If notes are still empty, add a placeholder
169
+ if [ ! -s notes.md ]; then
170
+ echo "This is a new build of Magisk." > notes.md
171
+ fi
172
+ echo -e '\n## Diffs to Official Magisk\n\nAdded support for GrapheneOS for personal use' >> notes.md
173
+ echo "Generated Release Notes:"
174
+ cat notes.md
175
+
176
+ - name : Release APK
177
+ if : ${{ env.DO_RELEASE == 'true' && env.RELEASE_TAG != '' }}
178
+ uses :
" dciborow/[email protected] "
179
+ with :
180
+ repo_token : " ${{ secrets.GITHUB_TOKEN }}"
181
+ automatic_release_tag : " ${{ env.RELEASE_TAG }}"
182
+ prerelease : ${{ env.IS_PRERELEASE }}
183
+ title : " ${{ env.RELEASE_TITLE }}"
184
+ files : |
185
+ out/app-release.apk
186
+ out/app-debug.apk
187
+ notes.md
188
+
48
189
- name : Upload mapping and native debug symbols
49
190
uses : actions/upload-artifact@v4
50
191
with :
0 commit comments