Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prepare for versioned formulae #51

Merged
merged 7 commits into from
Oct 23, 2023
Merged
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
18 changes: 18 additions & 0 deletions .github/workflows/SwiftLint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: SwiftLint

on:
pull_request:
paths:
- '.github/workflows/swiftlint.yml'
- '.swiftlint.yml'
- '**/*.swift'

jobs:
SwiftLint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Lint changed files
uses: norio-nomura/[email protected]
env:
DIFF_BASE: ${{ github.base_ref }}
5 changes: 1 addition & 4 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,7 @@ on:

jobs:
build:
runs-on: macos-12
# This doesn't seem to work, even when the internet seems to indicate it should...
env:
DEVELOPER_DIR: /Applications/Xcode_14.2.app/Contents/Developer
runs-on: macos-13
steps:
- uses: actions/checkout@v3

Expand Down
21 changes: 21 additions & 0 deletions .github/workflows/periphery.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: periphery

on:
pull_request:
paths:
- '**/*.swift'

jobs:
periphery-scan:
runs-on: macos-13
steps:
- uses: actions/checkout@v1
- name: Set up Homebrew
id: set-up-homebrew
uses: Homebrew/actions/setup-homebrew@master
- name: Install periphery
run: |
brew install peripheryapp/periphery/periphery
- name: Scan for unused code
run: |
periphery scan
123 changes: 0 additions & 123 deletions .github/workflows/release.yml

This file was deleted.

