A gulp-based tool that allows you to host your custom modules on github, create releases for them and update modules using drush.
For the tool to work you need the following files:
package.json- describes the packages that should be included for the tool to function as intended;gulpfile.js- a gulp file that contains all the logic.
The below commands presume that
- you're already opened console/terminal and moved to the tool's directory;
- you have npm installed;
- you ran
npm installto install the dependencies.
gulp [options]
There are two ways to pass the options:
- Using configuration file:
{
"user": "skullhole",
"repo": "d7psu",
"atok": "",
"info": "1",
"path": '.',
"file": "release.xml"
}
- Passing the command line parameters directly.
repo- repository machine name, e.g.d7psufor the current repository;user- github username that owns the repository, e.g.skullholefor the current repository;atok- github access token that is allowed to use github API to view releases and file contents. You can create one on Personal access tokens page of your github account. If your module's repo is public you may keep it empty, otherwise you want to add Full control of private repositories permission.info- defines if MODULENAME.info should be created/updated with the project status url configuration (MODULENAME is therepo). Default is 1 (enabled). That option makes sense when you want to use github-hosted xml file (see Technical Details).path- directory name to check for configuration file and place the resulting project status xml file and MODULENAME.info. Default is current directory.conf- relative path to the configuration file (relatively topathvalue). Default isrepo.json.file- relative path to the resulting project status xml file (relatively topathvalue). Default isrelease.xml.
Good when you host d7psu files into your project's directory.
Contents of repo.json:
{
"user": "skullhole",
"repo": "d7psu",
"atok": "",
"info": "1",
"path": '.',
"file": "release.xml"
}
With the above file you need only to run gulp in the directory that contains the above file. The result will be:
- project status xml file
release.xmlfile that can be used by Drupal to update the module; d7psu.infowill be created/updated with project status url line that points to github-hosted file.
That option is good when you for some reason don't want to have the access token exposed but don't want to type it every time in console.
If you have configration file stored somewhere outside of the tool's directory use:
gulp --conf=/path/to/config-file/config.json
For username is USER with the repository REPO and access token ATOK you want to use the below command:
gulp --user=USER --repo=REPO --atok=ATOK
The result will be:
- project status xml file
release.xmlfile in the tool's directory; REPO.infowill be created/updated with project status url line that points to github-hosted file.
The advanced example is good when you want to set up own storage for project status url XMLs.
Say, you have the tool installed in directory /path/to/tool and you want to use directory /path/to/project-status-url for the resulting files:
gulp --user=USER --repo=REPO --atok=ATOK --info=0 --path=/path/to/tool --file=../project-status-url/REPO.xml
The above command:
- Will NOT do anything to the MODULENAME.info file (because
infois set to0); - Add REPO.xml file to the destination:
/path/to/project-status-url/REPO.xml
In case you don't want to keep the project status url XMLs in your repositories you may want to store them on some domain.
When Drupal requests the project status url XML it uses that line from the info file of your module (see Updating With Drush) and appends the core version and the name of the project (repo), e.g. if project status url is set to http://example.com/update-server the requested URL will be http://example.com/update-server/7.x/REPO
Taking that into account you have two options:
- Use the tool and create the files on server with options
--path=/path/to/example-com-root/update-server/7.xand--file=REPO - Disable MODULENAME.info updates and specify the path to the project status url XML file manually in MODULENAME.info with an empty fragment suffix. E.g. line in the info file
project status url = http://example.com/update-server/REPO.xml#. Then Drupal will be requesting the pathhttp://example.com/update-server/REPO.xml#/7.x/REPOwhich will resolve correctly to the path you wanted.
The tool uses Github API to add the path to github-hosted file to the MODULENAME.info. That operation requires that you already have the file with the given name in your repository. With that in mind the complete process of adding the tool to your repo is as follows:
- Add tool's files (see Installation) and empty
release.xmlfile to your repo and push to github. That step should be done once. - Run the tool to populate the
release.xmland MODULENAME.info files. Add and push them to github. - For every further releases you want to publish the release on github first, then run the tool to generate xml file (with
--info=0since project status url won't change anyways), then add and push the release.xml file. NOTE:release.xmlin your release will not be up to date in your public version of the module, that's the limitation of the process.
You want to update your modules to the most recent version using the command:
drush dl -y MODULENAME --no-md5=1 --source=0
-
Github API does not return md5 and file size for releases. We might download the files using the tool and calculate those, but that's an overhead, since there's
--no-md5=1option that asks Drush to disregard file checks. -
Drush (at least version 7 that was used when developing the tool) has the caveat when regular run
drush dl -y MODULENAMEdoes not take project status url in your MODULENAME.info into account falling back to default Drupal's. To prevent that from happening you need to use--source=0option.
Here's why that happens in Drush's code:
In drush_pm_download():
$status_url = drush_get_option('source', ReleaseInfo::DEFAULT_URL); // Makes it non-empty
And then in pm_parse_request():
if ($status_url) { // It is not empty already.
$request['status url'] = $status_url;
}
elseif (!empty($projects[$project]['status url'])) {
$request['status url'] = $projects[$project]['status url'];
}