<pre style='margin:0'>
Rainer Müller (raimue) pushed a commit to branch master
in repository macports-base.
</pre>
<p><a href="https://github.com/macports/macports-base/commit/220723fc4e00d9252e45f8add5e2924d643f6f1c">https://github.com/macports/macports-base/commit/220723fc4e00d9252e45f8add5e2924d643f6f1c</a></p>
<pre style="white-space: pre; background: #F8F8F8"><span style='display:block; white-space:pre;color:#808000;'>commit 220723fc4e00d9252e45f8add5e2924d643f6f1c
</span>Author: Rainer Müller <raimue@macports.org>
AuthorDate: Thu Nov 10 21:58:01 2016 +0100
<span style='display:block; white-space:pre;color:#404040;'> ReleaseProcess: adapt to Git
</span>---
portmgr/ReleaseProcess | 153 ++++++++++++++++++++++---------------------------
1 file changed, 70 insertions(+), 83 deletions(-)
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/portmgr/ReleaseProcess b/portmgr/ReleaseProcess
</span><span style='display:block; white-space:pre;color:#808080;'>index 2658691..eaf3053 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/portmgr/ReleaseProcess
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/portmgr/ReleaseProcess
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -1,8 +1,6 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span> = MacPorts Release Process =
This file documents the evolving MacPorts release process.
<span style='display:block; white-space:pre;background:#ffe0e0;'>-$Id$
</span>
== Goals of a Release ==
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -20,10 +18,10 @@ There are several goals in the release process:
</span>
The following steps to a release are documented in more detail below:
<span style='display:block; white-space:pre;background:#ffe0e0;'>- * Create an svn branch to carry the release.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Create a release branch to carry the release.
</span> * Prepare the code for release.
* Tag the release.
<span style='display:block; white-space:pre;background:#ffe0e0;'>- * Create release products: tarballs and dmgs.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Create release products: tarballs and installers.
</span> * Post release products.
* Make release version available through selfupdate.
* Notify public of the release.
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -31,41 +29,41 @@ The following steps to a release are documented in more detail below:
</span>
=== Create a Release Branch ===
<span style='display:block; white-space:pre;background:#ffe0e0;'>-For each major release (i.e. 1.9.x, 2.0.x, etc.) an appropriate branch is created with a
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-consistent name. To do this, two things are required:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+For each major release (i.e. 1.9.x, 2.0.x, etc.) an appropriate branch is created with
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+a consistent name. To do this, two things are required:
</span>
<span style='display:block; white-space:pre;background:#ffe0e0;'>- * Choose the svn revision from which to create the branch, most likely based off trunk.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- * Create the branch (e.g. release_2_0) through the svn "copy" command for history preservation,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- first creating the needed branch directory to preserve the required directory structure
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- (the 'base' directory level *needs* to exist in each release branch, otherwise selfupdate breaks):
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Choose the git revision from which to create the branch, most likely based off master.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Create the branch (e.g. release-2.0) with git. The following commands assume
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ the remote "origin" points to macports/macports-base on GitHub.
</span>
<span style='display:block; white-space:pre;background:#ffe0e0;'>- svn mkdir -m "commit-message" https://svn.macports.org/repository/macports/branches/release_2_0
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- svn cp [-r<rev>] -m "commit-message" https://svn.macports.org/repository/macports/trunk/base \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- https://svn.macports.org/repository/macports/branches/release_2_0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ git branch release-2.0 origin/master
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ git push origin release-2.0
</span>
The actual release, alpha or beta releases, release candidates, and any point releases will all
<span style='display:block; white-space:pre;background:#ffe0e0;'>-live on this branch, and tagged appropriately and if necessary (a must for the actual releases,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-optional for beta snapshots) into the /tags svn directory.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+live on this branch. Releases of any kind will need to be tagged appropriately and point to
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+commits on this branch.
</span>
<span style='display:block; white-space:pre;background:#ffe0e0;'>-Only the base subdirectory, not the ports subdirectory, is branched for a given release.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+Only this base repository, not the ports tree kept in another repository, will be branched for
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+a given release.
</span>
<span style='display:block; white-space:pre;background:#ffe0e0;'>-It is strongly recommended to use the latest version of the subversion port so that merge
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-tracking information can be maintained between release branches and trunk/base if you intend
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-to merge revisions back and forth between them, which is a very likely scenario.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+Once master is to be used for development of the next major version, increase its version information to
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+indicate it's moved past the release version by setting the patch-level version to 99, e.g. 2.0.99 in
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+config/macports_version.
</span>
=== Prepare the code for Release ===
In preparation for a release, several things should be completed within the code:
<span style='display:block; white-space:pre;background:#ffe0e0;'>- * Update the file base/ChangeLog in both trunk and the release branch to reflect the appropriate changes.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- * Update the file base/config/macports_version with the target release number. The content of this file
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Update the file ChangeLog in both trunk and the release branch to reflect the appropriate changes.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Update the file config/macports_version with the target release number. The content of this file
</span> is recorded as the MacPorts version at MacPorts build time, as displayed by the port command, and it's
also used by the selfupdate procedure to determine whether a newer version of code is available.
It should be different between trunk and the release branch, the former greater to differentiate it from
the latter.
<span style='display:block; white-space:pre;background:#ffe0e0;'>- * Preserve the file base/config/mp_version at the 1.800 fixed value if selfupdate backwards compatibility
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- with pre 1.8.0 MacPorts installations is still desired (cf. svn's r43571).
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Preserve config/mp_version and config/dp_version at the 1.800 or 1.710 fixed values, respectively,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if selfupdate backwards compatibility with old MacPorts installations is still desired.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ (see https://trac.macports.org/changeset/43571/trunk/base or ce8a77c)
</span> * Update the autoconf 'configure' script through the provided base/autogen.sh script once the version number
in mp_version has been changed, since the former reads the latter.
* Make sure that these and any other changes or bug fixes are made on and/or merged between the release branch
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -81,68 +79,60 @@ approved as the actual release, an additional tag is created that names the same
</span>
Tagging conventions:
<span style='display:block; white-space:pre;background:#ffe0e0;'>- * release_2_0_0-beta2 (beta 2 for release 2.0.0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- * release_2_0_0-rc1 (release candidate 1 for release 2.0.0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- * release_2_0_0 (tagged release 2.0.0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- * release_2_0_0-archive (tagged release 2.0.0 -- complete archive)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- * release_2_0_1 (2.0.1 release)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-We first tag the branched base directory to make up the final release:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- svn cp -m "commit-message" https://svn.macports.org/repository/macports/branches/release_2_0 \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- https://svn.macports.org/repository/macports/tags/release_2_0_0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * v2.0.0-beta2 (beta 2 for release 2.0.0)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * v2.0.0-rc1 (release candidate 1 for release 2.0.0)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * v2.0.0 (tagged release 2.0.0)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * v2.0.1 (2.0.1 release)
</span>
<span style='display:block; white-space:pre;background:#ffe0e0;'>-Although only the base subdirectory is branched and tagged for a given major release, we also create a
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-separate tag for the entire tree (base sources and full ports tree) at the time the final release tag is
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-created (only for major releases, x.y.0), in order to provide a stake in the ground that specifies a set
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-of ports intended to work with that release. Note that this tag incorporates the entire svn trunk directory
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-at the revision number at which the final release was tagged.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+We first create an annotated tag pointing to the release branch to make up the final release. Annotated
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+tags preserve who made the tag and when. Additionally the tag should be signed with GPG by using the `-s`
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+flag in order to allow later verification of the signature.
</span>
<span style='display:block; white-space:pre;background:#ffe0e0;'>-The necessary working copy to create such a tag is created by checking out all of trunk at the specific
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-revision of the final tagging of base and then switching the base directory to the appropriate release
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-tag URL. For instance:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ git tag -a -s v2.0.0 release-2.0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ git push origin v2.0.0
</span>
<span style='display:block; white-space:pre;background:#ffe0e0;'>- svn co [-r<rev>] https://svn.macports.org/repository/macports/trunk release_2.0.0-archive
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- cd release_2.0.0-archive
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- svn rm base
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- svn cp https://svn.macports.org/repository/macports/tags/release_2_0_0/base base
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+Although only base repository is branched and tagged for a given major release, we also create a separate
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+tag in the ports tree at the time the final release tag is created for a major release (x.y.0). This
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+intends to provide a set of ports intended to work with that release.
</span>
<span style='display:block; white-space:pre;background:#ffe0e0;'>-And finally we tag the entire directory as release_2_0_0-archive:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- cd ..
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- svn cp -m "commit-message" release_2.0.0-archive https://svn.macports.org/repository/macports/tags/release_2_0_0-archive
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ git clone macports/macports-ports macports-ports
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ cd macports-ports
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ git tag -a -s v2.0.0-archive origin/master
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ git push origin v2.0.0-archive
</span>
=== Create & Post Release Tarballs ===
<span style='display:block; white-space:pre;background:#ffe0e0;'>-The release tarballs are tar.bz2 and tar.gz archives of the base directory only and of the entire svn tree
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-for a particular release. They are named with the following naming convention:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+The release tarballs are .tar.bz2 and .tar.gz archives of the base repository. They are named with the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+following naming convention:
</span>
<span style='display:block; white-space:pre;background:#ffe0e0;'>- MacPorts-2.0.0.tar.{bz2,gz} (base directory only, corresponding to tag release_2_0_0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- MacPorts-2.0.0-archive.tar.{bz2,gz} (complete archives corresponding to tag release_2_0_0-archive)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ MacPorts-2.0.0.tar.{bz2,gz} (base repository, corresponding to tag v2.0.0)
</span>
The following commands issued to the top level Makefile will generate all the tarballs and checksums:
<span style='display:block; white-space:pre;background:#ffe0e0;'>- make ARC=yes DISTVER=2.0.0 distfromsvn
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ make DISTVER=2.0.0 distfromgit
</span>
<span style='display:block; white-space:pre;background:#ffe0e0;'>-Note that if you omit the "ARC=yes" flag at the start of the make call then the full archive tarballs will not be produced.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+The release should be signed with a detached GPG signature in order to allow cryptographic verification:
</span>
<span style='display:block; white-space:pre;background:#ffe0e0;'>-All these tarballs are uploaded to the http://distfiles.macports.org/MacPorts/ directory. At present, this must
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-be done with the help of the MacOSForge sysadmin.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ for ext in bz2 gz; do
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ gpg --sign --detach-sig --armor MacPorts-2.0.0.tar.${ext}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ done
</span>
<span style='display:block; white-space:pre;background:#ffe0e0;'>-Additionally, a file is created, and posted to the same location, that contains md5, sha1, rmd160, and sha256 checksums
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+Additionally, a file with checksums is created, that contains md5, sha1, rmd160, and sha256 checksums
</span> for each of the files:
<span style='display:block; white-space:pre;background:#ffe0e0;'>- MacPorts-2.0.0.chk.txt
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- (We should have a way to sign these checksums, and have the signer's keys posted somewhere.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- Security experts in the project, would you be interested in leading this effort? Eric? Mark? Anyone else?)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ for type in -md5 -rmd160 -sha1 -sha256; do
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ openssl dgst ${type} MacPorts-2.0.0.tar.{gz,bz2} >> MacPorts-2.0.0.chk.txt
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ done
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+These tarballs and the checksums are uploaded to the https://distfiles.macports.org/MacPorts/ directory.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+At present, this must be done with the help of the infrastructure team.
</span>
=== Create Release Packages and Disk Image(s) ===
<span style='display:block; white-space:pre;background:#ffe0e0;'>-The dmg is a Mac OS X disk image that contains a standalone installer, configured in the usual way, for major
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-MacPorts releases (x.y.0), named in a consistent fashion and incorporating the OS version for which it
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-was built.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+The dmg is a Mac OS X disk image that contains a standalone installer, configured in the usual way, named
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+in a consistent fashion and incorporating the OS version for which it was built.
</span>
For 10.6 and newer, we now build flat packages, so an enclosing dmg is not necessary.
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -168,7 +158,9 @@ Installer certificate, not the Application one):
</span> After signing, generate checksums, which will need to be added to the existing checksums
file in the downloads directory:
<span style='display:block; white-space:pre;background:#ffe0e0;'>- for pkg in MacPorts-2.0.0-*.{pkg,dmg}; do for type in -md5 -sha1 -ripemd160 -sha256; do openssl dgst $type $pkg; done >> MacPorts-2.0.0.chk.txt; done
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ for type in -md5 -sha1 -ripemd160 -sha256; do
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ openssl dgst $type MacPorts-2.0.0-*.{pkg,dmg} >> MacPorts-2.0.0.chk.txt
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ done
</span>
These new products, along with the new checksums, also have to be posted to the appropriate
directory of the MacPorts distfiles server. Developers are required to validate the generated installer as
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -198,7 +190,7 @@ create the destroot of the port and examine it for:
</span> #\
exec /usr/bin/tclsh "$0" "$@"
thus ensuring that the default Mac OS X bundled Tcl is used in our scripts.
<span style='display:block; white-space:pre;background:#ffe0e0;'>- * macports1.0 Tcl package: The macports1.0 Tcl package should be sourced off its location in /opt/local/share/macports/Tcl/macports1.0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * macports1.0 Tcl package: The macports1.0 Tcl package should be sourced off its location in /opt/local/libexec/macports/lib/macports1.0
</span> in every single one of our scripts in ${destroot}/opt/local/bin.
* Miscellaneous: anything else that might seem out of the ordinary for a fully default-configured MacPorts
installation.
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -210,17 +202,9 @@ when it's double-clicked.
</span>
=== Make the Release Available through Self-Update ===
<span style='display:block; white-space:pre;background:#ffe0e0;'>-In order to make the release version available through selfupdate, the base/config/RELEASE_URL file in svn
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-trunk needs to be updated with the tag of the release to distribute. This file is read by the cron job that
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-makes the code available via rsync. See base/portmgr/mprsyncup. Though not strictly necessary, it's also good
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-practice to update the same file accordingly in its branched guise.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-=== Update trunk's version for next release ===
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-Once trunk is to be used for development of the next major version, increase its version information to
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-indicate it's moved past the release version by setting the patch-level version to 99, e.g. 2.0.99 (in
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-trunk/base/config/macports_version).
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+In order to make the release version available through selfupdate, the config/RELEASE_URL file in the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+base repository needs to be updated with the tag of the release to distribute. This file is read by the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+cron job that makes the code available via rsync. See jobs/mprsyncup in the macports-infra repository.
</span>
=== Notify the Public of the Release ===
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -229,12 +213,15 @@ Once the release has been posted, notification of the release should be sent/pos
</span>
* The macports-announce@, macports-users@ and macports-dev@ mailing lists.
* The MacPorts website, by adapting the $macports_version_major and $macports_version_latest variables as
<span style='display:block; white-space:pre;background:#ffe0e0;'>- appropriate in the trunk/www/includes/common.inc file.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- * The &macports-version; entity in trunk/doc-new/guide/xml/installing.xml.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- * [https://trac.macports.org/news/] The MacOSforge news section (submitter: portmgr@)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- * [http://www.versiontracker.com/dyn/moreinfo/macosx/26679 VersionTracker] (submitter: mij@)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- * [http://sourceforge.net/projects/macports/ sourceforge] (submitted: rhwood@)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- * [http://www.macupdate.com/info.php/id/21309/macports MacUpdate] (submitter: ???)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ appropriate in the includes/common.inc file in the macports-www repository.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * [https://macports.github.io/news/] The website's news section, see macports.github.io repository
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ (submitter: portmgr@)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * The &macports-version; entity in xml/installing.xml in the guide repository.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+External websites:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * [http://sourceforge.net/projects/macports/ sourceforge] (submitted: portmgr@)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * [https://www.macupdate.com/app/mac/21309/macports MacUpdate] (submitter: ???)
</span> * [http://twitter.com/macports twitter] (submitter: raimue@)
* [https://plus.google.com/communities/110287630398071712872 Google+ Community] (submitter: raimue@)
* (Where else?)
</pre><pre style='margin:0'>
</pre>