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

feat: precommit pipeline for QA [WPB-11042] #18339

Merged
merged 24 commits into from
Dec 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
3b26a7c
feat: testing some pipelines
tlebon Nov 18, 2024
f981404
chore: small changes
tlebon Nov 18, 2024
5f74925
chore: modify pipeline to check for total additions instead of per co…
tlebon Nov 18, 2024
f42a479
chore: updating pipeline again
tlebon Nov 19, 2024
3872e1a
chore: add deployment status
tlebon Nov 19, 2024
b04b925
chore: update jenkinsbot for QA sanity
tlebon Nov 26, 2024
0964c4f
chore: update pipeline to build app
tlebon Nov 26, 2024
a63d327
chore: change where total additions were saved
tlebon Nov 26, 2024
f21d74f
chore: testing pipeline
tlebon Dec 2, 2024
b54737c
chore: typo in jenkinsfile
tlebon Dec 10, 2024
ff530db
chore: ongoing changes to pipeline
tlebon Dec 10, 2024
931213a
chore: adjust post level for pipeline
tlebon Dec 10, 2024
d29d260
fix: pipeline ending when status is correct
tlebon Dec 10, 2024
6cfb499
chore: changing when-level
tlebon Dec 11, 2024
45bf683
chore: fix issue with commit hash
tlebon Dec 11, 2024
4ad434f
chore: updating run url
tlebon Dec 11, 2024
7c2d002
chore: updatimg PR commit id
tlebon Dec 11, 2024
af646f3
chore: updating wirebot secret
tlebon Dec 11, 2024
5845e5b
chore: fixing undefined commitmesssage
tlebon Dec 11, 2024
e951cda
chore: put success messsage inside script block
tlebon Dec 12, 2024
5c9bd01
chore: moving post outside stages instead of pipeline
tlebon Dec 12, 2024
d54309a
chore: remove undefined var
tlebon Dec 12, 2024
35a110f
chore: git-branch name
tlebon Dec 12, 2024
3b1ed37
Merge remote-tracking branch 'origin/dev' into feat/pre-commit-pipeline
tlebon Dec 17, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 118 additions & 0 deletions .github/workflows/precommit.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
name: precommit

on:
pull_request:
# we want to run the CI on every PR targetting those branches
branches: [dev]

concurrency:
group: precommit-deploy
cancel-in-progress: true

jobs:
build:
runs-on: buildjet-8vcpu-ubuntu-2204

outputs:
unit_tests_report: ${{ env.UNIT_TEST_REPORT_FILE }}
build_artifact: ${{ env.BUILD_ARTIFACT }}
total_additions: ${{ steps.check_additions.outputs.total_additions }}

env:
BUILD_DIR: server/dist/s3/
BUILD_ARTIFACT: ebs.zip
COMMIT_URL: ${{github.event.head_commit.url}}
COMMITTER: ${{github.event.head_commit.committer.name}}
CHANGELOG_FILE: './changelog.md'
UNIT_TEST_REPORT_FILE: './unit-tests.log'

steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
ref: ${{ github.event.pull_request.head.sha }}

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 18.16.x
cache: 'yarn'

- name: Install JS dependencies
run: yarn --immutable

- name: Update configuration
run: yarn configure

- name: Build
run: yarn build:prod

- uses: actions/upload-artifact@v4
with:
name: 'build-artifact'
path: '${{env.BUILD_DIR}}${{env.BUILD_ARTIFACT}}'

- name: Fetch PR details
id: pr_details
uses: octokit/[email protected]
with:
route: GET /repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Check total PR additions
id: check_additions
run: |
# Store response data in variable
response='${{ steps.pr_details.outputs.data }}'
# Parse additions from response
total_additions=$(echo "$response" | jq -r '.additions')
echo "Found total additions: $total_additions"
# Output for subsequent steps
echo "total_additions=$total_additions" >> $GITHUB_OUTPUT

