Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 84 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# Publishes a GitHub Release for each version tag, then opens a pull request
# on twostraws/homebrew-ignite that bumps the ignite-swift formula.

name: Release

on:
push:
tags:
- '[0-9]+.[0-9]+.[0-9]+'

permissions:
contents: write

jobs:
release:
runs-on: ubuntu-latest
env:
GH_TOKEN: ${{ github.token }}
TAG: ${{ github.ref_name }}
steps:
- name: Create GitHub Release
run: |
if gh release view "$TAG" --repo "$GITHUB_REPOSITORY" > /dev/null 2>&1; then
echo "Release $TAG already exists."
else
gh release create "$TAG" --repo "$GITHUB_REPOSITORY" --title "$TAG" --generate-notes --verify-tag
fi

bump-homebrew-tap:
needs: release
runs-on: ubuntu-latest
env:
TAG: ${{ github.ref_name }}
TAP_TOKEN: ${{ secrets.HOMEBREW_TAP_TOKEN }}
steps:
- name: Check for tap token
run: |
if [ -z "$TAP_TOKEN" ]; then
echo "::error::The HOMEBREW_TAP_TOKEN secret is not set, so the Homebrew tap can't be updated."
exit 1
fi

- name: Check out the tap
uses: actions/checkout@v4
with:
repository: twostraws/homebrew-ignite
token: ${{ secrets.HOMEBREW_TAP_TOKEN }}
path: homebrew-ignite

- name: Update the formula
working-directory: homebrew-ignite
run: |
url="https://github.com/${GITHUB_REPOSITORY}/archive/refs/tags/${TAG}.tar.gz"
if grep -qF "url \"${url}\"" Formula/ignite-swift.rb; then
echo "Formula is already at $TAG."
exit 0
fi
sha256=$(curl --fail --silent --show-error --location "$url" | sha256sum | cut -d ' ' -f 1)
sed -i -E \
-e "s|^ url \".*\"$| url \"${url}\"|" \
-e "s|^ sha256 \".*\"$| sha256 \"${sha256}\"|" \
Formula/ignite-swift.rb
# Bottles from the previous version no longer apply; brew pr-pull adds new ones.
perl -0pi -e 's/\n bottle do\n.*?\n end\n//s' Formula/ignite-swift.rb
git diff

- name: Open a pull request
working-directory: homebrew-ignite
env:
GH_TOKEN: ${{ secrets.HOMEBREW_TAP_TOKEN }}
run: |
git diff --quiet && exit 0
branch="ignite-swift-${TAG}"
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git switch -c "$branch"
git commit -am "ignite-swift ${TAG}"
git push --force origin "$branch"
gh pr create \
--repo twostraws/homebrew-ignite \
--base main \
--head "$branch" \
--title "ignite-swift ${TAG}" \
--body "Bumps ignite-swift to [${TAG}](https://github.com/${GITHUB_REPOSITORY}/releases/tag/${TAG}). Add the \`pr-pull\` label once the checks pass to publish bottles."
14 changes: 13 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,19 @@ Ignite doesn't try to convert SwiftUI code to HTML, or simply map HTML tags to S

## Getting started

The easiest way to get started is to use the Ignite command-line tool included with this package:
The easiest way to get started is to use the Ignite command-line tool included with this package.

If you use [Homebrew](https://brew.sh), you can install it like this:

```shell
brew tap twostraws/ignite
brew install ignite-swift
```

> [!Note]
> The Homebrew formula is called `ignite-swift` because Homebrew already has an unrelated `ignite` formula, but the installed command is still `ignite`.

Alternatively, you can build and install it from source:

1. Run `git clone https://github.com/twostraws/Ignite` to clone this repository to your computer.
2. Change into the new directory, e.g. `cd Ignite`.
Expand Down
44 changes: 34 additions & 10 deletions Sources/IgniteCLI/RunCommand.swift
Original file line number Diff line number Diff line change
Expand Up @@ -62,17 +62,13 @@ struct RunCommand: ParsableCommand {
" "
}

// Find the server script installed next to the tool itself
let tool = ProcessInfo.processInfo.arguments.first ?? "NEVER"
let dirLoc = tool.lastIndex(of: "/") ?? tool.endIndex
let toolDir = String(tool[..<dirLoc])
let serverScriptURL = URL(filePath: "\(toolDir)/ignite-server.py")

// Verify server script exists
guard FileManager.default.fileExists(atPath: serverScriptURL.path) else {
print("❌ Critical server script missing: \(serverScriptURL.path)")
// Find the server script installed alongside the tool itself
guard let serverScriptURL = locateServerScript() else {
print("❌ Critical server script missing: ignite-server.py")
print(" This suggests a corrupted installation. Please reinstall with:")
print(" make clean && make install")
print(" or, if you installed with Homebrew:")
print(" brew reinstall ignite-swift")
return
}

Expand All @@ -84,11 +80,39 @@ struct RunCommand: ParsableCommand {

let subsiteArgument = subsite.isEmpty ? "" : "-s \(subsite)"
try Process.execute(
command: "python3 \(serverScriptURL.path) -d \(directory) \(subsiteArgument) \(currentPort)",
command: "python3 \"\(serverScriptURL.path)\" -d \(directory) \(subsiteArgument) \(currentPort)",
then: previewCommand
)
}

/// Finds `ignite-server.py`, checking next to the executable (as installed
/// by `make install`), then next to the executable with symlinks resolved,
/// then in a sibling `libexec` folder (as installed by Homebrew).
private func locateServerScript() -> URL? {
let scriptName = "ignite-server.py"
var executableURLs = [URL]()

if let executableURL = Bundle.main.executableURL {
executableURLs.append(executableURL)
executableURLs.append(executableURL.resolvingSymlinksInPath())
}

let invokedPath = ProcessInfo.processInfo.arguments.first ?? ""
if invokedPath.contains("/") {
executableURLs.append(URL(filePath: invokedPath))
}

let candidates = executableURLs.flatMap { executableURL in
let toolDirectory = executableURL.deletingLastPathComponent()
return [
toolDirectory.appending(path: scriptName),
toolDirectory.deletingLastPathComponent().appending(path: "libexec/\(scriptName)")
]
}

return candidates.first { FileManager.default.fileExists(atPath: $0.path) }
}

/// Returns true if there is a server running on the specified port.
private func isServerRunning(on port: Int) throws -> Bool {
let result = try Process.execute(command: "lsof -t -i tcp:\(port)")
Expand Down
Loading