Giter Club home page Giter Club logo

hupkit's Introduction

HuPKit

In short HuPKit allows project(s) maintainers to easily manage their GitHub repositories, merging pull requests, creating new releases, merging older versioned branches into newer once and much more.

Note: On October 23rd 2023 the repository was moved to it's own organization, and renamed to HuPKit. The old PHP namespace has been left unchanged.

Features

  • Checkout an issue (as local working branch).
  • Merge pull-requests with preservation of all information (description and GitHub discussion).
  • (Up)Merge version branches without mistakes.
  • Create new releases with a proper changelog, and no gaps in version numbers.
  • (Automatically) Split a monolith repository into READ-ONLY repositories.

This tool is designed for project maintainers with a good knowledge of Git and GitHub.

If you have some special needs, please see the contributing section below.

Requirements

You need at least PHP 8.1, Git 2.10 and a GitHub account (GitHub Enterprise is possible). Composer is assumed to be installed and configured in your PATH.

Installation

HuPKit is a PHP application, you don't install it as a dependency and you don't install it with Composer global.

To install HuPKit first choose a directory where you want to keep the installation. Eg. ~/.hupkit or any of your choice.

Caution: Make sure you don't use a directory that is accessible by others (like the web server root) as this may expose your API access-token!

Download HuPKit by cloning the repository:

mkdir ~/.hupkit
cd ~/.hupkit
git clone https://github.com/hupkit/hupkit.git .

Checkout the latest version. Eg.

git checkout tags/1.0.0 -b version-1.0.0

And install the dependencies:

./bin/install

Special note for Windows users

HuPKit has not been tested on Windows yet, it should work. But you may encounter some problems.

Note that HuPKit expects a Unix (alike) environment. You are advised to use the Git console or Bash shell (Windows 10+).

Please open an issue in the issue-tracker when something is not working. Or open a pull-request when you can fix the problem ๐Ÿ‘

Updating

Updating HuPKit is very easy. Go to the HuPKit installation directory, and run ./bin/upgrade.

Done, you now have the latest version.

Basic usage

Run hupkit help for a full list of all available commands and options.

Note: All commands except help, repo-create and self-diagnose require you are in a Git repository, and have Git remote upstream existing and pointing to the GitHub head repository (from which all work is coordinated, not your fork).

See the usage documentation for full instructions.

Versioning

For transparency and insight into the release cycle, and for striving to maintain backward compatibility, this package is maintained under the Semantic Versioning guidelines as much as possible.

Releases will be numbered with the following format:

<major>.<minor>.<patch>

And constructed with the following guidelines:

  • Breaking backward compatibility bumps the major (and resets the minor and patch)
  • New additions without breaking backward compatibility bumps the minor (and resets the patch)
  • Bug fixes and misc changes bumps the patch

For more information on SemVer, please visit http://semver.org/.

Contributing

HuPKit is open-source and community driven, but to prevent becoming to bloated not all requested features will be actually accepted.

The purpose of HuPKit is to ease the daily workflow of project maintainers, not to replace already sufficient functionality. Creating an issue is easier with the web interface then using a limited CLI application.

Support for other adapters, like BitBucket or GitLab will only ever happen once all adapters support the same level of functionality and stability and performance is not negatively affected.

License

HuPKit is provided under the MIT license.

Credits

This project is maintained by Sebastiaan Stok (aka. @sstok).

HuPKit was inspired on the GH Tool used by the Symfony maintainers, no actual code from GH was used.

hupkit's People

Contributors

acrobat avatar angyvolin avatar dependabot[bot] avatar gwendolenlynch avatar jibbarth avatar nicolas-grekas avatar sstok avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

hupkit's Issues

Automatically close related issues

Q A
Bug report? no
Feature request? yes
BC Break report? no
RFC? no

The pull-request template used by Hubkit managed projects allow to provide which issues were fixed, but more then often I forget to close these issues. Instead these issues should be detected and automatically be asked if these should be closed (or at least some).