deploy_to_aws:
name: 'Deploy to live environments'
runs-on: ubuntu-latest
needs: [build]

steps:
- uses: actions/download-artifact@v4
with:
name: 'build-artifact'

- name: Deploy to precommit environment
id: deploy
if: ${{ needs.build.outputs.total_additions > 100 && github.actor != 'dependabot[bot]' }}
uses: einaregilsson/beanstalk-deploy@v22
with:
application_name: Webapp
aws_access_key: ${{ secrets.WEBTEAM_AWS_ACCESS_KEY_ID }}
aws_secret_key: ${{ secrets.WEBTEAM_AWS_SECRET_ACCESS_KEY }}
deployment_package: ${{needs.build.outputs.build_artifact}}
environment_name: wire-webapp-precommit
region: eu-central-1
use_existing_version_if_available: true
version_description: ${{ github.sha }}
version_label: ${{ github.run_id }}
wait_for_deployment: false
wait_for_environment_recovery: 150

- name: Deployment Status
if: ${{ always() }}
run: |
if [[ "${{ steps.deploy.outcome }}" == "success" ]]; then
echo "✅ Deployment completed successfully"
elif [[ "${{ steps.deploy.outcome }}" == "skipped" ]]; then
if [[ "${{ needs.build.outputs.total_additions }}" -le 100 ]]; then
echo "⏭️ Deployment was skipped: PR has ${{ needs.build.outputs.total_additions }} additions (threshold: 100)"
elif [[ "${{ github.actor }}" == "dependabot[bot]" ]]; then
echo "⏭️ Deployment was skipped: PR is from dependabot"
else
echo "⏭️ Deployment was skipped"
fi
else
echo "❌ Deployment failed"
exit 1
fi
166 changes: 166 additions & 0 deletions Jenkinsfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
@NonCPS
def checkWorkflowRun(Map run, String commitHash) {
final String headSha = run['head_sha']
if (headSha == commitHash) {
echo("Found hash ${headSha}")
final String conclusion = run['conclusion']
echo("conclusion: ${conclusion}")

switch (conclusion) {
case 'success':
return true
case 'failure':
final String url = run['url']
error("❌ **Build failed for branch '${GIT_BRANCH_WEBAPP}'** See [Github Actions](${url})")
break
case 'cancelled':
final String url = run['url']
error("⚠️ **Build aborted for branch '${GIT_BRANCH_WEBAPP}'** See [Github Actions](${url})")
break
}
}
return false
}

