From 92aa76643c4bdaffbcf37a3fb94a0ab566f43570 Mon Sep 17 00:00:00 2001 From: NinjaLikesCheez Date: Fri, 20 Oct 2023 16:02:03 +0200 Subject: [PATCH 1/7] Remove release action, add documentation for release and branching --- .github/workflows/release.yml | 123 ----------------------- Documentation/branching_model.md | 29 ++++++ Documentation/images/branching_model.png | Bin 0 -> 52317 bytes Documentation/releasing_an_update.md | 97 ++++++++++++++---- 4 files changed, 104 insertions(+), 145 deletions(-) delete mode 100644 .github/workflows/release.yml create mode 100644 Documentation/branching_model.md create mode 100644 Documentation/images/branching_model.png diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml deleted file mode 100644 index d8844c1..0000000 --- a/.github/workflows/release.yml +++ /dev/null @@ -1,123 +0,0 @@ -name: Release Update - -# This workflow merges a PR and, optionally, releases a GitHub Release with an auto bumped version. - -# Using the merge-bump- label on a PR, you can choose to bump the major, minor, or patch version -# Using the merge-no-bump label on a PR, you can merge the PR with no version change - -# You should only attach **one** of these labels, anymore will result in undefined behavior as to which bump will be performed. - - -# Run only on labeled Pull Requests -on: - pull_request_target: - types: - - labeled - -permissions: - contents: write - pull-requests: write - repository-projects: read - -jobs: - release: - - # Limit job to requests with a merge-* label on them - if: contains(${{ github.event.pull_request.labels.*.name }}, 'merge-') - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - # Fetches the last tag in the repo - - name: πŸ”™ Get Previous Tag - id: previous_tag - uses: "WyriHaximus/github-action-get-previous-tag@v1" - env: - GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" - - # Generates the next major, minor, and patch version given the previous tag - - name: ⏭ Get Next Versions - id: next_versions - uses: "WyriHaximus/github-action-next-semvers@v1" - with: - version: ${{ steps.previous_tag.outputs.tag }} - - # Selects the next version based off the label attached to the PR - # NOTE: it will select _the first_ tag it sees. Do **not** attach more than one `merge-bump-` labels - - name: βœ… Select Next Version - id: next_version - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - HEAD_REF: ${{ github.head_ref }} - MAJOR_VERSION: ${{ steps.next_versions.outputs.major }} - MINOR_VERSION: ${{ steps.next_versions.outputs.minor }} - PATCH_VERSION: ${{ steps.next_versions.outputs.patch }} - NO_VERSION: no-bump - run: | - LABEL=$(gh pr view $HEAD_REF --json labels -q '.labels[] | select(.name | contains("merge-bump-")) | .name' | head -n 1) - echo "Found label: $LABEL" - - if [[ $LABEL == "merge-bump-major" ]]; then - echo "next_tag=$MAJOR_VERSION" >> $GITHUB_ENV - elif [[ $LABEL == "merge-bump-minor" ]]; then - echo "next_tag=$MINOR_VERSION" >> $GITHUB_ENV - elif [[ $LABEL == "merge-bump-patch" ]]; then - echo "next_tag=$PATCH_VERSION" >> $GITHUB_ENV - else - echo "Setting no-bump as no bump label was found" - echo "next_tag=$NO_VERSION" >> $GITHUB_ENV - fi - - # Merges the underlying PR - - name: γŠ—οΈ Merge PR - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - HEAD_REF: ${{ github.head_ref }} - run: gh pr merge --merge $HEAD_REF - - # Delete the underlying PR branch - - name: ␑ Delete PR Branch - if: github.event.pull_request.head.repo.fork == false - env: - HEAD_REF: ${{ github.event.pull_request.head.ref }} - run: git push --delete origin $HEAD_REF - - # Checkout main again, the PR has merged so we want to pull that update down before bumping the version - - uses: actions/checkout@v3 - if: contains(toJSON(github.event.pull_request.labels.*.name), 'merge-bump-') - with: - ref: main - - # Apply the version bump by editing the Versions.swift file - - name: πŸ‘Š Bump Version - if: contains(toJSON(github.event.pull_request.labels.*.name), 'merge-bump-') - run: | - sed -i 's/.*static let version.*/\tstatic let version = "'"${{ env.next_tag }}"'"/g' Sources/GenIR/Versions.swift - # Confirm the tag is in place - if ! grep -Fq '${{ env.next_tag }}' Sources/GenIR/Versions.swift ; then - echo "Failed to find tag in Versions.swift: ${{ env.next_tag }}. Bailing out." - exit 1 - fi - - # Commit the change to main - - name: πŸ’ Commit Version Change - if: contains(toJSON(github.event.pull_request.labels.*.name), 'merge-bump-') - run: | - git config user.name 'github-actions[bot]' - git config user.email 'github-actions[bot]@github.com' - - git add Sources/GenIR/Versions.swift - git commit -m "Gen IR version: ${{ env.next_tag }}" - git push - - # Create a new GitHub release with the new version - - name: πŸš€ Release New Version - uses: softprops/action-gh-release@v1 - if: contains(toJSON(github.event.pull_request.labels.*.name), 'merge-bump-') - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - tag_name: ${{ env.next_tag }} - name: ${{ env.next_tag }} \ No newline at end of file diff --git a/Documentation/branching_model.md b/Documentation/branching_model.md new file mode 100644 index 0000000..5172fda --- /dev/null +++ b/Documentation/branching_model.md @@ -0,0 +1,29 @@ +# Gen IR Branching Model + +![Branching Model](images/branching_model.png) + +Gen IR uses a modified version of [GitFlow](https://nvie.com/posts/a-successful-git-branching-model/) as the basis of it’s branching model. This model is tried, tested, and has remained so over 10+ years for a project of this type. + +Modifications to the model: + +- `develop` becomes `unstable` +- No `hotfix` branch for now. We can just follow the regular flow +- Unstable releases are tagged on `unstable` if and when we want to make a new release + - 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 `unstable` and name it appropriately + - `git checkout unstable && git pull && git checkout -b sensibly_named_branch` +- Add your new feature commits +- Create a merge request to the `unstable` branch + +### Unstable releases + +If a feature should be released for testing & early adopters, you will need to do some additional steps. See [Releasing an Update - Unstable](releasing_an_update.md#unstable) for more. diff --git a/Documentation/images/branching_model.png b/Documentation/images/branching_model.png new file mode 100644 index 0000000000000000000000000000000000000000..a277abb4443187629249a931ed68d4009d9a9f13 GIT binary patch literal 52317 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 -- 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 +A release has been made, congratulations. However there's additional steps for distributing the release via `brew`. -Users can now run `brew update && brew upgrade` to update `gen-ir` and `brew install gen-ir` will install the latest version. +## 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 git@github.com:veracode/homebrew-tap.git +``` + +Then, do the following to increment the formula: + +- Create a new branch - replacing `` with the released version: + - `git checkout -b gen_ir_` +- 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 + +Creating a versioned formula can happen in one of two ways - I suggest using `brew extract` for this, but you can also manually find and copy the formula file, ensuring you add `keg_only :versioned_formula`. + +Rather unhelpfully, you can only use `brew extract` to extract a formula from one tap to another - not to an existing tap with the same formula. In this case you can substitute in any tap, but in this case I will use mine: `ninjalikescheez/tap` + +```shell +# assuming you're inside the veracode/homebrew-tap checkout +brew extract --version= veracode/tap/gen-ir ninjalikescheez/tap +cp /opt/homebrew/Library/Taps/ninjalikescheez/homebrew-tap/Formula/gen-ir@.rb Formula/ +``` + +Edit the file to add the `keg_only :versioned_formula` tag. + +TODO: Try this irl and see if the brew automation is able to auto-add the bottles or if we have to do it ourselves. From 7d4c767943bc15f2ae05f4155503972cd4774c0e Mon Sep 17 00:00:00 2001 From: NinjaLikesCheez Date: Mon, 23 Oct 2023 11:04:59 +0200 Subject: [PATCH 2/7] Address linting issues --- .gitignore | 3 ++- .swiftlint.yml | 4 ++++ .../Tests/PBXProjParserTests/PBXProjParserTests.swift | 2 +- Sources/GenIR/BuildCacheManipulator.swift | 2 +- Sources/GenIR/Extensions/FileManager+Extension.swift | 2 ++ Sources/GenIR/Extensions/String+Extension.swift | 1 + Sources/GenIR/OutputPostprocessor.swift | 6 +----- Sources/GenIR/StdoutLogHandler.swift | 7 ++++--- Sources/GenIR/Targets/Targets.swift | 2 +- 9 files changed, 17 insertions(+), 12 deletions(-) diff --git a/.gitignore b/.gitignore index cbd71e6..cc3876c 100644 --- a/.gitignore +++ b/.gitignore @@ -16,4 +16,5 @@ output/ *.xcarchive/ *.bc *.dia -_build/ \ No newline at end of file +_build/ +**/.build/* \ No newline at end of file diff --git a/.swiftlint.yml b/.swiftlint.yml index addd3ae..44b675c 100644 --- a/.swiftlint.yml +++ b/.swiftlint.yml @@ -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 \ No newline at end of file diff --git a/PBXProjParser/Tests/PBXProjParserTests/PBXProjParserTests.swift b/PBXProjParser/Tests/PBXProjParserTests/PBXProjParserTests.swift index 5b33bf0..3d9d527 100644 --- a/PBXProjParser/Tests/PBXProjParserTests/PBXProjParserTests.swift +++ b/PBXProjParser/Tests/PBXProjParserTests/PBXProjParserTests.swift @@ -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( diff --git a/Sources/GenIR/BuildCacheManipulator.swift b/Sources/GenIR/BuildCacheManipulator.swift index cb5e678..35def63 100644 --- a/Sources/GenIR/BuildCacheManipulator.swift +++ b/Sources/GenIR/BuildCacheManipulator.swift @@ -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)") diff --git a/Sources/GenIR/Extensions/FileManager+Extension.swift b/Sources/GenIR/Extensions/FileManager+Extension.swift index 5f1a4b8..964df3f 100644 --- a/Sources/GenIR/Extensions/FileManager+Extension.swift +++ b/Sources/GenIR/Extensions/FileManager+Extension.swift @@ -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) } diff --git a/Sources/GenIR/Extensions/String+Extension.swift b/Sources/GenIR/Extensions/String+Extension.swift index 1eb1774..ca6e499 100644 --- a/Sources/GenIR/Extensions/String+Extension.swift +++ b/Sources/GenIR/Extensions/String+Extension.swift @@ -31,6 +31,7 @@ extension String { return self[startIndex..() diff --git a/Sources/GenIR/StdoutLogHandler.swift b/Sources/GenIR/StdoutLogHandler.swift index 96e850a..f95a688 100644 --- a/Sources/GenIR/StdoutLogHandler.swift +++ b/Sources/GenIR/StdoutLogHandler.swift @@ -22,9 +22,10 @@ struct StdOutLogHandler: LogHandler { var logLevel: Logging.Logger.Level = .info - init(label: String) { } + init(_: String) { } // swiftlint:disable function_parameter_count + // periphery:ignore:parameters source func log( level: Logger.Level, message: Logger.Message, @@ -36,7 +37,7 @@ struct StdOutLogHandler: LogHandler { ) { let levelPrefix = prefix(for: level) let timestamp = timestamp(for: level) - let lineInfo = lineInfo(for: level, source: source, file: file, function: function, line: line) + let lineInfo = lineInfo(for: level, file: file, function: function, line: line) print("\(timestamp)\(lineInfo)\(levelPrefix)\(message)") } @@ -70,7 +71,7 @@ struct StdOutLogHandler: LogHandler { } } - private func lineInfo(for level: Logger.Level, source: String, file: String, function: String, line: UInt) -> String { + private func lineInfo(for level: Logger.Level, file: String, function: String, line: UInt) -> String { switch level { case .trace, .debug, .notice, .warning, .error, .critical: return "[\(file):\(line) \(function)] " diff --git a/Sources/GenIR/Targets/Targets.swift b/Sources/GenIR/Targets/Targets.swift index 3d63854..32862d9 100644 --- a/Sources/GenIR/Targets/Targets.swift +++ b/Sources/GenIR/Targets/Targets.swift @@ -118,4 +118,4 @@ extension Targets: Collection { func makeIterator() -> CollectionType.Iterator { targets.makeIterator() } -} \ No newline at end of file +} From b865fd61e8dd4f0a82a35ba0b1b8e5fb557614dd Mon Sep 17 00:00:00 2001 From: NinjaLikesCheez Date: Mon, 23 Oct 2023 11:05:18 +0200 Subject: [PATCH 3/7] Add workflows for linting --- .github/workflows/SwiftLint.yml | 18 ++++++++++++++++++ .github/workflows/build.yml | 5 +---- .github/workflows/periphery.yml | 21 +++++++++++++++++++++ 3 files changed, 40 insertions(+), 4 deletions(-) create mode 100644 .github/workflows/SwiftLint.yml create mode 100644 .github/workflows/periphery.yml diff --git a/.github/workflows/SwiftLint.yml b/.github/workflows/SwiftLint.yml new file mode 100644 index 0000000..12300cf --- /dev/null +++ b/.github/workflows/SwiftLint.yml @@ -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/action-swiftlint@3.2.1 + env: + DIFF_BASE: ${{ github.base_ref }} \ No newline at end of file diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 81350e9..8a13885 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -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-latest steps: - uses: actions/checkout@v3 diff --git a/.github/workflows/periphery.yml b/.github/workflows/periphery.yml new file mode 100644 index 0000000..8689e82 --- /dev/null +++ b/.github/workflows/periphery.yml @@ -0,0 +1,21 @@ +name: periphery + +on: + pull_request: + paths: + - '**/*.swift' + +jobs: + periphery-scan: + runs-on: macos-latest + 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 From a87ead8104e577776320adeee3e799f5abe87896 Mon Sep 17 00:00:00 2001 From: NinjaLikesCheez Date: Mon, 23 Oct 2023 11:05:45 +0200 Subject: [PATCH 4/7] Add drawio file for the branching model to make it easier to change in the future --- Documentation/files/branching_model.drawio | 235 +++++++++++++++++++++ 1 file changed, 235 insertions(+) create mode 100644 Documentation/files/branching_model.drawio diff --git a/Documentation/files/branching_model.drawio b/Documentation/files/branching_model.drawio new file mode 100644 index 0000000..8b38980 --- /dev/null +++ b/Documentation/files/branching_model.drawio @@ -0,0 +1,235 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 98c8a30d1d3ae82449fb21fda606463e5886efe4 Mon Sep 17 00:00:00 2001 From: NinjaLikesCheez Date: Mon, 23 Oct 2023 11:11:28 +0200 Subject: [PATCH 5/7] Use macos-13, apparently it's still in beta and not -latest... --- .github/workflows/build.yml | 2 +- .github/workflows/periphery.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8a13885..d4c66cc 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -7,7 +7,7 @@ on: jobs: build: - runs-on: macos-latest + runs-on: macos-13 steps: - uses: actions/checkout@v3 diff --git a/.github/workflows/periphery.yml b/.github/workflows/periphery.yml index 8689e82..b645c49 100644 --- a/.github/workflows/periphery.yml +++ b/.github/workflows/periphery.yml @@ -7,7 +7,7 @@ on: jobs: periphery-scan: - runs-on: macos-latest + runs-on: macos-13 steps: - uses: actions/checkout@v1 - name: Set up Homebrew From b41c23ba8bbb2540d4b51b43385747bf79b19d98 Mon Sep 17 00:00:00 2001 From: NinjaLikesCheez Date: Mon, 23 Oct 2023 11:31:32 +0200 Subject: [PATCH 6/7] Remove brew extract command in favour of easier instructions --- Documentation/releasing_an_update.md | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/Documentation/releasing_an_update.md b/Documentation/releasing_an_update.md index 3627bc1..df8f7ce 100644 --- a/Documentation/releasing_an_update.md +++ b/Documentation/releasing_an_update.md @@ -74,16 +74,8 @@ So, if you have released a new major or minor version you should: ### Creating Versioned Formulae -Creating a versioned formula can happen in one of two ways - I suggest using `brew extract` for this, but you can also manually find and copy the formula file, ensuring you add `keg_only :versioned_formula`. +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@` -Rather unhelpfully, you can only use `brew extract` to extract a formula from one tap to another - not to an existing tap with the same formula. In this case you can substitute in any tap, but in this case I will use mine: `ninjalikescheez/tap` +Edit the file to add the `keg_only :versioned_formula` tag after the `bottle`. -```shell -# assuming you're inside the veracode/homebrew-tap checkout -brew extract --version= veracode/tap/gen-ir ninjalikescheez/tap -cp /opt/homebrew/Library/Taps/ninjalikescheez/homebrew-tap/Formula/gen-ir@.rb Formula/ -``` - -Edit the file to add the `keg_only :versioned_formula` tag. - -TODO: Try this irl and see if the brew automation is able to auto-add the bottles or if we have to do it ourselves. +> Note: it is a good idea to run `brew style Formulae/gen-ir@.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. From e27bfe846b86ef2c9ee116cfe50530c8ae32d33a Mon Sep 17 00:00:00 2001 From: NinjaLikesCheez Date: Mon, 23 Oct 2023 14:52:04 +0200 Subject: [PATCH 7/7] Clean up documentation --- Documentation/branching_model.md | 20 +- Documentation/files/branching_model.drawio | 235 --------------------- Documentation/images/branching_model.png | Bin 52317 -> 0 bytes Documentation/releasing_an_update.md | 18 +- 4 files changed, 27 insertions(+), 246 deletions(-) delete mode 100644 Documentation/files/branching_model.drawio delete mode 100644 Documentation/images/branching_model.png diff --git a/Documentation/branching_model.md b/Documentation/branching_model.md index 5172fda..21484dd 100644 --- a/Documentation/branching_model.md +++ b/Documentation/branching_model.md @@ -2,13 +2,12 @@ ![Branching Model](images/branching_model.png) -Gen IR uses a modified version of [GitFlow](https://nvie.com/posts/a-successful-git-branching-model/) as the basis of it’s branching model. This model is tried, tested, and has remained so over 10+ years for a project of this type. +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: -- `develop` becomes `unstable` -- No `hotfix` branch for now. We can just follow the regular flow -- Unstable releases are tagged on `unstable` if and when we want to make a new release +- 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 @@ -19,11 +18,14 @@ Releases should increment this (see [Releasing an Update](releasing_an_update.md ## New Feature Development -- Create a new branch off `unstable` and name it appropriately - - `git checkout unstable && git pull && git checkout -b sensibly_named_branch` +- 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 `unstable` branch +- Create a merge request to the `develop` branch -### Unstable releases +## New Release -If a feature should be released for testing & early adopters, you will need to do some additional steps. See [Releasing an Update - Unstable](releasing_an_update.md#unstable) for more. +- Create a branch off `develop` and name it `release/` +- Test, QA, fix +- Merge to `main` and create a release +- Merge to `develop`, remove the `develop` tag and retag the new commit with `develop` diff --git a/Documentation/files/branching_model.drawio b/Documentation/files/branching_model.drawio deleted file mode 100644 index 8b38980..0000000 --- a/Documentation/files/branching_model.drawio +++ /dev/null @@ -1,235 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Documentation/images/branching_model.png b/Documentation/images/branching_model.png deleted file mode 100644 index a277abb4443187629249a931ed68d4009d9a9f13..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 52317 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 + - `git push --tags` Then, in the GitHub UI: - 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 +- 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 + A release has been made, congratulations. However there's additional steps for distributing the release via `brew`. ## Distributing a release