-
Notifications
You must be signed in to change notification settings - Fork 13
Specification: Contribution Management
This specification outlines the functionality for the Contributor Workflow functionality of mrbelvedere. The Contributor Workflow is designed to support a traditional master / fork GitHub contribution model directly to a Salesforce DE org with no local software required. The goal is to lower the bar for submitting contributions to a Salesforce development project hosted on GitHub by allowing non-developer admins to submit metadata changes to the project repository with only a DE org and a Github account.
- One DE org per Contribution: Each individual Contribution is assumed to have its own assigned DE org to simplify the process. If a Contributor wishes to reuse a DE org from a submitted Contribution, they are responsible for manually cleaning the org.
- DE orgs only: While this could be revisited in the future, for now, we intend to only support connecting DE orgs to avoid impacting any production orgs
- DE org data is not persistent: Since we might have to uninstall managed packages to upgrade them or down the road might want to manage metadata deletions for the Contributor, no data in the DE org should be considered persistent.
- Contributor comes to page to start a new Contribution. They are shown instructions providing an overview of the process and what’s involved as well as a button to start the process. The Contributor reads the instructions and clicks the button to start.
- The Contributor is taken to a page to authorize access to their Github repositories via OAuth
- If the Contributor does not have a fork of the main repository, they are prompted to authorize creating one on their behalf
- The Contributor is taken to the New Contribution form
- The Contributor is prompted to select an existing GitHub issue from the main repository or to create a new issue
-
Existing Issue: The Contributor can enter a Github Issue ID to use an existing issue.
- Provide a link to the repo’s issues
- Add a comment with an @ mention for the contributor
-
New Issue: The Contributor can enter a new issue with a Title and Body
- Suggest existing issues
- Allow assigning labels
- Add an @ mention of the contributor in the body
-
Existing Issue: The Contributor can enter a Github Issue ID to use an existing issue.
- The Contributor is prompted to select an existing GitHub issue from the main repository or to create a new issue
- The Contributor is prompted for a hyphenated string to describe their branch
- Widget restricts to a-z,0-9,-
- feature/<ISSUE_ID>- automatically prefixed
- The name format should be made configurable at some point
- The branch is automatically created in the Contributor’s fork
- A comment is posted to the GitHub Issue @ mentioning as working on a contribution with a link to the Contribution on mrbelvedere and to the Contributor’s branch on GitHub
- The Contributor is guided through the process of connecting a Salesforce DE org
- Instructions to create a DE org
- Instructions for any manual configuration required for the package (i.e. enable Chatter)
- OAuth grant of access
- The initial sync process begins
- The Contributor is shown a status of the sync process which automatically updates
- The metadata from the branch is deployed to the DE org along with all dependencies including managed packages and unpackaged metadata
- The packaged metadata from the org is then retrieved and committed to their feature branch in their fork
- The Contributor is instructed to start developing their Contribution in their DE org and return when ready to commit or to submit their contribution
Once a Contributor has started a Contribution, they can return to the Contribution at any time to manage the process. When managing a Contribution, the Contributor is a presented overview information about their Contribution and of buttons to different management tasks
If the Contributor wants to save their work incrementally before submitting, they click the Commit button
- The last deploy date on the Contribution is compared against the latest commit date on the Contributor’s feature branch
- If there is a new commit since the last deployment to the Contributor’s DE org, the 3 Way Sync process is triggered (see below)
- The Contributor is prompted for a commit message describing the changes they are saving
- The Contributor’s feature branch is cloned by mrbelvedere
- The packaged metadata is retrieved from the Contributor’s DE org and unzipped on top of the locally cloned repository
- A git diff is used to build a new tree and commit in GitHub and then the feature branches git reference is updated to point to the new commit as HEAD.
- The Contributor is prompted to Submit their Contribution if it is completed.
When the Contributor is done with their work, they click Submit
- They are prompted to enter some information about their changes
- Reviewer Notes: Any notes they wish to make to the Reviewer
- Critical Changes: Any changes made in the Contributions which end users must be made aware of before installing the new release
- Changes: Minor changes in the functionality or new functionality added by the Contribution
- A Pull Request is automatically created requesting to merge the changes in their feature branch into the default branch of the main repository
- The Contributor is notified that their Contribution is pending review and provided a link to the Pull Request on GitHub.
When new changes are committed to the default branch in the main repository, a Contributor might want to pull those changes into their feature branch. To do this, they click Update
- The packaged metadata is retrieved from their DE org
- A local clone of their feature branch is created by mrbelvedere The packaged metadata is unzipped over the local cloned repository
- A git diff is used to compare the changes to see if the Contributor has any uncommitted changes in their DE org
- If there are any differences, the Contributor is prompted to first Save their changes
- If there are not any differences, an attempt is made to automatically merge the default branch of the main repository into the Contributor’s feature branch
- If the automatic merge fails due to a merge conflict, automatically create a Pull Request in GitHub to merge the main repository’s default branch into the fork’s feature branch and return a notice to the Contributor that the issue needs to be manually resolved with a link to the Pull Request.
If a Contributor has saved changes, they can revert their feature branch and org to a save point by clicking Revert
- The Contributor is shown a list of commits to select from starting with the latest commit
- The Contributor is warned that the change is destructive to anything currently in their DE org and will roll back subsequent commits
- Show commits which will be rolled back?
- The Contributor chooses to continue anyhow
- If the commit being deployed is not the feature branch’s HEAD, a new rollback commit is created on the Contributor’s feature branch
- The selected commit is pushed to the Contributor’s DE org
- Packaged metadata is retrieved from the DE org and committed back if there are any changes.
If a Contributor wishes to change to a different DE org for a Contribution, they click Swap Org to connect a different org
- The Contributor is warned that the old org will no longer be managed and clicks to accept the warning
- The current Salesforce OAuth information is cleared from the Contribution as well as the last deployed commit field
- The Contributor is guided through the process of connecting a new Salesforce DE org
- Instructions to create a DE org
- Instructions for any manual configuration required for the package (i.e. enable Chatter)
- OAuth grant of access
If a Contributor needs assistance, they click Help to be shown available Help resources.
When the manage page is loaded by the Contributor, a series of automated processes will be kicked off in the background to ensure all the needed parts are in place:
- Ensure that the Contributor has a fork of the repository. If not, create one automatically
- Ensure that the feature branch exists in the forked repository. If not, create it automatically
- ??? How should we handle pulling from the main repository to the default branch first?
- Ensure that the Github Issue exists. If not, create it automatically
- Check if the feature branch is behind the main repository. If so, alert the Contributor and prompt them to Update.
Because we are dealing with the entire set of packaged metadata, we need to be careful to never accidentally overwrite changes made by the Contributor in their DE org. In theory, this situation should be rare, but it is helpful to have a way to resolve the issue on behalf of the Contributor as it can be confusing.
We need to be able to detect the sync state between the fork repository’s feature branch, the main repository’s default branch,
-
Behind Main: The feature branch in the Contributor’s fork is behind the default branch of the main repository.
- Use the GitHub API to compare the feature branch in the Contributor’s fork repository with the default branch of the main repository. If the
-
Undeployed Commit: The feature branch in the Contributor’s fork has a HEAD commit which has not been deployed to the DE org
- Compare the branch HEAD from the GitHub API to to last deployed commit on the Contribution object which records the commit sha of the last commit we deployed to the DE org.
-
Uncommited Changes Sometimes changes like feature activation or Salesforce releases can cause a change in the retrieved package metadata and we always want to know that what’s in the org is in the branch whenever possible.
- Whenever we deploy to a DE org, we immediately retrieve and commit any metadata changes that come down in the retrieve. The metadata comes down as a zip file. We take an md5sum of the concatenated CRC checksums for each file in the zip. If the md5sum of the current retrieve does not match the md5sum of the last retrieve, we know the org has uncommitted changes which need to be saved to GitHub.
When detecting Sync State, it is possible that any combination of these states may exist in an org. For example, if the Contributor made changes in the package metadata in their DE org while at the same time a new Pull Request was merged to the default branch in the main repository and a new commit was pushed into the Contributor’s feature branch, all states could be True at the same time. Scenario: Uncommitted Changes
If the last deployed commit on the Contribution matches the HEAD commit on the feature branch, the normal Save process of Manage Contribution can be used to save the changes so there is no need for the Out of Sync Process
If both the Uncommitted Changes and Undeployed Commit states are True, we need to carefully handle the commit and merge of the metadata to avoid deleting anything.
- Create a new branch in the Contributor’s fork using feature branch name + “-devorg” and based on the last deployed commit on the Contribution. For example, the branch feature/123-some-feature would create a branch named feature/123-some-feature-devorg
- Retrieve the packaged metadata from the DE org and commit to the new branch.
- Attempt to automatically merge the -devorg branch
In any situation where Behind Main is True, whether in combination with other sync states or not, the issue does not need immediate resolution. The Contributor is alerted in the UI to the state and can click Update at any time to merge the changes from the main repository’s default branch into the feature branch.