|
| 1 | +name: End to End Tests |
| 2 | + |
| 3 | +on: |
| 4 | + schedule: |
| 5 | + # run daily at 2:00 AM UTC |
| 6 | + - cron: '0 2 * * *' |
| 7 | + |
| 8 | + # allow manual triggering for testing purposes |
| 9 | + workflow_dispatch: |
| 10 | + |
| 11 | +permissions: |
| 12 | + contents: read |
| 13 | + |
| 14 | +jobs: |
| 15 | + test-symfony-cli-installation: |
| 16 | + name: Test Symfony CLI Installation |
| 17 | + runs-on: ubuntu-latest |
| 18 | + |
| 19 | + steps: |
| 20 | + - name: Setup PHP |
| 21 | + uses: shivammathur/setup-php@v2 |
| 22 | + with: |
| 23 | + coverage: none |
| 24 | + extensions: none, ctype, dom, iconv, intl, mbstring, pdo_sqlite, simplexml, tokenizer, xml, xmlwriter |
| 25 | + php-version: '8.2' |
| 26 | + tools: symfony-cli |
| 27 | + |
| 28 | + - name: Configure environment |
| 29 | + run: | |
| 30 | + git config --global init.defaultBranch main |
| 31 | + git config --global user.email "noreply@example.com" |
| 32 | + git config --global user.name "Symfony Demo" |
| 33 | +
|
| 34 | + - name: Create project using Symfony CLI |
| 35 | + run: symfony new --demo ${{ github.job }} |
| 36 | + |
| 37 | + - name: Test application |
| 38 | + working-directory: ${{ github.job }} |
| 39 | + run: | |
| 40 | + php bin/console about |
| 41 | + symfony server:start -d --no-tls |
| 42 | + curl --fail --max-time 5 --no-progress-meter --output home.html -v http://127.0.0.1:8000/ |
| 43 | + symfony server:stop |
| 44 | +
|
| 45 | + test-composer-create-project: |
| 46 | + name: Test Composer Create Project |
| 47 | + runs-on: ubuntu-latest |
| 48 | + |
| 49 | + steps: |
| 50 | + - name: Setup PHP |
| 51 | + uses: shivammathur/setup-php@v2 |
| 52 | + with: |
| 53 | + coverage: none |
| 54 | + extensions: none, ctype, dom, iconv, intl, mbstring, pdo_sqlite, simplexml, tokenizer, xml, xmlwriter |
| 55 | + php-version: latest |
| 56 | + tools: symfony-cli |
| 57 | + |
| 58 | + - name: Create project using Composer |
| 59 | + run: composer create-project symfony/symfony-demo ${{ github.job }} |
| 60 | + |
| 61 | + - name: Test application |
| 62 | + working-directory: ${{ github.job }} |
| 63 | + run: | |
| 64 | + php bin/console about |
| 65 | + symfony server:start -d --no-tls |
| 66 | + curl --fail --max-time 5 --no-progress-meter --output home.html -v http://127.0.0.1:8000/ |
| 67 | + symfony server:stop |
| 68 | +
|
| 69 | + test-git-clone-installation: |
| 70 | + name: Test Git Clone Installation |
| 71 | + runs-on: ubuntu-latest |
| 72 | + |
| 73 | + steps: |
| 74 | + - name: Setup PHP |
| 75 | + uses: shivammathur/setup-php@v2 |
| 76 | + with: |
| 77 | + coverage: none |
| 78 | + extensions: none, ctype, dom, iconv, intl, mbstring, pdo_sqlite, simplexml, tokenizer, xml, xmlwriter |
| 79 | + php-version: '8.3' |
| 80 | + tools: symfony-cli |
| 81 | + |
| 82 | + - name: Clone repository and install dependencies |
| 83 | + run: | |
| 84 | + git clone https://github.com/symfony/demo.git ${{ github.job }} |
| 85 | + cd ${{ github.job }} |
| 86 | + composer install |
| 87 | +
|
| 88 | + - name: Test application |
| 89 | + working-directory: ${{ github.job }} |
| 90 | + run: | |
| 91 | + php bin/console about |
| 92 | + symfony server:start -d --no-tls |
| 93 | + curl --fail --max-time 5 --no-progress-meter --output home.html -v http://127.0.0.1:8000/ |
| 94 | + symfony server:stop |
| 95 | +
|
| 96 | + notify-on-failure: |
| 97 | + if: ${{ always() && contains(needs.*.result, 'failure') }} |
| 98 | + name: Notify on Failure |
| 99 | + needs: [test-symfony-cli-installation, test-composer-create-project, test-git-clone-installation] |
| 100 | + runs-on: ubuntu-latest |
| 101 | + |
| 102 | + permissions: |
| 103 | + issues: write |
| 104 | + |
| 105 | + steps: |
| 106 | + - name: Create Issue on Failure |
| 107 | + uses: actions/github-script@v7 |
| 108 | + env: |
| 109 | + NEEDS_CONTEXT: ${{ toJSON(needs) }} |
| 110 | + with: |
| 111 | + script: | |
| 112 | + const needsContext = JSON.parse(process.env.NEEDS_CONTEXT); |
| 113 | +
|
| 114 | + // Map job ids to human-readable names used in the workflow UI |
| 115 | + const jobNames = { |
| 116 | + 'test-symfony-cli-installation': 'Test Symfony CLI Installation', |
| 117 | + 'test-composer-create-project': 'Test Composer Create Project', |
| 118 | + 'test-git-clone-installation': 'Test Git Clone Installation', |
| 119 | + }; |
| 120 | +
|
| 121 | + const failedJobs = Object.entries(needsContext) |
| 122 | + .filter(([, v]) => v.result === 'failure') |
| 123 | + .map(([id]) => `- **${jobNames[id] || id}**: failed`); |
| 124 | +
|
| 125 | + const runUrl = `${process.env.GITHUB_SERVER_URL}/${process.env.GITHUB_REPOSITORY}/actions/runs/${process.env.GITHUB_RUN_ID}`; |
| 126 | + const date = new Date().toISOString().split('T')[0]; |
| 127 | + const title = `E2E Test Failure: ${date}`; |
| 128 | +
|
| 129 | + const body = [ |
| 130 | + 'The daily end-to-end test workflow has failed.', |
| 131 | + '', |
| 132 | + 'This may indicate users are experiencing issues installing the Symfony Demo application.', |
| 133 | + '', |
| 134 | + `**Run**: ${runUrl}`, |
| 135 | + '', |
| 136 | + '### Failed Jobs', |
| 137 | + failedJobs.join('\n'), |
| 138 | + '', |
| 139 | + 'Please investigate and fix the installation issues as soon as possible.' |
| 140 | + ].join('\n'); |
| 141 | +
|
| 142 | + // Ensure label exists |
| 143 | + const owner = context.repo.owner; |
| 144 | + const repo = context.repo.repo; |
| 145 | + const labelName = 'bug'; |
| 146 | + try { |
| 147 | + await github.rest.issues.getLabel({ owner, repo, name: labelName }); |
| 148 | + } catch { |
| 149 | + await github.rest.issues.createLabel({ |
| 150 | + owner, repo, name: labelName, color: 'd73a4a', description: 'Something is broken' |
| 151 | + }); |
| 152 | + } |
| 153 | +
|
| 154 | + // Reuse an open issue for today if it already exists to avoid duplicates |
| 155 | + const { data: issues } = await github.rest.issues.listForRepo({ |
| 156 | + owner, repo, state: 'open', labels: labelName, per_page: 100 |
| 157 | + }); |
| 158 | + const existing = issues.find(i => i.title === title); |
| 159 | +
|
| 160 | + if (existing) { |
| 161 | + await github.rest.issues.createComment({ |
| 162 | + owner, repo, issue_number: existing.number, |
| 163 | + body: `Another failing run detected.\n\n${body}` |
| 164 | + }); |
| 165 | + } else { |
| 166 | + await github.rest.issues.create({ owner, repo, title, body, labels: [labelName] }); |
| 167 | + } |
0 commit comments