3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@ output/
*.xcarchive/
*.bc
*.dia
_build/
_build/
**/.build/*
4 changes: 4 additions & 0 deletions .swiftlint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@ excluded:
- .vscode/
- PBXProjParser/.build/ # https://github.com/realm/SwiftLint/issues/2329 doesn't support recursive globs yet
- GenIRLogging/.build/
- TestAssets/

line_length:
warning: 150
ignores_comments: true

disabled_rules:
- todo
31 changes: 31 additions & 0 deletions Documentation/branching_model.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Gen IR Branching Model

![Branching Model](images/branching_model.png)

Gen IR uses the [GitFlow](https://nvie.com/posts/a-successful-git-branching-model/) branching model. This model is tried, tested, and has remained so over 10+ years for a project of this type.

Modifications to the model:

- No `hotfix` branch for now. We can just follow the regular release flow
- Unstable releases are tagged on `develop`
- These should be set as `prelease` in the GitHub Release!

## Versioning

We use the [SemVar 2.0.0](https://semvar.org) versioning scheme.

Releases should increment this (see [Releasing an Update](releasing_an_update.md))

## New Feature Development

- Create a new branch off `develop` and name it appropriately
- `git checkout develop && git pull && git checkout -b sensibly_named_branch`
- Add your new feature commits
- Create a merge request to the `develop` branch

## New Release

- Create a branch off `develop` and name it `release/<version>`
- Test, QA, fix
- Merge to `main` and create a release
- Merge to `develop`, remove the `develop` tag and retag the new commit with `develop`
103 changes: 81 additions & 22 deletions Documentation/releasing_an_update.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,93 @@
When you have an update for `gen-ir`, there's a couple things that need to happen:

- Release a version in the `gen-ir` repo
- Update the version in the `homebrew-tap` repo, so brew picks up the update
- Update the version(s) in the `homebrew-tap` repo, so brew picks up the update(s)

## Releasing a gen-ir version
## Releasing a Gen IR version

To release a new version of `gen-ir`, create a Pull Request with your changes, ensuring the `build` pipeline finishes successfully, then attach one of the following labels to the PR.
As mentioned in the [Branching Model](branching_model.md), features should be merged into the `develop` branch. You should never merge a feature directly to `main`.

- `merge-bump-major`
- This will merge the PR & bump a major version (i.e. 1.0.0 to 2.0.0)
- `merge-bump-minor`
- This will merge the PR & bump a minor version (i.e. 1.0.0 to 1.1.0)
- `merge-bump-patch`
- This will merge the PR & bump a patch version (i.e. 1.0.0 to 1.0.1)
- `merge-no-bump`
- This will merge the PR with no version bump
To release a new version of `gen-ir`, create a release branch and open a merge request from the release branch (see the [Branching Model](branching_model.md)) to `main` at the commit point you're wanting to release and to `develop`. Allow any automated check, peer reviews, and - when approved - merge the request.

This will merge the PR, bump the version, fix the version in the `Versions.swift` file, push the commit to main, tag the _new_ commit with the version number, and perform a GitHub release with that tag.
Then, on your local machine:

Now, navigate to the release and note the tag name & revision for the next part
- Change to `main` and pull the changes
- `git checkout main && git pull`
- Create the new tag for the release:
- `git tag -a 1.0.0 -m "Gen IR version: 1.0.0`
- `git push --tags`
- Change to `develop` and pull the changes
- `git checkout develop && git pull`
- Recreate the new `develop` tag for the release:
- `git tag -d develop && git push --delete origin develop`
- `git tag -a develop -m "Gen IR Develop version: <commit hash>`
- `git push --tags`

## Updating Homebrew Tap
Then, in the GitHub UI:

The formula for the tap lives in the [veracode/homebrew-taps](https://github.com/veracode/homebrew-tap) repo. This needs to be updated in order to propagate a new version to users.
- Go to the [Releases](https://github.com/veracode/gen-ir/releases) page
- Click `Draft a new release`
- Set the title to the version name
- From the drop down list, choose your newly created tag
- Click the `Generate release notes` button to create a change log
- Ensure `Set as the latest release` is checked
- Click the `Publish` button

- Create a new branch: `gen_ir_<version>`
- Update the `gen-ir` formulae url.tag & url.revision keys to match the release the previous step made
- Open a PR with these changes _and these changes only!_.
- If any other changes are detected, or more than one commit is made, homebrew's automation will fail
- When checks pass, add the `pr-pull` label to the PR
- Automation will make a new release
- Click `Draft a new release`
- Set the title to `develop`
- From the drop down list, choose your newly created `develop` tag
- Click the `Generate release notes` button to create a change log
- Ensure `Set as pre-release` is checked
- Click the `Publish` button

Users can now run `brew update && brew upgrade` to update `gen-ir` and `brew install gen-ir` will install the latest version.
A release has been made, congratulations. However there's additional steps for distributing the release via `brew`.

## Distributing a release

Gen IR uses a Homebrew Tap for distribution. In order for the Tap to see the new release, you need to update the [Gen IR Formula](https://github.com/veracode/homebrew-tap/blob/main/Formula/gen-ir.rb).

> Note: You may have to update more than one formula! If you're releasing a new major or minor version, you'll need to ensure versioning of the formula is correct. See the section [Versioning Tap Releases](#versioning-tap-releases) for more information.

First, if you haven't already, checkout the `veracode/homebrew-tap` repo:

```shell
git clone [email protected]:veracode/homebrew-tap.git
```

Then, do the following to increment the formula:

- Create a new branch - replacing `<version>` with the released version:
- `git checkout -b gen_ir_<version>`
- Update the `gen-ir.rb` formula:
- Change `url.tag`'s value to the tag's name
- Change `url.revision` to the commit hash pointed to by the tag
- Open a merge request with _only these changes!_
- If you have more than one commit, or change more than this single file - homebrews automation will refuse to merge the request.
- When the `test-bot` check passes, add the `pr-pull` label to the request
- Automation will make the new release

Users can now run `brew update && brew upgrade gen-ir` to update to the latest version.

## Versioning Tap Releases

It is likely that you will need to do One More Thing, which is to ensure the formula is versioned correctly.

Gen IR has the following policy on versions:

- Gen IR will maintain formulae for one version behind _and_ any current prerelease versions
- Any versioned formulae **must** use `keg_only :versioned_formula`
- This means brew will _only_ install into the Cellar, and will not link into the brew prefix
- Gen IR _will not_ maintain formulae for patch versions

So, if you have released a new major or minor version you should:

- Create a new versioned formula for the previous release to yours
- Remove any now-deprecated formula(e)

### Creating Versioned Formulae

Using the history of the `homebrew-tap` find the version of the Gen IR formula you're looking for, then copy the file to the `Formula` folder renaming it like so: `gen-ir@<version>`

Edit the file to add the `keg_only :versioned_formula` tag after the `bottle`.

> Note: it is a good idea to run `brew style Formulae/gen-ir@<version>.rb` before you push the commit! Brew is _very_ particular about the layout of a formula and the test-bot will fail if your key isn't in the right spot.
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ final class PBXProjParserTests: XCTestCase {
"DoubleTargetTest": [],
// TODO: should we also disregard Cocoapods doing their stupid bundle as a native target even though it isn't
"MyBundle": ["MyBundle.bundle"],
"Pods-DoubleTargetTest": ["MyBundle.framework", "MyBundle.bundle"],
"Pods-DoubleTargetTest": ["MyBundle.framework", "MyBundle.bundle"]
]

XCTAssert(
Expand Down
2 changes: 1 addition & 1 deletion Sources/GenIR/BuildCacheManipulator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ struct BuildCacheManipulator {
self.buildCachePath = buildCachePath
self.buildSettings = buildSettings
buildProductsPath = archive
shouldDeploySkipInstallHack = buildSettings["SKIP_INSTALL"] == "NO"
shouldDeploySkipInstallHack = self.buildSettings["SKIP_INSTALL"] == "NO"

guard FileManager.default.directoryExists(at: buildCachePath) else {
throw Error.directoryNotFound("Build cache path doesn't exist at expected path: \(buildCachePath)")
Expand Down
2 changes: 2 additions & 0 deletions Sources/GenIR/Extensions/FileManager+Extension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,9 @@ extension FileManager {

if let type = attributes[.type] as? FileAttributeType, type == .typeSymbolicLink {
let destination = try destinationOfSymbolicLink(atPath: path.filePath)
// swiftlint:disable identifier_name
let actualDestinationCausePathingSucksInFoundation = path.deletingLastPathComponent().appendingPathComponent(destination)
// swiftlint:enable identifier_name
return fileExists(atPath: actualDestinationCausePathingSucksInFoundation.filePath)
}

Expand Down
1 change: 1 addition & 0 deletions Sources/GenIR/Extensions/String+Extension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ extension String {
return self[startIndex..<self.endIndex].firstIndexWithEscapes(of: character, from: startIndex)
}

// periphery:ignore - not used, but written and could be useful in the future.
/// Splits a String ignoring matches where a split would normally occur, but is escaped with a \ character
/// - Parameter separator: The separator to split on
/// - Returns: An array of subsequences, split from the collection's elements
Expand Down
Loading