Skip to content

Workflow file for this run

name: Integration Tests
on:
workflow_dispatch:
inputs:
use_minimal_test_account:
description: 'Indicate whether to use a minimal test account with limited resources for testing. Defaults to "false"'
required: false
default: 'false'
test_suite:
description: "Specify test suite to run from the 'tests/integration' directory. Examples: 'cli', 'domains', 'events', etc. If not provided, all suites are executed"
required: false
run_long_tests:
description: "Select 'True' to include long-running tests (e.g., database provisioning, server rebuilds). Defaults to 'False'"
required: false
type: choice
options:
- "True"
- "False"
default: "False"
sha:
description: 'Specify commit hash to test. This value is mandatory to ensure the tests run against a specific commit'
required: true
default: ''
pull_request_number:
description: 'Specify pull request number associated with the commit. Optional, but recommended when providing a commit hash (sha)'
required: false
openapi_spec_url:
description: 'Specify URL of the OpenAPI specification file to use for testing. Useful for validating tests against a specific API version or custom specification'
required: false
default: ''
python-version:
description: 'Specify the Python version to use for running tests. Leave empty to use the default Python version configured in the environment'
required: false
run-eol-python-version:
description: 'Indicates whether to run tests using an End-of-Life (EOL) Python version. Defaults to "false". Choose "true" to include tests for deprecated Python versions'
required: false
default: 'false'
type: choice
options:
- 'true'
- 'false'
push:
branches:
- main
- dev
env:
DEFAULT_PYTHON_VERSION: "3.10"
EOL_PYTHON_VERSION: "3.8"
EXIT_STATUS: 0
jobs:
integration_tests:
name: Run integration tests on Ubuntu
runs-on: ubuntu-latest
if: github.event_name == 'workflow_dispatch' && inputs.sha != '' || github.event_name == 'push' || github.event_name == 'pull_request'
steps:
- name: Checkout Repository with SHA
if: ${{ inputs.sha != '' }}
uses: actions/checkout@v4
with:
fetch-depth: 0
submodules: 'recursive'
ref: ${{ inputs.sha }}
- name: Checkout Repository without SHA
if: ${{ inputs.sha == '' }}
uses: actions/checkout@v4
with:
fetch-depth: 0
submodules: 'recursive'
- name: Get the hash value of the latest commit from the PR branch
uses: octokit/[email protected]
id: commit-hash
if: ${{ inputs.pull_request_number != '' }}
with:
query: |
query PRHeadCommitHash($owner: String!, $repo: String!, $pr_num: Int!) {
repository(owner:$owner, name:$repo) {
pullRequest(number: $pr_num) {
headRef {
target {
... on Commit {
oid
}
}
}
}
}
}
owner: ${{ github.event.repository.owner.login }}
repo: ${{ github.event.repository.name }}
pr_num: ${{ fromJSON(inputs.pull_request_number) }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Update system packages
run: sudo apt-get update -y
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: ${{ inputs.run-eol-python-version == 'true' && env.EOL_PYTHON_VERSION || inputs.python-version || env.DEFAULT_PYTHON_VERSION }}
- name: Install Python dependencies and update cert
run: |
pip install wheel boto3 && \
pip install certifi -U && \
pip install .[obj,dev]
- name: Install Package
run: make install SPEC="${{ inputs.OPENAPI_SPEC_URL }}"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Set LINODE_CLI_TOKEN
run: |
echo "LINODE_CLI_TOKEN=${{ secrets[inputs.use_minimal_test_account == 'true' && 'MINIMAL_LINODE_TOKEN' || 'LINODE_TOKEN'] }}" >> $GITHUB_ENV
- name: Run the integration test suite
run: |
timestamp=$(date +'%Y%m%d%H%M')
report_filename="${timestamp}_cli_test_report.xml"
make test-int TEST_ARGS="-v --junitxml=${report_filename}" TEST_SUITE="obj" RUN_LONG_TESTS="${{ inputs.run_long_tests }}"
env:
LINODE_CLI_TOKEN: ${{ env.LINODE_CLI_TOKEN }}
- name: Upload Test Report as Artifact
if: always()
uses: actions/upload-artifact@v4
with:
name: test-report-file
if-no-files-found: ignore
path: '*.xml'
retention-days: 1
- name: Update PR Check Run
uses: actions/github-script@v7
id: update-check-run
if: ${{ inputs.pull_request_number != '' && fromJson(steps.commit-hash.outputs.data).repository.pullRequest.headRef.target.oid == inputs.sha }}
env:
number: ${{ inputs.pull_request_number }}
job: ${{ github.job }}
conclusion: ${{ job.status }}
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const { data: pull } = await github.rest.pulls.get({
...context.repo,
pull_number: process.env.number
});
const ref = pull.head.sha;
const { data: checks } = await github.rest.checks.listForRef({
...context.repo,
ref
});
const check = checks.check_runs.filter(c => c.name === process.env.job);
const { data: result } = await github.rest.checks.update({
...context.repo,
check_run_id: check[0].id,
status: 'completed',
conclusion: process.env.conclusion
});
return result;
apply-calico-rules:
runs-on: ubuntu-latest
needs: [integration_tests]
if: ${{ success() || failure() }}
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
submodules: 'recursive'
- name: Set LINODE_CLI_TOKEN
run: |
echo "LINODE_CLI_TOKEN=${{ secrets[inputs.use_minimal_test_account == 'true' && 'MINIMAL_LINODE_TOKEN' || 'LINODE_TOKEN'] }}" >> $GITHUB_ENV
- name: Download kubectl and calicoctl for LKE clusters
run: |
curl -LO "https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl"
curl -LO "https://github.com/projectcalico/calico/releases/download/v3.25.0/calicoctl-linux-amd64"
chmod +x calicoctl-linux-amd64 kubectl
mv calicoctl-linux-amd64 /usr/local/bin/calicoctl
mv kubectl /usr/local/bin/kubectl
- name: Apply Calico Rules to LKE
run: |
cd e2e_scripts/cloud_security_scripts/lke_calico_rules/ && ./lke_calico_rules_e2e.sh
env:
LINODE_TOKEN: ${{ env.LINODE_CLI_TOKEN }}
add-fw-to-remaining-instances:
runs-on: ubuntu-latest
needs: [integration_tests]
if: ${{ success() || failure() }}
steps:
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.x'
- name: Install Linode CLI
run: |
pip install linode-cli
- name: Set LINODE_CLI_TOKEN
run: |
echo "LINODE_CLI_TOKEN=${{ secrets[inputs.use_minimal_test_account == 'true' && 'MINIMAL_LINODE_TOKEN' || 'LINODE_TOKEN'] }}" >> $GITHUB_ENV
- name: Create Firewall and Attach to Instances
run: |
FIREWALL_ID=$(linode-cli firewalls create --label "e2e-fw-$(date +%s)" --rules.inbound_policy "DROP" --rules.outbound_policy "ACCEPT" --text --format=id --no-headers)
echo "Created Firewall with ID: $FIREWALL_ID"
for instance_id in $(linode-cli linodes list --format "id" --text --no-header); do
echo "Attaching firewall to instance: $instance_id"
if linode-cli firewalls device-create "$FIREWALL_ID" --id "$instance_id" --type linode; then
echo "Firewall attached to instance $instance_id successfully."
else
echo "An error occurred while attaching firewall to instance $instance_id. Skipping..."
fi
done
env:
LINODE_CLI_TOKEN: ${{ env.LINODE_CLI_TOKEN }}
process-upload-report:
runs-on: ubuntu-latest
needs: [integration_tests]
if: always() && github.repository == 'linode/linode-cli' # Run even if integration tests fail and only on main repository
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
submodules: 'recursive'
- name: Download test report
uses: actions/download-artifact@v4
with:
name: test-report-file
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.x'
- name: Install Python dependencies
run: pip3 install requests wheel boto3==1.35.99
- name: Set release version env
run: echo "RELEASE_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV
- name: Add variables and upload test results
if: always()
run: |
filename=$(ls | grep -E '^[0-9]{12}_cli_test_report\.xml$')
python3 e2e_scripts/tod_scripts/xml_to_obj_storage/scripts/add_gha_info_to_xml.py \
--branch_name "${GITHUB_REF#refs/*/}" \
--gha_run_id "$GITHUB_RUN_ID" \
--gha_run_number "$GITHUB_RUN_NUMBER" \
--xmlfile "${filename}"
sync
python3 e2e_scripts/tod_scripts/xml_to_obj_storage/scripts/xml_to_obj.py "${filename}"
env:
LINODE_CLI_OBJ_ACCESS_KEY: ${{ secrets.LINODE_CLI_OBJ_ACCESS_KEY }}
LINODE_CLI_OBJ_SECRET_KEY: ${{ secrets.LINODE_CLI_OBJ_SECRET_KEY }}
notify-slack:
runs-on: ubuntu-latest
needs: [integration_tests]
if: ${{ (success() || failure()) && github.repository == 'linode/linode-cli' }} # Run even if integration tests fail and only on main repository
steps:
- name: Notify Slack
uses: slackapi/[email protected]
with:
method: chat.postMessage
token: ${{ secrets.SLACK_BOT_TOKEN }}
payload: |
channel: ${{ secrets.SLACK_CHANNEL_ID }}
blocks:
- type: section
text:
type: mrkdwn
text: ":rocket: *${{ github.workflow }} Completed in: ${{ github.repository }}* :white_check_mark:"
- type: divider
- type: section
fields:
- type: mrkdwn
text: "*Build Result:*\n${{ needs.integration_tests.result == 'success' && ':large_green_circle: Build Passed' || ':red_circle: Build Failed' }}"
- type: mrkdwn
text: "*Branch:*\n`${{ github.ref_name }}`"
- type: section
fields:
- type: mrkdwn
text: "*Commit Hash:*\n<${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }}|${{ github.sha }}>"
- type: mrkdwn
text: "*Run URL:*\n<${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|View Run Details>"
- type: divider
- type: context
elements:
- type: mrkdwn
text: "Triggered by: :bust_in_silhouette: `${{ github.actor }}`"