Yes I know GitHub provides auto closing closes #xxx but this doesn't work with markdown templates ๐Ÿ˜ฅ

[RFC] Automatically delete pr "working branch" instead asking

Description
Currently when you merge your own pull request you get asked if you want to remove the "working branch" as this gets easily forgotten. But as with #85 you get asked multiple questions.

Instead I propose to automatically remove the "working branch" (if fully merged of course and not the "master" or versioning branch). And only keep it with the new option --no-cleanup (or a better name).

[bug] config managent might lead to removal of ignored files

HubKit version(s) affected: 1.6-BETA7

When you run the config-init command (or checkout the _hubkit branch) and have a config.php file that is ignored by Git (as is the case for HubKit itself) the config.php file will overwritten.

And the same is true for other files, although unlikely I still consider this a serious problem. Both commands should check if these files exist (and are ignored by .gitignore) and warn that these will be temporarily moved to named file like hk~config.php, once done these files moves are moved back.

As the the config-init command is designed with the purpose of initializing the configuration branch this requires a finalizing command to clean-up everything once done.

Effectively editing/initializing the configuration is as follows:

  1. inti-config or edit-config (new command)
  2. Editing the configuration, adding files, etc
  3. save-config verifies the configuration (by crashing if broken ๐Ÿ˜… ), checkout the previous branch (before editing started),
    and restores backed-up files.

In the rare case the temp files still exist fail hard with an error, and require to solve this manually.

Existing release tag is displayed as version gap

[WARNING] It appears there is gap compared to the last version.
           Expected one of : 0.6.2, 0.7.0, 1.0.0-BETA1, 1.0.0

Instead this should fail and tell a release already exists for this tag as it's properly a user error.
And suggest a possible next version (which is valid).

Squashed merge doesn't show up in changelog

Q A
Bug report? yes
Feature request? no
BC Break report? no
RFC? no

When a PR is merged with the --squash option, the "merge" commit doesn't show up in the changelog. It looks like this commit done by the github api is not a real merge commit to git.

git log --merges ... used for the changelog command does not list that commit.

KnpLabs/php-github-api@5eb55ce Example commit has only one parent if merged with --squash

I was also looking at symfony commits but somehow they can have a squash merged with a commit with 2 parents -> symfony/symfony@cea5ebc

[Merge] Repository splitting should be done when branch was updated

Q A
Bug report? yes
Feature request? no
BC Break report? no
RFC? no
 [OK] Pull request has been merged.

 [WARNING] The Git working tree has uncommitted changes, unable to update your local branch.

 Split repository now? (yes/no) [yes]:
 > 

Splitting is not possible here because the local branch is not updated, this split would have no effect.

Ensure everything works for version 1.2.0

The big day is almost here. HuPKit v1.2.0 final.

