Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

build: Ephemeral environments for PRs via slash command #13189

Merged
merged 20 commits into from
Feb 24, 2021

Conversation

robdiciuccio
Copy link
Member

@robdiciuccio robdiciuccio commented Feb 17, 2021

SUMMARY

Github Actions that provide the ability to create an ephemeral environment running a PR's latest merge commit via a command executed via PR comment. The Docker build is run in a virtual environment created via AWS ECS, using the Fargate container runtime. This functionality is sponsored by @preset-io.

  • Adds an additional Docker build target (ci) which includes additional scripts to initialize and run the container instance
  • Builds the Docker ci target on pull_request events (utilizing the cache from previous docker build runs) and saves the build as a workflow artifact.
  • Adds a Push ephmereral env image (workflow_run) workflow to tag and push the Docker ci image to AWS ECR.
  • Adds an Ephemeral env workflow (issue_comment) workflow to evaluate PR comments for the /testenv up or /testenv down commands and deploy ECS services accordingly.
  • Adds new secrets to the repo: AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY. These credentials correspond to an AWS IAM user with appropriate ECS privileges. An Apache INFRA ticket is pending to add these secrets to the repo.

Github Actions_ Ephemeral Environments

Running

  • When a PR is opened or updated, a Docker ci build of the merge commit will be saved and uploaded to ECR.
  • Posting a comment on the PR containing /testenv up (and nothing else) will trigger the ephemeral environment creation or update. Note: this functionality is currently restricted to members of the apache Github organization.
  • When the environment is created, a comment will be posted to the PR with the relevant details:

Screen Shot 2021-02-17 at 12 34 15 PM

  • Note that the environment will take several minutes to become available, as all DB migrations and example data loading is performed upon startup.
  • If the environment fails to startup, for example, if the Docker image is not yet built and pushed to ECR, a comment will also be posted to the PR:

Screen Shot 2021-02-17 at 1 04 21 PM

Security

The enclosed workflows follow Github's security guidelines for builds. Docker images are built via the read-only pull_request event, preventing malicious code from accessing tokens with repo write access. workflow_run and issue_comment privileged workflows are limited to uploading and interacting with the AWS API, not building or running any of the untrusted code.

TEST PLAN

  • Follow the procedure in Running, above. Note that the workflow_run and issue_comment workflows will not run until they are merged to master.
  • These workflows have been tested pretty extensively on my fork of Superset.

TODO (in future PRs)

  • Add handler for /testenv down command to manually shutdown environments
  • Automate shutting down server resources after ~48h
  • Shutdown and cleanup on PR close
  • Add support for celery and async jobs
  • Add support for feature flag and configuration overrides

ADDITIONAL INFORMATION

  • Has associated issue:
  • Changes UI
  • Requires DB Migration.
  • Confirm DB Migration upgrade and downgrade tested.
  • Introduces new feature or API
  • Removes existing feature or API

@ktmud
Copy link
Member

ktmud commented Feb 17, 2021

Super excited for this! Thanks for setting this up and the sponsorship!

@junlincc
Copy link
Member

Thanks for setting this up; it's going to improve the manual testing process vastly. 🙂

Copy link
Member

@ktmud ktmud left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since issue_comment event also has access to all the base repo secrets, would it make sense to bypass the workflow_run step and upload artifacts to ECR in the issue_comment workflow, too?

The built docker image is kind of large, too. I'm wondering whether it's possible to use the latest released apache/superset:master as the base image and build a new image just for ECR? (I'd imagine the saved docker build will only contain the new layers with pip package, python file, and static assets overrides.)

echo ${{ github.sha }} > ./build/SHA
echo ${{ github.event.pull_request.number }} > ./build/PR-NUM
docker build --target ci -t ${{ github.sha }} -t "pr-${{ github.event.pull_request.number }}" .
docker save ${{ github.sha }} | gzip > ./build/${{ github.sha }}.tar.gz
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will it make sense to save the already built image from previously step and rely on file names to get both SHA and PR number?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the --target ci build here is already using the cached layers from the previous builds, there's not much of a gain in using those images directly. We could embed both the PR num and SHA in the filename, but this felt a bit cleaner, and wouldn't save any measurable time in the workflow_run step.

with:
github-token: ${{secrets.GITHUB_TOKEN}}
script: |
const errMsg = 'Ephemeral environment creation is currently limited to committers.'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe add a @comment_author here 😉

@robdiciuccio
Copy link
Member Author

Since issue_comment event also has access to all the base repo secrets, would it make sense to bypass the workflow_run step and upload artifacts to ECR in the issue_comment workflow, too?

Ideally, yes, but there's no way (that I've found) for an issue_comment event to reference workflow runs for a PR, making it impossible to retrieve the uploaded build artifacts.

