Skip to content

Commit d016fff

Browse files
feat: v0.2.0
1 parent a17605f commit d016fff

5 files changed

Lines changed: 322 additions & 12 deletions

File tree

.github/workflows/release.yml

Lines changed: 261 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,261 @@
1+
name: Cross-Platform Release
2+
3+
on:
4+
push:
5+
tags:
6+
- 'v*'
7+
workflow_dispatch:
8+
9+
jobs:
10+
build:
11+
name: Build for ${{ matrix.target }}
12+
runs-on: ${{ matrix.runner }}
13+
strategy:
14+
fail-fast: false
15+
matrix:
16+
include:
17+
# Linux x86_64
18+
- target: x86_64-unknown-linux-gnu
19+
runner: ubuntu-latest
20+
use_cross: false
21+
# Linux ARM64
22+
- target: aarch64-unknown-linux-gnu
23+
runner: ubuntu-latest
24+
use_cross: true
25+
# macOS x86_64
26+
- target: x86_64-apple-darwin
27+
runner: macos-latest
28+
use_cross: false
29+
# macOS ARM64 (Apple Silicon)
30+
- target: aarch64-apple-darwin
31+
runner: macos-latest
32+
use_cross: false
33+
# Windows x86_64
34+
- target: x86_64-pc-windows-msvc
35+
runner: windows-latest
36+
use_cross: false
37+
38+
steps:
39+
- uses: actions/checkout@v5
40+
41+
- uses: dtolnay/rust-toolchain@stable
42+
with:
43+
targets: ${{ matrix.target }}
44+
45+
- uses: Swatinem/rust-cache@v2
46+
with:
47+
key: ${{ matrix.target }}-${{ hashFiles('**/Cargo.lock') }}
48+
shared-key: ${{ matrix.target }}
49+
50+
# Install cross for Linux ARM builds
51+
# Using cargo install from git since there are no recent releases
52+
# (last release v0.2.5 was in Feb 2023, but development is active)
53+
- name: Install cross
54+
if: matrix.use_cross
55+
run: cargo install cross --git https://github.com/cross-rs/cross --rev 8633ec65ab914015c2444c732568b414bd3c47cf
56+
57+
# For Linux ARM, we need proper configuration
58+
- name: Create .cargo/config.toml for Linux ARM
59+
if: matrix.target == 'aarch64-unknown-linux-gnu'
60+
shell: bash
61+
run: |
62+
mkdir -p .cargo
63+
cat > .cargo/config.toml << 'EOF'
64+
[target.aarch64-unknown-linux-gnu]
65+
linker = "aarch64-linux-gnu-gcc"
66+
ar = "aarch64-linux-gnu-ar"
67+
EOF
68+
69+
- name: Build
70+
run: |
71+
if [ "${{ matrix.use_cross }}" = "true" ]; then
72+
cross build --release --target ${{ matrix.target }}
73+
else
74+
cargo build --release --target ${{ matrix.target }}
75+
fi
76+
shell: bash
77+
78+
# macOS Code Signing (optional - requires secrets to be configured)
79+
- name: Import Apple Code Signing Certificate
80+
if: runner.os == 'macOS'
81+
continue-on-error: true
82+
uses: Apple-Actions/import-codesign-certs@v3
83+
with:
84+
p12-file-base64: ${{ secrets.APPLE_CERTIFICATE_BASE64 }}
85+
p12-password: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
86+
87+
- name: Code sign and notarize macOS binaries
88+
if: runner.os == 'macOS'
89+
run: |
90+
CERT_IMPORTED=false
91+
92+
# Check if certificate was imported (if secrets exist, cert should be imported)
93+
if security find-identity -v -p codesigning | grep -q "Developer ID Application"; then
94+
CERT_IMPORTED=true
95+
fi
96+
97+
# Sign both binaries
98+
for BINARY in gravityfile grav; do
99+
BINARY_PATH="target/${{ matrix.target }}/release/$BINARY"
100+
101+
if [ "$CERT_IMPORTED" = "true" ]; then
102+
echo "Signing $BINARY with Developer ID..."
103+
codesign --deep --force --verify --verbose \
104+
--timestamp --options runtime \
105+
--sign "${{ secrets.APPLE_DEVELOPER_ID }}" \
106+
"$BINARY_PATH"
107+
codesign -v "$BINARY_PATH"
108+
109+
echo "Notarizing $BINARY with Apple..."
110+
ditto -c -k --sequesterRsrc "$BINARY_PATH" "${BINARY}-notarize.zip"
111+
112+
xcrun notarytool submit "${BINARY}-notarize.zip" \
113+
--apple-id "${{ secrets.APPLE_ID }}" \
114+
--password "${{ secrets.APPLE_ID_PASSWORD }}" \
115+
--team-id "${{ secrets.APPLE_TEAM_ID }}" \
116+
--wait \
117+
--timeout 30m
118+
119+
echo "Note: Stapling is not applicable to bare CLI binaries"
120+
echo "Binary is notarized server-side - users will be verified online"
121+
122+
echo "Verifying notarization status..."
123+
spctl -a -v "$BINARY_PATH" || true
124+
echo "✓ $BINARY signed and notarized"
125+
else
126+
echo "Developer ID certificate not configured. Using ad-hoc signing for $BINARY..."
127+
codesign --remove-signature "$BINARY_PATH" || true
128+
codesign -s - "$BINARY_PATH"
129+
codesign -v "$BINARY_PATH"
130+
echo "⚠ $BINARY ad-hoc signed (users may see Gatekeeper warning)"
131+
fi
132+
done
133+
134+
135+
- name: Prepare artifacts (Windows)
136+
if: runner.os == 'Windows'
137+
run: |
138+
# Create artifacts directory
139+
New-Item -ItemType Directory -Force -Path artifacts | Out-Null
140+
141+
$archiveName = "gravityfile-${{ matrix.target }}"
142+
143+
# Create a directory for the archive contents
144+
New-Item -ItemType Directory -Force -Path $archiveName | Out-Null
145+
146+
# Copy both binaries
147+
Copy-Item "target/${{ matrix.target }}/release/gravityfile.exe" "$archiveName/"
148+
Copy-Item "target/${{ matrix.target }}/release/grav.exe" "$archiveName/"
149+
150+
# Create zip for Windows (tar.gz not common on Windows)
151+
Compress-Archive -Path $archiveName -DestinationPath "artifacts/$archiveName.zip"
152+
153+
# Generate SHA256 for the archive
154+
$hash = (Get-FileHash "artifacts/$archiveName.zip" -Algorithm SHA256).Hash.ToLower()
155+
"$hash $archiveName.zip" | Out-File -FilePath "artifacts/$archiveName.zip.sha256" -Encoding ascii -NoNewline
156+
157+
Write-Host "Archive contents:"
158+
Get-ChildItem $archiveName | Format-List Name, Length
159+
Write-Host "SHA256:"
160+
Get-Content "artifacts/$archiveName.zip.sha256"
161+
shell: pwsh
162+
163+
- name: Prepare artifacts (Unix)
164+
if: runner.os != 'Windows'
165+
run: |
166+
mkdir -p artifacts
167+
ARCHIVE_NAME="gravityfile-${{ matrix.target }}"
168+
169+
# Create a directory for the archive contents
170+
mkdir -p "$ARCHIVE_NAME"
171+
172+
# Copy both binaries
173+
cp "target/${{ matrix.target }}/release/gravityfile" "$ARCHIVE_NAME/"
174+
cp "target/${{ matrix.target }}/release/grav" "$ARCHIVE_NAME/"
175+
chmod +x "$ARCHIVE_NAME/gravityfile" "$ARCHIVE_NAME/grav"
176+
177+
# Create tar to preserve permissions
178+
tar -czf "artifacts/$ARCHIVE_NAME.tar.gz" "$ARCHIVE_NAME"
179+
180+
# Generate SHA256 for the archive
181+
cd artifacts
182+
sha256sum "$ARCHIVE_NAME.tar.gz" > "$ARCHIVE_NAME.tar.gz.sha256"
183+
184+
echo "Archive contents:"
185+
tar -tzf "$ARCHIVE_NAME.tar.gz"
186+
echo "SHA256:"
187+
cat "$ARCHIVE_NAME.tar.gz.sha256"
188+
shell: bash
189+
190+
- name: Upload artifacts
191+
uses: actions/upload-artifact@v4
192+
with:
193+
name: ${{ matrix.target }}
194+
path: artifacts/*
195+
if-no-files-found: error
196+
retention-days: 1
197+
198+
release:
199+
name: Create Release
200+
runs-on: ubuntu-latest
201+
needs: build
202+
if: startsWith(github.ref, 'refs/tags/v')
203+
permissions:
204+
contents: write
205+
206+
steps:
207+
- uses: actions/checkout@v5
208+
209+
- name: Download all artifacts
210+
uses: actions/download-artifact@v4
211+
with:
212+
path: release-artifacts
213+
214+
- name: Prepare release assets
215+
run: |
216+
mkdir -p final-release
217+
218+
# Copy archives directly (tar.gz and zip preserve permissions internally)
219+
find release-artifacts -name "*.tar.gz" -type f -exec cp {} final-release/ \;
220+
find release-artifacts -name "*.zip" -type f -exec cp {} final-release/ \;
221+
222+
# Copy individual SHA256 files
223+
find release-artifacts -name "*.sha256" -type f -exec cp {} final-release/ \;
224+
225+
echo "Final release contents:"
226+
ls -lah final-release/
227+
228+
echo "Verifying archive integrity:"
229+
cd final-release
230+
for archive in *.tar.gz; do
231+
[ -f "$archive" ] || continue
232+
echo "Testing $archive:"
233+
tar -tzf "$archive" | head -10
234+
done
235+
for archive in *.zip; do
236+
[ -f "$archive" ] || continue
237+
echo "Testing $archive:"
238+
unzip -l "$archive"
239+
done
240+
shell: bash
241+
242+
- name: Generate combined checksums
243+
run: |
244+
cd final-release
245+
# Generate SHA256SUMS for archives (not individual binaries)
246+
sha256sum *.tar.gz *.zip 2>/dev/null | grep -v "No such file" > SHA256SUMS || true
247+
cat SHA256SUMS
248+
shell: bash
249+
250+
- name: Create Release
251+
uses: softprops/action-gh-release@v2
252+
with:
253+
files: |
254+
final-release/*.tar.gz
255+
final-release/*.zip
256+
final-release/*.sha256
257+
final-release/SHA256SUMS
258+
generate_release_notes: true
259+
draft: false
260+
prerelease: false
261+
fail_on_unmatched_files: true

.github/workflows/rust.yml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
name: Rust
2+
3+
on:
4+
push:
5+
branches: [ "main" ]
6+
pull_request:
7+
branches: [ "main" ]
8+
9+
env:
10+
CARGO_TERM_COLOR: always
11+
12+
jobs:
13+
build:
14+
15+
runs-on: ubuntu-latest
16+
17+
steps:
18+
- uses: actions/checkout@v5
19+
- name: Build
20+
run: cargo build --verbose
21+
- name: Run tests
22+
run: cargo test --verbose

CHANGELOG.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,31 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [0.2.0] - 2025-12-13
9+
10+
### Added
11+
12+
- **Miller Columns Layout** - Ranger-style three-pane view (Parent | Current | Preview), toggle with `v` or `:layout miller`
13+
- **File Operations** - Full clipboard support with vim-style keybindings:
14+
- `y` - Yank (copy) to clipboard
15+
- `x` - Cut to clipboard
16+
- `p` - Paste from clipboard
17+
- `r` - Rename file/directory
18+
- `a` - Create new file
19+
- `A` - Create new directory
20+
- `T` - Take (mkdir + cd into new directory)
21+
- **Conflict Resolution** - Interactive handling for file conflicts during copy/move operations
22+
- **Cross-Platform Releases** - GitHub Actions workflow for automated releases:
23+
- Linux x86_64 and ARM64
24+
- macOS Intel and Apple Silicon (with optional code signing/notarization)
25+
- Windows x86_64
26+
- **CI Pipeline** - Automated build and test on push/PR to main
27+
28+
### Changed
29+
30+
- Improved navigation with history preservation across drill-down operations
31+
- Enhanced details panel with more file metadata
32+
833
## [0.1.2] - 2025-12-09
934

1035
### Changed
@@ -40,5 +65,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
4065
- `gravityfile age [PATH]` - Analyze file ages
4166
- `gravityfile export [PATH]` - Export scan results to JSON
4267

68+
[0.2.0]: https://github.com/epistates/gravityfile/releases/tag/v0.2.0
69+
[0.1.2]: https://github.com/epistates/gravityfile/releases/tag/v0.1.2
4370
[0.1.1]: https://github.com/epistates/gravityfile/releases/tag/v0.1.1
4471
[0.1.0]: https://github.com/epistates/gravityfile/releases/tag/v0.1.0

Cargo.lock

Lines changed: 6 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)