pipeline {
agent {
node {
label 'built-in'
}
}

options { disableConcurrentBuilds(abortPrevious: true) }

environment {
CREDENTIALS = credentials('GITHUB_TOKEN_WEB')
WIRE_BOT_SECRET = credentials('JENKINSBOT_WEBAPP_DEV')
webappApplicationPath = 'https://wire-webapp-precommit.zinfra.io/'
}

stages {
stage('Wait for GitHub action to finish') {
when {
expression { BRANCH_NAME ==~ /PR-[0-9]+/ }
}
steps {
script {
def commit_hash = sh(script: 'git rev-parse HEAD', returnStdout: true).trim()
def pr_number = BRANCH_NAME.replaceAll(/\D/, '')
def changeTargetBranch = env.CHANGE_TARGET

def targetWorkflowUrl
switch (changeTargetBranch) {
case ['dev']:
targetWorkflowUrl = 'https://api.github.com/repos/wireapp/wire-webapp/actions/workflows/128602012/runs'
break
default:
targetWorkflowUrl = 'https://api.github.com/repos/wireapp/wire-webapp/actions/workflows/128602012/runs'
break
}

echo("Wait for github actions to start for ${BRANCH_NAME} against ${changeTargetBranch}")
final def VALID_STATUSES = ['queued', 'in_progress', 'completed']
timeout(time: 45, unit: 'MINUTES') {
waitUntil {
def output = sh label: 'Get runs', returnStdout: true, script: "curl -s -L -H 'Accept: application/vnd.github+json' -H 'Authorization: Bearer ${CREDENTIALS}' -H 'X-GitHub-Api-Version: 2022-11-28' ${targetWorkflowUrl}"
def json = readJSON text: output
if (json['message']) {
echo('Output: ' + output)
error('**Trigger script failed:** ' + json['message'])
}
def runs = json['workflow_runs']
echo('Looking for PR-' + pr_number + ' with hash' + commit_hash)
def matchingRun = runs.find { it['head_sha'] == commit_hash }
if (matchingRun) {
echo('Found ' + commit_hash)
def status = matchingRun['status']
echo('status: ' + status)
env.GITHUB_ACTION_URL = matchingRun['url'].replace('api.github.com/repos', 'github.com/')
return VALID_STATUSES.contains(status)
}
false
}
sleep(20)
}
}
}
}

stage('Check GitHub Action Status') {
when { expression { BRANCH_NAME ==~ /PR-[0-9]+/ } }
steps {
timeout(time: 15, unit: 'MINUTES') {
script {
def commit_hash = sh(script: 'git rev-parse HEAD', returnStdout: true).trim()
final String apiUrl = 'https://api.github.com/repos/wireapp/wire-webapp/actions/workflows/128602012/runs'
final String curlCmd = "curl -u \${CREDENTIALS} ${apiUrl}"
waitUntil {
final String output = sh(label: 'Check workflow', returnStdout: true, script: curlCmd)
final Object jsonData = readJSON(text: output)
final List workflowRuns = jsonData['workflow_runs']
echo("Looking for hash ${commit_hash}")

return workflowRuns.any { run -> checkWorkflowRun(run, commit_hash) }
}
}
}
}
}

stage('Check deployment') {
steps {
script {
def commit_hash = sh(script: 'git rev-parse HEAD', returnStdout: true).trim()
String commitMsg = sh(returnStdout: true, script: 'git log -1 --pretty=%B').trim()
try {
// Wait until deployment has finished (20 retries * 30 seconds == 10 minutes)
timeout(time: 10, unit: 'MINUTES') {
waitUntil {
def randomid = sh returnStdout: true, script: 'uuidgen'
randomid = randomid.trim()
def current_hash = sh returnStdout: true, script: "curl '${webappApplicationPath}commit?v=${randomid}'"
current_hash = current_hash.trim()
echo('Current version is: ' + current_hash)
if (current_hash == commit_hash) {
echo('Deployment finished.')
return true
}
env.MESSAGE = 'Current hash still is ' + current_hash + ' and not ' + commit_hash
sh "echo '${MESSAGE}' > deployment.log"
sleep(30)
return false
}
}
} catch (e) {
def reason = sh returnStdout: true, script: 'cat deployment.log || echo ""'
String errorMessage = """❌ **Deployment failed on** ${webappApplicationPath}
${commitMsg}
**Reason:** ${e}
${reason}"""
wireSend secret: env.WIRE_BOT_SECRET, message: errorMessage
}
def successMessage = """✅ **Deployment successful on** ${webappApplicationPath}
${commitMsg}"""
wireSend secret: env.WIRE_BOT_SECRET, message: successMessage
}
}
}

stage('Trigger smoke test') {
steps {
build job: 'Webapp_Smoke_Chrome', parameters: [string(name: 'TAGS', value: '@smoke'), string(name: 'GIT_BRANCH', value: 'web-dev'), string(name: 'webappApplicationPath', value: "$webappApplicationPath")], wait: false
}
}
}

post {
success {
wireSend secret: env.WIRE_BOT_SECRET, message: "✅ **Build finished for branch '$env.webappApplicationPath'**"
}
failure {
script {
wireSend(secret: env.WIRE_BOT_SECRET, message: "❌ **$BRANCH_NAME**\n[$CHANGE_TITLE](${CHANGE_URL})\nBuild aborted or failed! See [Github Actions](${env.GITHUB_ACTION_URL})")
}
}
}
}
Loading