Skip to content

Contribute a fix to Pharo

StéphaneDucasse edited this page May 12, 2020 · 41 revisions

This tutorial shows how to contribute to Pharo using Iceberg. For more information about Iceberg, check its wiki in here.

In a nutshell

The general process is summarised as the following steps:

  1. Download the latest version (this is important since I will make sure that you do not have to resync your fork manually and also that you are not reverting changes that were already made in Pharo).
  2. Use repair (it will fetch some commits)
  3. Use repair (and create a branch let us called Bottom-123 that will point to the commits of your image).
  4. Create a new branch for the issue you want to work on.
  5. Code, then commit, then push to YOUR fork
  6. Issue a PullRequest from your fork to Pharo
  7. Check out your Bottom-123 branch and you can restart step 5

Video Tutorials

A Pharo TechTalk shows the whole process for two simple issues: TechTalk Recording.

Step 0: Setting up the development environment

Download and launch latest 9.0 pharo:

The recommended way to download Pharo is to use the Pharo launcher, which you can get from Pharo download's page. Otherwise, if you have a nice command line environment (wget, readline, bash), download latest development pharo using zeroconf.

Pro tip: If you're on windows and you want a nice command line environment, install msys

wget -O- get.pharo.org/64/90+vm | bash
./pharo-ui Pharo.image

If you don't have a command line environment, you can download both image and vm manually from the following links for windows for example:

Or you can browse the file server and find the files suiting your environment.

Fork the Pharo repository

All changes you'll do will be versionned in your own fork of the pharo repository. Then, from your fork you'll be able to issue pull requests to pharo, where they will be reviewed, and luckily, integrated.

Go to pharo github's repository and click on the fork button on the top right. Yes, this means that you'll need a github account to contribute to pharo, yes.

Setup Iceberg

To be able to contribute to Pharo, you need a pharo git repository.

Pre-requisite: Setting credentials

You will need to set a valid set of credentials in your system to be able to work with Pharo. In case you use SSH (the default way), you will need to make sure those keys are available. In case they are not (and you will notice as soon as you try to clone a project or commit a change into one), you can add them following this steps:

  • in linux, execute in your shell:
    ssh-add ~/.ssh/id_rsa
  • in OSX, execute in your shell:
    ssh-add -K ~/.ssh/id_rsa

Both for OSX and linux you can add such lines in your .bash_profile (or the one corresponding to your shell installation) so they are automatically executed on each new shell session.

  • On windows is more complicated, you may need to generate a pair of keys (that needs to be uploaded to your account on github). You can follow instructions on how to generate your keys here.

Then you need to go to settings browser, search for "Use custom SSH keys" and complete your data there. Alternatively, you can execute in your image playground:

IceCredentialsProvider useCustomSsh: true.
IceCredentialsProvider sshCredentials
	publicKey: 'path\to\ssh\id_rsa.pub';
	privateKey: 'path\to\ssh\id_rsa'

Pro Tip:: this can be used too in case you have a non default key file, you just need to replace "id_rsa" with your file name.

Step 1. Setting up your repository

A fresh Pharo image comes with a pre-configured Pharo repository. This repository will be in state "Local Repository Missing". This means that the image does not find your forked pharo clone in your disk. You can have more details of it in the Glossary.

Repairing local repository missing

To solve this situation, you need to rebind your repository with your local clone. You will be proposed with the repair menu item/button.

And clicking on it will show you the repair view, showing an explanation of the current situation and some proposed solutions:

You can then choose to search in your disk for an existing clone or to clone as a new repository your forked Pharo repository.

Once the repository has a clone, it will check the repository status and most probably you'll find out that your repository is in Fetch required state.

Solving the Fetch Required

Fetch Required means that your image was built from a commit that cannot be found in your repository. In other words, we need to update your repository, doing a fetch (more details of it in the Glossary).

If you click again on the repair action, you'll see that there are other repair actions available. Usually, if you already have all your remotes correctly configured, doing a fetch will put you in a Detached Working Copy state.

Pro Tip:: Usually instead of doing a simple fetch (second option) it is quite powerful to create a branch (first option), give it a name like sync, bottom... This branch is pointing to the point where your repository and image are in sync and this is super useful to be able to checkout it later when you want to do multiple PRs on different and unrelated issues. This way you can go back to a sync state in one click and be super productive.

Step 2: Opening an issue

The process of contributing to pharo starts by opening an issue. Please, address yourself to the issue tracker.

Click on New issue and:

  • Put a title to it
  • Write a description
  • And finally click on Submit new isue

Step 3: Work on your image and push your change

Once you have modifications in your image, it's time to push those changes to your fork and make a pull request. To do that, we enforce the following process:

  • you create a local branch for the issue
  • you issue a pull request of that issue to the main pharo development branch

Solving the Detached Working Copy

Detached Working Copy means that the image commit does not correspond with the repository commit (more details of it in the Glossary). At this point, we need to synchronize both to be able to work.

Most of the times, the easier thing to do in this case is to just create a new branch. If you already know which issue you'll be working on, you can create a branch using the "New branch from issue" option. Otherwise, a nice alternative is to create a temporary branch like temp/synch that you can later on remove.

Step 4: Issue a pull request

Once you have done and commited all your work, you need to push it and create a pull request. Right click on the repository and go to the Github plugin.

Select the option Create pull request and select as target branch pharo's development branch.

And issue the pull request!

Pro Tip: If your PR fixes the issue, you can put a keyword "fixes #IssueNumber" in the description to automatically close the issue on merge. https://help.github.com/en/articles/closing-issues-using-keywords

Step 4: Follow your pull request

If you go to github, you'll see your pull request open and that some checks are running.

You can click in details to go see the jenkins job validating the pull request. This is always a cool feeling, so enjoy it.

Pro Tip: Note that if your PR fails because of test failing or you want to integrate feedback provided by reviewed, it is super simple: just continue to commit in your branch. Your Pull Request will be updated with your new changes.

Step 5: Once your pull request is integrated

Some cleanups are required:

  • remove your branch from your fork
  • close the issue (this is done automatically if your PR contained "fixes #numberOfIssue")

Why you do not need to resync your fork with the pharo repo?

No you do not need to explicitly resync your fork. Why? Because when you push your commits, you push also the Pharo commits. But let us look at it in details:

  • When you download an image (imagine that this image contains the code of commit3 and that Pharo'repository is at commit5), the repair action will fetch all the commits (up to 5) and put them in your LOCAL repository.
  • When you create your bottom branch (the branch that points to the situation of your image when you downloaded) and later a child branch for your fixes (call it myfix), it means that when you commit your myfix branch all the commits from myfixes and then from commit3 down to the common ancestor between your fork and your local repository will be pushed back to your fork.

Now if you downloaded the latest image (imagine for commit6 and that the pharo repository is at commit6 - yes this is the latest image!) when you push your branch (which here points to commit6), automatically all the commits (6 down to the common ancestors between your local repo to your fork) will be pushed to your fork. So your fork will be in sync with Pharo's one.

So each time you work and push to your fork from the latest image, your fork gets updated.