But running split-repo revealed a fatal bug (#124), and I'm pretty sure this isn't the last one.

  • Add tests for
    • SwitchBaseHandler
    • SynchronizeConfigHandler
    • InitConfigHandler
    • EditConfigHandler
    • CheckoutHandler
  • Update vendors
  • Run all commands
  • Ensure proper testing coverage
  • Ensure no major PHPStan errors
  • Ensure Github workflows are working
  • Small things, CS etc.

[RFC] Remove automatically closing of linked issues

Pull request #59 introduced to the ability to detect and automatically close related issues. In the meantime this feature was added natively to GitHub itself.

I propose to remove this functionality from HubKit and use the GitHub auto detection instead.

Upmerge with automatic repository splitting

Q A
Bug report? no
Feature request? yes
BC Break report? no
RFC? no

Problem: When using upmerge with a monolith repository you still need to split the repository manually after each upmerge operation.

Proposal: Automatically (or ask to) split the repository after an upmerge operation, unless the option --no-split was provided.

Automatically use the current branch for `take`

Description
The take command defaults to the master branch, in many projects this has (or is changing to) main or versioned branch names instead.

Instead of changing the default to main the command should instead use the current branch-name as the base, and check if the branch is either a common name like: master, main, devel, develop, or an acceptable major.minor version syntax.
And ask for confirmation if this is not the case (to prevent mistakes).

In fact, the current situation is misleading:

$ hk take 290
Working on rollerworks/search (branch main)

fatal: The command "'git' 'checkout' 'upstream/master'" failed.

Documentation building broken

Documentation building is currently broken and cannot be fixed easily, as Markdown has reached it's limits for what this project needs it's best to switch to RestDoc instead.

I'm working on this, so stay tuned.

[bug] MergeHandler fails when commit is not linked to user account

HubKit version(s) affected: 1.0

Description
This pull request failed to merge because the commit was using the GitHub web interface, and no user was selected.
rollerworks/PasswordStrengthValidator#39

Possible Solution

        foreach ($commits as $commit) {
            if (! isset($commit['author'])) {
                $authors['web-flow'] = $authors['commit']['author']['name'] ?? 'web-flow'; // web-flow is the default user for GitHub web edited commits.
            } else {
                $authors[$commit['author']['login']] = $commit['author']['login'];
            }

            $message .= $commit['sha'].' '.explode("\n", $commit['commit']['message'], 2)[0]."\n";
        }

Additional context

Print-r dump of the commit.

Array
(
    [sha] => 0a4acd92e95a6d5df7f08a955af3aee10b03f02b
    [node_id] => MDY6Q29tbWl0MzIyNTU4MDI3OjBhNGFjZDkyZTk1YTZkNWRmN2YwOGE5NTVhZjNhZWUxMGIwM2YwMmI=
    [commit] => Array
        (
            [author] => Array
                (
                    [name] => Cรฉdric Martineau
                    [email] => [email protected]
                    [date] => 2020-12-18T11:04:46Z
                )

            [committer] => Array
                (
                    [name] => Cรฉdric Martineau
                    [email] => [email protected]
                    [date] => 2020-12-18T11:04:46Z
                )

            [message] => Fix regex for specials characters
            [tree] => Array
                (
                    [sha] => 27221ca879d57cc0e6353b9f827e6f5276c4feab
                    [url] => https://api.github.com/repos/tino299/PasswordStrengthValidator/git/trees/27221ca879d57cc0e6353b9f827e6f5276c4feab
                )

            [url] => https://api.github.com/repos/tino299/PasswordStrengthValidator/git/commits/0a4acd92e95a6d5df7f08a955af3aee10b03f02b
            [comment_count] => 0
            [verification] => Array
                (
                    [verified] =>
                    [reason] => unsigned
                    [signature] =>
                    [payload] =>
                )

        )

    [url] => https://api.github.com/repos/tino299/PasswordStrengthValidator/commits/0a4acd92e95a6d5df7f08a955af3aee10b03f02b
    [html_url] => https://github.com/tino299/PasswordStrengthValidator/commit/0a4acd92e95a6d5df7f08a955af3aee10b03f02b
    [comments_url] => https://api.github.com/repos/tino299/PasswordStrengthValidator/commits/0a4acd92e95a6d5df7f08a955af3aee10b03f02b/comments
    [author] =>
    [committer] =>
    [parents] => Array
        (
            [0] => Array
                (
                    [sha] => 98a72a0a8a2f599afee137666ae0c4faceee25d3
                    [url] => https://api.github.com/repos/tino299/PasswordStrengthValidator/commits/98a72a0a8a2f599afee137666ae0c4faceee25d3
                    [html_url] => https://github.com/tino299/PasswordStrengthValidator/commit/98a72a0a8a2f599afee137666ae0c4faceee25d3
                )

        )

)

Note. I will try to fix this later today ๐Ÿ‘๐Ÿผ

[Feature] Show GitHub checks status when merging

Description
When using TravisCI the build-status is shown in the status table of the merge command but GitHub checks are not shown here?

Example

| Item                      | Status | Details                   |
|---------------------------|--------|---------------------------|
| Full CI process / PHP 7.1 | OK     | Successful in 2m          |
| Full CI process / PHP 7.2 | OK     | Successful in 2m          |
| Full CI process / PHP 7.3 | OK     | Successful in 2m          |
| Full CI process / PHP-QA  | Failed | Failing after 1m โ€” PHP-QA |
| Scrutinizer               | OK     | No new issues             |

[Feature][Upmerge] Allow to change/detect 'main' branch

Description
Some repositories use 'master' as the final branch for upmerging while newer repositories use 'main'

It should be possible to detect what the correct branch is, though a git config (core.main-branch) .
If absent use 'master' for compatibility (can be changed in v2.0).

Redesign documentation

Currently the documentation has a number of problems that need to be resolved.

  • No way to see all navigation
  • Local configuration isn't really explained, as new hook scripts will be placed this needs better coverage
  • Configuration schema isn't directly accessible, only though other pages (see first point)
  • Authentication for GitHub enterprise should in the configuration page

release: Show expected versions when a gap is detected

Release command detects when there is a gap between versions (compared to the last one in for the major version). It would be nice to also known which versions "are" expected.

This should be as precise as possible, so a gap in the minor should only inform minor not patch.

Say the following versions exist

v1.0.0-beta1
v1.0.0-beta2
v1.0.0-beta3
v1.0.0-beta4
v1.0.0-beta5
v1.0.0-beta6
v1.0.0-beta7
v1.0.0
v1.0.1
v1.1.0

And I release 1.3.0 I should see:

It appears there is gap compared to the last version.
Expected: v1.2.0

Please check your input or confirm is this intended.

Expected candidates for (with current version list shown above):

  • 1.1.2 -> 1.1.1
  • 2.0 -> none
  • 1.2.1 -> 1.2.0

Git root-directory detection is not working

HubKit can only be used "properly" from the Git root-directory, but the detection seems broken.
This not a big issue as it does work, but branch-alias detection is incorrect when you are in a sub-directory ๐Ÿ˜…

[RFC] Deprecate global repository configuration

Since HuPKit v1.2 it's possible to store repository configuration (repository splits mainly) either locally (in the _hubkit branch) or globally in the config.php located with the installed HuPKit installation.

In v1.3 a new feature was (is) added to allow configuring the main-branch, and additional features are planned as well.
Note that the main-branch can only be configured with the local configuration, and the same will apply to new repository configuration as well (with the exception of branch-level configurations).

For HuPKit v1.4 I'd like to propose to deprecate the global repository configuration (not adapter configurations, as tokens cannot be stored within version control ๐Ÿ˜„ ) and remove global repository configuration completely in v2.0.

This makes the documentation easier to understand and explain and prevents outdated configuration among team members.
Note that it's not required (but recommended) to push the _hubkit configuration branch to the remote central repository, so only keeping this branch locally still works as normal.

Please let me know of any objections, thanks ๐Ÿ‘๐Ÿผ

Automatically (offer to) composer.json branch-alias

Q A
Bug report? no
Feature request? yes
BC Break report? no
RFC? no

When you make a new minor/major release the composer.json branch alias should be updated afterwards. I tend to forget this, so it would make sense to add this feature to the release command.
And automatically commit and push.

Note: It should be offered to update the branch alias, as not always this possible or there could be commits that weren't pushed yet. In relation to #9 this is disabled when there are custom scripts used.

[Release] Fatal error when prefix directory does not exist

Q A
Bug report? yes
Feature request? yes
BC Break report? no
RFC? no

When a configured prefix directory does not exists a fatal error is thrown, the problems happens with tag synchronizing.

  • Check for all existing prefixes before the operation (warn if missing, and ignore if confirmed)
  • Allow different split configurations per branch-source

[bug] Repository split doesn't work when branch is checked out

HubKit version(s) affected: v1.2.0

 Error Output:
  ================
  remote: error: refusing to update checked out branch: refs/heads/main
  remote: error: By default, updating the current branch in a non-bare repository
  remote: is denied, because it will make the index and work tree inconsistent
  remote: with what you pushed, and will require 'git reset --hard' to match
  remote: the work tree to HEAD.
  remote:
  remote: You can set the 'receive.denyCurrentBranch' configuration variable
  remote: to 'ignore' or 'warn' in the remote repository to allow pushing into
  remote: its current branch; however, this is not recommended unless you
  remote: arranged to update its work tree to match what you pushed in some
  remote: other way.
  remote:
  remote: To squelch this message and still keep the default behaviour, set
  remote: 'receive.denyCurrentBranch' configuration variable to 'refuse'.
  To file:///var/folders/6h/r8zg1bc56q77p71lnj38ln1w0000gn/T/hubkit/stor/repo_afd97f6cec2c5a25a2f235183fe557e5a70804f0
   ! [remote rejected]   b8e0efe1c4c745dbe022371dfa485f221caa7998 -> main (branch is currently checked out)
  error: failed to push some refs to 'file:///var/folders/6h/r8zg1bc56q77p71lnj38ln1w0000gn/T/hubkit/stor/repo_afd97f6cec2c5a25a2f235183fe557e5a70804f0'

I'm already working on a fix.

Command to switch pull-request base

Q A
Bug report? no
Feature request? yes
BC Break report? no
RFC? no

We had this in Gush (mainly for contributors), but since GitHub allows to update pull-request of a contributor (unless disabled) it makes sense to have it in Hubkit also.

This makes it easier to help contributors without having to perform complex Git operations or resorting back to local Git merges and closing a pull-request (like Symfony's GH does).

[Merge] `--squash` doesn't acutally squash

I just merged a pull request with the --squash option but still the commits were retained as-is, nothing was squashed.

Not sure if this a bug in Hubkit or the GitHub API end-point.

[Release] only push the new tag (Monolith splitting only)

Q A
Bug report? yes
Feature request? no
BC Break report? no
RFC? no

Currently when a new release is made all the tags are pushed which in some rare cases results in an unresolvable fatal error. Instead only the new tag must be pushed, and no other tags.

Allow `[patch | minor | major | ....]` as version for release command

When creating a new release I should be able to use the next "version fragment" automatically
hubkit minor and get the next logical minor version for this branch.

The command already validates if there are gaps so getting the next version should not be a problem.

This should support patch, minor, major, beta, rc and alpha. And increase that fragment.
For beta this means the current beta version is increased, if there there is no current beta release then increase the minor version and set beta to 1.

Pre/post release script execution

Problem: Sometimes a release requires the execution of a script for some additional process, like updating the meta-data version number, updating the changelog release date, etc.

Solution: Detect if a ./.hubkit/[pre|post]-release.php file exists and execute it.

When the pre-release script updates versioned files, a new pull-request will be created (and merged, as a normal GitHub merge) so changes can be traced.

The post script should be used for release workflow components (like publishing a pre-written article in an external CMS, Tweeting an announcement, etc.) when versioned files are changed these need to be commited and pushed manually.

[Feature] Allow to skip empty releases

Description
Allow to skip a release for a split-repository which doesn't have any new commits.

This feature can be enabled using either a repository config (schema-version 2) or using a using a command option.
--skip-empty=[force-]yes|no.

Rebase (new command)

Q A
Bug report? no
Feature request? yes
BC Break report? no
RFC? no

Add a rebase command for pull-request to update the remote and local branch (if any) to skip some manual steps.

self-diagnose command fails when run from a Git repository without upstream remote

Problem: The self-diagnose command fails when run from a Git repository without the upstream remote being set. This problem is caused by GitHub::autoConfigure() which is called whenever a Git repository is detected.

For install I solved this by adding the remote automatically, but for other cases this should be taken care of properly. It's just a small issues, but it should be fixed.

Solution: Only run GitHub::autoConfigure() when RequiresGitRepository is implemented by the CommandHandler. Making this method required for Git enabled CommandHandlers, and ignored otherwise.

Choose head remote

Q A
Bug report? no
Feature request? yes
BC Break report? no
RFC? no

Hi,
Is it possible to add a way to choose the head remote ? (and choose something different than upstream)

I can suggest you using the composer extra field to make configuration (like that it would be repository-wide only.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.