Skip to content

Commit 4b68b53

Browse files
committed
initial release: sf — terminal file manager written in ARO
Midnight Commander-style dual-panel file manager with keyboard navigation, file preview, and directory browsing. Includes CI/CD pipeline with signed macOS builds and Homebrew tap support.
0 parents  commit 4b68b53

File tree

9 files changed

+876
-0
lines changed

9 files changed

+876
-0
lines changed

.github/workflows/build.yml

Lines changed: 347 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,347 @@
1+
name: Build & Release
2+
3+
on:
4+
push:
5+
branches: [main]
6+
tags: ['*']
7+
pull_request:
8+
branches: [main]
9+
10+
env:
11+
ARO_VERSION: latest
12+
SWIFT_VERSION: '6.2.1'
13+
14+
jobs:
15+
# ===========================================================================
16+
# Check — syntax-check on both platforms
17+
# ===========================================================================
18+
check:
19+
strategy:
20+
fail-fast: false
21+
matrix:
22+
include:
23+
- os: ubuntu-22.04
24+
asset: aro-linux-amd64.tar.gz
25+
- os: macos-latest
26+
asset: aro-macos-arm64.tar.gz
27+
runs-on: ${{ matrix.os }}
28+
steps:
29+
- name: Checkout repository
30+
uses: actions/checkout@v4
31+
32+
- name: Install dependencies (Linux)
33+
if: runner.os == 'Linux'
34+
run: |
35+
sudo apt-get update -qq
36+
sudo apt-get install -y -qq libgit2-dev
37+
wget -qO- https://apt.llvm.org/llvm-snapshot.gpg.key | sudo gpg --dearmor -o /usr/share/keyrings/llvm-archive-keyring.gpg
38+
echo "deb [signed-by=/usr/share/keyrings/llvm-archive-keyring.gpg] http://apt.llvm.org/jammy/ llvm-toolchain-jammy-20 main" | sudo tee /etc/apt/sources.list.d/llvm.list
39+
sudo apt-get update -qq
40+
sudo apt-get install -y -qq libllvm20
41+
42+
- name: Install ARO (Linux)
43+
if: runner.os == 'Linux'
44+
run: |
45+
if [ "$ARO_VERSION" = "latest" ]; then
46+
DOWNLOAD_URL=$(curl -s https://api.github.com/repos/arolang/aro/releases/latest \
47+
| grep "browser_download_url.*${{ matrix.asset }}" \
48+
| cut -d '"' -f 4)
49+
else
50+
DOWNLOAD_URL="https://github.com/arolang/aro/releases/download/${ARO_VERSION}/${{ matrix.asset }}"
51+
fi
52+
curl -fsSL "$DOWNLOAD_URL" | tar xz
53+
sudo mv aro /usr/local/bin/
54+
sudo mv libARORuntime.a /usr/local/lib/
55+
aro --version
56+
57+
- name: Install ARO (macOS)
58+
if: runner.os == 'macOS'
59+
run: |
60+
brew tap arolang/aro
61+
brew install aro libgit2 llvm@20
62+
aro --version
63+
64+
- name: Check code
65+
run: aro check .
66+
67+
# ===========================================================================
68+
# Build — compile for macOS (signed) and Linux
69+
# ===========================================================================
70+
build-linux:
71+
needs: check
72+
runs-on: ubuntu-22.04
73+
steps:
74+
- name: Checkout repository
75+
uses: actions/checkout@v4
76+
77+
- name: Install Swift
78+
run: |
79+
curl -fsSL "https://download.swift.org/swift-${SWIFT_VERSION}-release/ubuntu2204/swift-${SWIFT_VERSION}-RELEASE/swift-${SWIFT_VERSION}-RELEASE-ubuntu22.04.tar.gz" -o swift.tar.gz
80+
sudo mkdir -p /usr/share/swift
81+
sudo tar xzf swift.tar.gz -C /usr/share/swift --strip-components=1
82+
echo "/usr/share/swift/usr/bin" >> $GITHUB_PATH
83+
rm swift.tar.gz
84+
85+
- name: Install dependencies
86+
run: |
87+
sudo apt-get update -qq
88+
sudo apt-get install -y -qq libgit2-dev
89+
wget -qO- https://apt.llvm.org/llvm-snapshot.gpg.key | sudo gpg --dearmor -o /usr/share/keyrings/llvm-archive-keyring.gpg
90+
echo "deb [signed-by=/usr/share/keyrings/llvm-archive-keyring.gpg] http://apt.llvm.org/jammy/ llvm-toolchain-jammy-20 main" | sudo tee /etc/apt/sources.list.d/llvm.list
91+
sudo apt-get update -qq
92+
sudo apt-get install -y -qq llvm-20
93+
sudo ln -sf /usr/lib/llvm-20/bin/llc /usr/local/bin/llc
94+
sudo ln -sf /usr/lib/llvm-20/bin/clang /usr/local/bin/clang
95+
96+
- name: Install ARO
97+
run: |
98+
if [ "$ARO_VERSION" = "latest" ]; then
99+
DOWNLOAD_URL=$(curl -s https://api.github.com/repos/arolang/aro/releases/latest \
100+
| grep "browser_download_url.*aro-linux-amd64.tar.gz" \
101+
| cut -d '"' -f 4)
102+
else
103+
DOWNLOAD_URL="https://github.com/arolang/aro/releases/download/${ARO_VERSION}/aro-linux-amd64.tar.gz"
104+
fi
105+
curl -fsSL "$DOWNLOAD_URL" | tar xz
106+
sudo mv aro /usr/local/bin/
107+
sudo mv libARORuntime.a /usr/local/lib/
108+
109+
- name: Build
110+
run: aro build . --optimize --strip --size -o sf
111+
112+
- name: Upload artifact
113+
uses: actions/upload-artifact@v4
114+
with:
115+
name: sf-linux-amd64
116+
path: sf
117+
118+
build-macos:
119+
needs: check
120+
runs-on: macos-latest
121+
env:
122+
APPLE_CERTIFICATE_BASE64: ${{ secrets.APPLE_CERTIFICATE_BASE64 }}
123+
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
124+
APPLE_ID: ${{ secrets.APPLE_ID }}
125+
steps:
126+
- name: Checkout repository
127+
uses: actions/checkout@v4
128+
129+
- name: Install Swift
130+
run: |
131+
curl -fsSL "https://download.swift.org/swift-${SWIFT_VERSION}-release/xcode/swift-${SWIFT_VERSION}-RELEASE/swift-${SWIFT_VERSION}-RELEASE-osx.pkg" -o swift.pkg
132+
sudo installer -pkg swift.pkg -target /
133+
TOOLCHAIN_BIN="/Library/Developer/Toolchains/swift-${SWIFT_VERSION}-RELEASE.xctoolchain/usr/bin"
134+
echo "$TOOLCHAIN_BIN" >> $GITHUB_PATH
135+
rm swift.pkg
136+
137+
- name: Install ARO
138+
run: |
139+
brew tap arolang/aro
140+
brew install aro libgit2 llvm@20
141+
echo "/opt/homebrew/opt/llvm@20/bin" >> $GITHUB_PATH
142+
143+
- name: Import Code Signing Certificate
144+
if: github.ref_type == 'tag' && env.APPLE_CERTIFICATE_BASE64 != ''
145+
env:
146+
APPLE_CERTIFICATE_BASE64: ${{ secrets.APPLE_CERTIFICATE_BASE64 }}
147+
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
148+
run: |
149+
KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db
150+
KEYCHAIN_PASSWORD=$(openssl rand -base64 32)
151+
152+
echo "$APPLE_CERTIFICATE_BASE64" | base64 --decode > certificate.p12
153+
154+
security create-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
155+
security set-keychain-settings -lut 21600 $KEYCHAIN_PATH
156+
security unlock-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
157+
158+
security import certificate.p12 \
159+
-P "$APPLE_CERTIFICATE_PASSWORD" \
160+
-A \
161+
-t cert \
162+
-f pkcs12 \
163+
-k $KEYCHAIN_PATH
164+
165+
security list-keychain -d user -s $KEYCHAIN_PATH
166+
security set-key-partition-list \
167+
-S apple-tool:,apple: \
168+
-s \
169+
-k "$KEYCHAIN_PASSWORD" \
170+
$KEYCHAIN_PATH
171+
172+
rm certificate.p12
173+
174+
- name: Build (signed)
175+
if: github.ref_type == 'tag' && env.APPLE_TEAM_ID != ''
176+
env:
177+
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
178+
run: |
179+
aro build . --sign "$APPLE_TEAM_ID" --optimize --strip --size -o sf
180+
codesign --verify --verbose sf
181+
182+
- name: Build (unsigned)
183+
if: github.ref_type != 'tag' || env.APPLE_TEAM_ID == ''
184+
run: aro build . --optimize --strip --size -o sf
185+
186+
- name: Notarize Binary
187+
if: github.ref_type == 'tag' && env.APPLE_ID != ''
188+
env:
189+
APPLE_ID: ${{ secrets.APPLE_ID }}
190+
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
191+
APPLE_APP_PASSWORD: ${{ secrets.APPLE_APP_PASSWORD }}
192+
run: |
193+
zip -r sf.zip sf
194+
xcrun notarytool submit sf.zip \
195+
--apple-id "$APPLE_ID" \
196+
--team-id "$APPLE_TEAM_ID" \
197+
--password "$APPLE_APP_PASSWORD" \
198+
--wait
199+
# Staple may fail for CLI tools — that's OK
200+
xcrun stapler staple sf || true
201+
202+
- name: Upload artifact
203+
uses: actions/upload-artifact@v4
204+
with:
205+
name: sf-macos-arm64
206+
path: sf
207+
208+
# ===========================================================================
209+
# Release — create GitHub release on tag push
210+
# ===========================================================================
211+
release:
212+
name: Create Release
213+
needs: [build-linux, build-macos]
214+
runs-on: ubuntu-latest
215+
if: github.ref_type == 'tag'
216+
permissions:
217+
contents: write
218+
steps:
219+
- name: Checkout repository
220+
uses: actions/checkout@v4
221+
222+
- name: Download all artifacts
223+
uses: actions/download-artifact@v4
224+
with:
225+
path: artifacts
226+
227+
- name: Package release assets
228+
run: |
229+
cd artifacts/sf-linux-amd64
230+
chmod +x sf
231+
tar -czvf ../sf-linux-amd64.tar.gz sf
232+
cd ../..
233+
234+
cd artifacts/sf-macos-arm64
235+
chmod +x sf
236+
tar -czvf ../sf-macos-arm64.tar.gz sf
237+
cd ../..
238+
239+
- name: Extract version from tag
240+
id: version
241+
run: |
242+
VERSION="${{ github.ref_name }}"
243+
VERSION="${VERSION#v}"
244+
echo "version=${VERSION}" >> $GITHUB_OUTPUT
245+
246+
- name: Create GitHub Release
247+
uses: softprops/action-gh-release@v2
248+
with:
249+
name: sf ${{ steps.version.outputs.version }}
250+
draft: false
251+
prerelease: ${{ contains(github.ref_name, '-') }}
252+
generate_release_notes: true
253+
files: |
254+
artifacts/sf-linux-amd64.tar.gz
255+
artifacts/sf-macos-arm64.tar.gz
256+
body: |
257+
## ShowFiles ${{ steps.version.outputs.version }}
258+
259+
A Midnight Commander-style terminal file manager written in ARO.
260+
261+
### Downloads
262+
263+
| Platform | Architecture | Download |
264+
|----------|--------------|----------|
265+
| macOS | Apple Silicon | [sf-macos-arm64.tar.gz](https://github.com/${{ github.repository }}/releases/download/${{ github.ref_name }}/sf-macos-arm64.tar.gz) |
266+
| Linux | x86_64 | [sf-linux-amd64.tar.gz](https://github.com/${{ github.repository }}/releases/download/${{ github.ref_name }}/sf-linux-amd64.tar.gz) |
267+
268+
### Installation
269+
270+
**macOS (Homebrew)**
271+
```bash
272+
brew tap arolang/applications
273+
brew install sf
274+
```
275+
276+
**macOS (Manual)**
277+
```bash
278+
curl -fsSL https://github.com/${{ github.repository }}/releases/download/${{ github.ref_name }}/sf-macos-arm64.tar.gz | tar xz
279+
sudo mv sf /usr/local/bin/
280+
```
281+
282+
**Linux**
283+
```bash
284+
curl -fsSL https://github.com/${{ github.repository }}/releases/download/${{ github.ref_name }}/sf-linux-amd64.tar.gz | tar xz
285+
sudo mv sf /usr/local/bin/
286+
```
287+
288+
# ======================================================================
289+
# Update Homebrew Formula
290+
# ======================================================================
291+
- name: Update Homebrew Formula
292+
continue-on-error: true
293+
env:
294+
HOMEBREW_TAP_TOKEN: ${{ secrets.HOMEBREW_TAP_TOKEN }}
295+
run: |
296+
SHA256_MACOS=$(shasum -a 256 artifacts/sf-macos-arm64.tar.gz | awk '{print $1}')
297+
SHA256_LINUX=$(shasum -a 256 artifacts/sf-linux-amd64.tar.gz | awk '{print $1}')
298+
VERSION="${{ steps.version.outputs.version }}"
299+
REPO="${{ github.repository }}"
300+
TAG="${{ github.ref_name }}"
301+
302+
echo "Version: $VERSION"
303+
echo "SHA256 macOS: $SHA256_MACOS"
304+
echo "SHA256 Linux: $SHA256_LINUX"
305+
306+
git clone https://x-access-token:${HOMEBREW_TAP_TOKEN}@github.com/arolang/homebrew-applications.git
307+
cd homebrew-applications
308+
mkdir -p Formula
309+
310+
{
311+
echo 'class Sf < Formula'
312+
echo ' desc "Midnight Commander-style terminal file manager written in ARO"'
313+
echo " homepage \"https://github.com/${REPO}\""
314+
echo " version \"${VERSION}\""
315+
echo ' license "MIT"'
316+
echo ''
317+
echo ' on_macos do'
318+
echo ' depends_on arch: :arm64'
319+
echo " url \"https://github.com/${REPO}/releases/download/${TAG}/sf-macos-arm64.tar.gz\""
320+
echo " sha256 \"${SHA256_MACOS}\""
321+
echo ' end'
322+
echo ''
323+
echo ' on_linux do'
324+
echo " url \"https://github.com/${REPO}/releases/download/${TAG}/sf-linux-amd64.tar.gz\""
325+
echo " sha256 \"${SHA256_LINUX}\""
326+
echo ' end'
327+
echo ''
328+
echo ' def install'
329+
echo ' bin.install "sf"'
330+
echo ' end'
331+
echo ''
332+
echo ' test do'
333+
echo ' assert_match version.to_s, shell_output("#{bin}/sf --version")'
334+
echo ' end'
335+
echo 'end'
336+
} > Formula/sf.rb
337+
338+
git config user.name "github-actions[bot]"
339+
git config user.email "github-actions[bot]@users.noreply.github.com"
340+
341+
git add Formula/sf.rb
342+
if git diff --staged --quiet; then
343+
echo "No changes to formula"
344+
else
345+
git commit -m "chore: update sf to version ${VERSION}"
346+
git push https://x-access-token:${HOMEBREW_TAP_TOKEN}@github.com/arolang/homebrew-applications.git main
347+
fi

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
/sf
2+
/.idea
3+
/.DS_Store

0 commit comments

Comments
 (0)