pantheon-systems / example-drops-8-composer

Install drops-8 with Composer on Pantheon.
MIT License
90 stars 124 forks source link

Abstraction of environmental variables #89

Closed stevector closed 5 years ago

stevector commented 7 years ago

This issue is a child of https://github.com/pantheon-systems/example-drops-8-composer/issues/61

I anticipate that one of the biggest difficulties in supporting this project across different CI services (Circle, Travis, Jenkins, GitLab CI) as well as making alternate versions of the repo (WordPress, Drupal Commerce, Drupal 7, etc) will be keeping global variable conventions consistent. We spend more lines in circle.yml on environmental variables than we do on any other section.

I just came across a mechanism for setting environmental variables in CircleCI that might help with this problem. This example repo from CircleCI concatenates on to ~/.circlerc in order to add environmental variables.

That example repo is using that mechanism as an alternative to the CircleCI UI for setting private variables. I am suggesting we consider using it for the management of non-private variables (and maybe private ones too). We could have a file in this repo containing something like

export BRANCH=$(echo $CIRCLE_BRANCH | grep -v '^\(master\|[0-9]\+.x\)$')
export PR_ENV=${BRANCH:+pr-$BRANCH}
export CIRCLE_ENV=ci-$CIRCLE_BUILD_NUM
export DEFAULT_ENV=$(echo ${PR_ENV:-$CIRCLE_ENV} | tr '[:upper:]' '[:lower:]' | sed 's/[^0-9a-z-]//g' | cut -c -11 | sed 's/-$//')
export TERMINUS_ENV=${TERMINUS_ENV:-$DEFAULT_ENV}
export NOTIFY='scripts/github/add-commit-comment {project} {sha} "Created multidev environment [{site}#{env}]({dashboard-url})." {site-url}'

I might just try a PR to validate that this would even work.

greg-1-anderson commented 7 years ago

Hm, maybe.

First, a couple of alterations.

TERMINUS_ENV needs to be customizable. It should appear as written when testing on multidev branches, and should be changed to TERMINUS_ENV=dev to always test on the dev environment. Actually, it should work as written. If the user sets TERMINUS_ENV in circle.yml, that will override the values calculated in ~/.circlerc.

I've been meaning to move NOTIFY to composer.json. Requires modification to the build tools plugin.

The next question is, how would you use this technique to increase abstraction?

I presume this technique only works because Circle CI sources ~/.circlerc before each script command that is run. Does Travis have a similar feature? Techniques that do not work across all of the systems we hope to support would increase variation, which might be more costly than the reduced abstraction gains us.

Perhaps ~/.circlerc could be modified to source a file in vendor/pantheon-systems/ci-scripts (or something -- I mean a new project, not my deprecated scripts project. Maybe give it a new name). That project could contain a circlerc file, a travisrc file, etc. Not sure if there should be one big project that had everything needed for every supported CI system, or lots of little projects, one for every CI system (or for all of the permutations of CI vs. repository host?) If we put everything in one file, then maybe they could go in pantheon-systems/terminus-build-tools-plugin? It is more efficient to install fewer projects. Not sure if that is the proper grouping of functionality or not.

If we did have an external repository to store things like this, we could also put our remaining scripts such as add-commit-comment et. al. (I started a PR, https://github.com/github/hub/pull/1465, that would allow us to just use hub instead of this script.)

I want to be a little wary about abstraction, though. The first time I tried this I created a ci-scripts project, which was included from circle-scripts project and a travis-scripts project. It became confusing and hard to modify. If we go this direction again, we should clearly define what our "API" is, and use semver major version bumps when altering any contract.

It could work out this time.

stevector commented 7 years ago

If we go this direction again, we should clearly define what our "API" is, and use semver major version bumps when altering any contract.

Agreed. I'm adding a "postponed" label here. We can't optimize our Travis support until we have Travis support. FWIW, I don't know if Travis supports the same mechanism.

stevector commented 5 years ago

This issue is basically addressed by a script in the container used by Circle 2: https://github.com/pantheon-systems/example-drops-8-composer/blob/master/.circleci/config.yml#L56