The built docker image is kind of large, too. I'm wondering whether it's possible to use the latest released apache/superset:master as the base image and build a new image just for ECR? (I'd imagine the saved docker build will only contain the new layers with pip package, python file, and static assets overrides.)

Not sure how this would work in a PR context, as the standard docker builds are not pushed to Dockerhub for PRs from forked repos (no secrets access). The current CI (ephemeral env) build is leveraging the cache from the current Docker build process, but agreed that the image size is large. I'm working on getting the overall image size down, but on first pass there's not a whole lot of wasted space here.

@ktmud
Copy link
Member

ktmud commented Feb 18, 2021

Ideally, yes, but there's no way (that I've found) for an issue_comment event to reference workflow runs for a PR, making it impossible to retrieve the uploaded build artifacts.

You can potentially get the branch name of the PR first, then find the workflow runs by branch name. I've done that in the cancel_github_workflow script:

if pr:
runs = get_runs(
repo,
statuses=statuses,
events=event,
branch=pr["head"]["ref"],
user=pr["user"]["login"],
)

Not sure how this would work in a PR context, as the standard docker builds are not pushed to Dockerhub for PRs from forked repos (no secrets access). The current CI (ephemeral env) build is leveraging the cache from the current Docker build process, but agreed that the image size is large. I'm working on getting the overall image size down, but on first pass there's not a whole lot of wasted space here.

I'm not familiar with Docker, but I was imaging if you have a Dockerfile like this:

FROM apache/superset:master

# copy latest file contents
...

# re-install dependencies
...

# rebuild assets
...

The saved docker image will contain only the additional layers on top of apache/superset, so the image you uploaded to Amazon would be smaller than building Superset from scratch.

@robdiciuccio
Copy link
Member Author

The saved docker image will contain only the additional layers on top of apache/superset, so the image you uploaded to Amazon would be smaller than building Superset from scratch.

Reinstalling dependencies and rebuilding assets would add significant time to the build of the CI image. Running webpack is the most expensive operation in the build.

@robdiciuccio
Copy link
Member Author

Apache INFRA ticket: https://issues.apache.org/jira/browse/INFRA-21442

@rusackas rusackas requested a review from suddjian February 23, 2021 00:59
Copy link
Member

@craig-rueda craig-rueda left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@robdiciuccio
Copy link
Member Author

Secrets have been added by Apache infra.

@robdiciuccio robdiciuccio merged commit 27f7d11 into apache:master Feb 24, 2021
@robdiciuccio robdiciuccio deleted the rd/ephemeral-env branch February 24, 2021 18:50
@junlincc
Copy link
Member

@robdiciuccio thanks again for improving the process. Do you mind adding a non-technical user friendly tutorial, so our designers and PMs can all benefit from it? 🙏

@robdiciuccio
Copy link
Member Author

@junlincc yes, I'll be adding some documentation once the feature has gone through some testing on the repo (merging this PR is required for testing due to the security model of GitHub Action).

allanco91 pushed a commit to allanco91/superset that referenced this pull request May 21, 2021
* First pass at ephemeral env, new Docker ci target

* Add service checks, get public IP

* Separate issue_comment and workflow_run jobs

* Refactor workflows

* Adjust comment author association

* Checkout code

* Fix image name, manage service desired task count

* Use merge commit sha

* Fix IP output, add failure comment

* Refactor comment parsing & env spinup

* Check container image publish status

* Parse AWS account ID from registry URL

* Use PR number rather than variable merge commit SHA for image tag

* Fix docker push conditional

* Push multiple tags to ECR

* Fix comment author check

* Refactor comment body check

* Provision service with active task to get correct IP

* /testenv up

* Add @mentions to PR comments, env var cleanup
@mistercrunch mistercrunch added 🏷️ bot A label used by `supersetbot` to keep track of which PR where auto-tagged with release labels 🚢 1.2.0 labels Mar 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🏷️ bot A label used by `supersetbot` to keep track of which PR where auto-tagged with release labels preset-io size/L 🚢 1.2.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants