GitHub’s pull_request_target event presents a significant security challenge due to its access to the pull request within the target repository’s context. This can expose sensitive secrets to untrusted users submitting pull requests.

For projects like Pipelines-as-Code (PAC), where interaction with multiple upstream providers (Bitbucket, GitLab, GitHub) is essential, this risk is amplified. Access to repository secrets is vital for E2E testing across these platforms, yet arbitrary pull requests triggering secret-laden workflows is unacceptable.

Restricting pull requests to originate solely from repository branches would mitigate this risk, but it would also severely limit external contributions—a trade-off we aimed to avoid.

Exploring Alternatives: GitHub Environments and Workflow Dispatch

Initially, GitHub Environments were considered. Configuring workflows to run only within specific environments allows for leveraging GitHub’s built-in approval mechanism. This offers a user-friendly approval button in the UI. However, it necessitates manual approval for every workflow execution, including automated nightly runs, which becomes cumbersome.

Next, the workflow_dispatch event was explored. This involved a PAC PipelineRun that triggers the workflow dispatch API and monitors its completion. The appeal lies in utilizing PAC’s robust permission control features. Approved users can trigger E2E tests by commenting /ok-to-test on pull requests, while non-approved users have the workflow automatically initiated.

However, several challenges arose. While the GitHub Actions workflow was triggered with the correct SHA and input arguments, it failed to accurately target the specified SHA during execution. This resulted in inaccurate status updates in the UI. Additionally, reliably retrieving the run ID of a newly created workflow dispatch proved difficult.

Ultimately, this approach proved overly complex and challenging to debug, prompting a search for a simpler, more transparent solution.

The Solution: Automating with GitHub Labels and PAC

The solution involved leveraging GitHub labels, specifically the e2e label, to trigger our E2E testing workflow. This approach offers several advantages:

  • Explicit Triggering: Workflows are triggered only when the e2e label is added.
  • Transparency: The label’s presence is clearly visible in the pull request UI.
  • Simplicity: This method avoids the complexities of API-based triggering and run ID management.

To automate the label application, we utilize a Pipelines-as-Code (PAC) PipelineRun. This PipelineRun is triggered on pull requests targeting the main branch and involving changes to specific files (e.g., Go files, workflow configurations).

apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
  name: e2e-label.yaml
  annotations:
    pipelinesascode.tekton.dev/on-event: "pull_request"
    pipelinesascode.tekton.dev/on-target-branch: "main"
    pipelinesascode.tekton.dev/on-path-change: "[***/*.go, .github/workflows/*l]"
spec:
  pipelineSpec:
    tasks:
      - name: label-pr
        taskSpec:
          steps:
            - name: label-pr
              image: registry.access.redhat.com/ubi9/ubi
              env:
                - name: HUB_TOKEN
                  valueFrom:
                    secretKeyRef:
                      name: "nightly-ci-github-hub-token"
                      key: "hub-token"
              script: |
                #!/usr/bin/env python3
                # ... Python script to add the 'e2e' label ...

This PipelineRun runs within the context of PAC’s Access Control List (ACL) authorization, which is highly flexible. This allows us to define specific rules for when the e2e label should be applied. For example, we can restrict label application to pull requests originating from trusted users or those meeting specific criteria.

By configuring the GitHub workflow to trigger both when the label is added and when it already exists, we ensure that the workflow is executed for all relevant pull requests. This automation, driven by PAC’s flexible ACL, significantly streamlines the E2E testing process.

Another benefit of this approach is that if the automatic labeling fails to apply—such as when the Pull Request doesn’t involve any Go files but still requires testing—a GitHub repository admin can manually add the e2e label. This manual addition will trigger the workflow. Previously, the workflow would not have been triggered at all unless it specifically targeted changes in Go files.

name: E2E Tests

on:
  pull_request_target:
    types:
      - labeled
      - opened
      - reopened
      - synchronize

jobs:
  e2e-tests:
    if: >
      github.event_name == 'pull_request_target' && (github.event.label.name == 'e2e' || contains(github.event.pull_request.labels.*.name, 'e2e'))
    # ... rest of the workflow configuration

Conclusion

The pull_request_target event in GitHub Actions presents inherent security risks. By exploring alternative solutions and ultimately adopting a label-based triggering mechanism, coupled with PAC’s automated labeling and flexible authorization, a more secure, transparent, and manageable E2E testing workflow is established. This approach allows for maintaining a balance between security and the ability to accept contributions from external developers, while automating the triggering process.

pipelines and cat