You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficcontrol.apache.org by er...@apache.org on 2023/06/08 16:56:47 UTC

[trafficcontrol] branch master updated: Created Github Actions for running API contract tests against Traffic Ops V4 (#7553)

This is an automated email from the ASF dual-hosted git repository.

ericholguin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficcontrol.git


The following commit(s) were added to refs/heads/master by this push:
     new 530696d301 Created Github Actions for running API contract tests against Traffic Ops V4 (#7553)
530696d301 is described below

commit 530696d30101b2488e13216f1c9fa64e70546255
Author: Gokula Krishnan <67...@users.noreply.github.com>
AuthorDate: Thu Jun 8 22:26:40 2023 +0530

    Created Github Actions for running API contract tests against Traffic Ops V4 (#7553)
    
    * Added github actions for API contract tests
    
    * changed permission for entrypoint
    
    * removed py-actions
    
    * Added traffic ops paths in workflow
    
    * modified entrypoint and workflow file
    
    * modified workflow file
    
    * modified workflow file
    
    * modified workflow file
    
    * modified workflow file
    
    * modified workflow file
    
    * modified workflow file
    
    * modified workflow file
    
    * modified workflow file
    
    * modified workflow file
    
    * modified workflow file
    
    * modified workflow file
    
    * Refactored entrypoint.sh
---
 .github/actions/to-api-contract-tests/README.md    |  59 ++++++++++
 .github/actions/to-api-contract-tests/action.yml   |  31 +++++
 .github/actions/to-api-contract-tests/cdn.json     |  59 ++++++++++
 .../actions/to-api-contract-tests/database.json    |  10 ++
 .github/actions/to-api-contract-tests/dbconf.yml   |  22 ++++
 .../actions/to-api-contract-tests/entrypoint.sh    | 125 +++++++++++++++++++++
 .github/workflows/to.api.contract.tests.yml        | 116 +++++++++++++++++++
 7 files changed, 422 insertions(+)

diff --git a/.github/actions/to-api-contract-tests/README.md b/.github/actions/to-api-contract-tests/README.md
new file mode 100644
index 0000000000..9130af97ac
--- /dev/null
+++ b/.github/actions/to-api-contract-tests/README.md
@@ -0,0 +1,59 @@
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+-->
+
+# to-api-contract-tests Python action
+This action runs the Traffic Ops API Contract tests with the Traffic Ops API.
+
+## Inputs
+
+### `version`
+**Required** Major API version to test e.g. 1, 2, 3, 4  etc.
+
+## Outputs
+
+### `exit-code`
+1 if the Go program(s) could be built successfully.
+
+## Example usage
+```yaml
+jobs:
+  tests:
+    runs-on: ubuntu-latest
+
+    services:
+      postgres:
+        image: postgres:11.9
+        env:
+          POSTGRES_USER: traffic_ops
+          POSTGRES_PASSWORD: twelve
+          POSTGRES_DB: traffic_ops
+        ports:
+        - 5432:5432
+        options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
+
+    steps:
+      - name: Checkout
+        uses: actions/checkout@master
+      - name: initialize database
+        uses: ./.github/actions/todb-init
+      - name: Run API v4 contract tests
+        uses: ./.github/actions/to-api-contract-tests
+        with:
+          version: 4
+```
diff --git a/.github/actions/to-api-contract-tests/action.yml b/.github/actions/to-api-contract-tests/action.yml
new file mode 100644
index 0000000000..2b56bef3c2
--- /dev/null
+++ b/.github/actions/to-api-contract-tests/action.yml
@@ -0,0 +1,31 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+name: 'to-api-contract-tests'
+description: 'Runs Traffic Ops API Contract tests'
+inputs:
+  version:
+    description: 'Version of Traffic Ops API against which to run tests, e.g. 1, 2, 3, etc.'
+    required: true
+    default: '4'
+runs:
+  using: composite
+  steps:
+    - run: ${{ github.action_path }}/entrypoint.sh
+      shell: bash
+      env:
+        INPUT_VERSION: ${{ inputs.version }}
diff --git a/.github/actions/to-api-contract-tests/cdn.json b/.github/actions/to-api-contract-tests/cdn.json
new file mode 100644
index 0000000000..0da5adbe8e
--- /dev/null
+++ b/.github/actions/to-api-contract-tests/cdn.json
@@ -0,0 +1,59 @@
+{
+	"disable_auto_cert_deletion": false,
+	"use_ims": true,
+	"role_based_permissions": true,
+	"traffic_ops_golang": {
+		"cert": "$PWD/localhost.crt",
+		"key": "$PWD/localhost.key",
+		"insecure": true,
+		"port": "6443",
+		"log_location_error": "traffic.ops.log",
+		"log_location_warning": "traffic.ops.log",
+		"log_location_info": null,
+		"log_location_debug": null,
+		"log_location_event": null,
+		"max_db_connections": 20,
+		"db_conn_max_lifetime_seconds": 60,
+		"db_query_timeout_seconds": 20,
+		"traffic_vault_backend": "postgres",
+		"traffic_vault_config": {
+			"dbname": "traffic_vault",
+			"hostname": "localhost",
+			"user": "traffic_vault",
+			"password": "twelve",
+			"port": 5432,
+			"ssl": false,
+			"conn_max_lifetime_seconds": 60,
+			"max_connections": 500,
+			"max_idle_connections": 30,
+			"query_timeout_seconds": 10,
+			"aes_key_location": "/aes.key"
+		},
+		"supported_ds_metrics": [ "kbps", "tps_total", "tps_2xx", "tps_3xx", "tps_4xx", "tps_5xx" ]
+	},
+	"cors": {
+		"access_control_allow_origin": "*"
+	},
+	"to": {
+		"base_url": "https://localhost",
+		"email_from": "no-reply@traffic-ops.test",
+		"no_account_found_msg": "A Traffic Ops user account is required for access. Please contact your Traffic Ops user administrator."
+	},
+	"portal": {
+		"base_url": "https://not-a-real-host.test/#!/",
+		"email_from": "no-reply@traffic-portal.test",
+		"pass_reset_path": "user",
+		"user_register_path": "user"
+	},
+	"secrets": [
+		"blahblah"
+	],
+	"inactivity_timeout": 60,
+	"smtp": {
+		"enabled": true,
+		"user": "$INPUT_SMTP_USER",
+		"password": "$INPUT_SMTP_PASSWORD",
+		"address": "${INPUT_SMTP_ADDRESS}:${INPUT_SMTP_PORT}"
+	},
+	"InfluxEnabled": false
+}
diff --git a/.github/actions/to-api-contract-tests/database.json b/.github/actions/to-api-contract-tests/database.json
new file mode 100644
index 0000000000..778be80bcd
--- /dev/null
+++ b/.github/actions/to-api-contract-tests/database.json
@@ -0,0 +1,10 @@
+{
+	"description": "Local PostgreSQL database on port 5432",
+	"dbname": "traffic_ops",
+	"hostname": "172.17.0.1",
+	"user": "traffic_ops",
+	"password": "twelve",
+	"port": "5432",
+	"ssl": false,
+	"type": "Pg"
+}
diff --git a/.github/actions/to-api-contract-tests/dbconf.yml b/.github/actions/to-api-contract-tests/dbconf.yml
new file mode 100644
index 0000000000..bd2d20426f
--- /dev/null
+++ b/.github/actions/to-api-contract-tests/dbconf.yml
@@ -0,0 +1,22 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+version: "1.0"
+name: dbconf.yml
+
+test:
+  driver: postgres
+  open: host=172.17.0.1 port=5432 user=traffic_ops password=twelve dbname=traffic_ops sslmode=disable
diff --git a/.github/actions/to-api-contract-tests/entrypoint.sh b/.github/actions/to-api-contract-tests/entrypoint.sh
new file mode 100755
index 0000000000..59f74c9159
--- /dev/null
+++ b/.github/actions/to-api-contract-tests/entrypoint.sh
@@ -0,0 +1,125 @@
+#!/bin/bash
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+set -o errexit -o nounset -o pipefail
+
+export PGUSER="traffic_ops"
+export PGPASSWORD="twelve"
+export PGHOST="localhost"
+export PGDATABASE="traffic_ops"
+export PGPORT="5432"
+
+to_admin_username="$(jq -r '.params.login.username' "${GITHUB_WORKSPACE}/traffic_portal/test/integration/config.json")"
+to_admin_password="$(jq -r '.params.login.password' "${GITHUB_WORKSPACE}/traffic_portal/test/integration/config.json")"
+password_hash="$(<<PYTHON_COMMANDS PYTHONPATH="${GITHUB_WORKSPACE}/traffic_ops/install/bin" python
+from _postinstall import hash_pass
+print(hash_pass('${to_admin_password}'))
+PYTHON_COMMANDS
+)"
+<<QUERY psql
+INSERT INTO tm_user (username, role, tenant_id, local_passwd)
+	VALUES ('${to_admin_username}', (
+		SELECT id
+		FROM "role"
+		WHERE "name" = 'admin'
+	), (
+		SELECT id
+		FROM tenant
+		WHERE "name" = 'root'
+	),
+    '${password_hash}'
+  );
+QUERY
+
+sudo useradd trafops
+
+openssl rand 32 | base64 | sudo tee /aes.key
+
+sudo apt-get install -y --no-install-recommends gettext
+
+cd "traffic_ops/traffic_ops_golang"
+
+if  [[ ! -d "${GITHUB_WORKSPACE}/vendor/golang.org" ]]; then
+	go mod vendor
+fi
+go build .
+
+echo "
+-----BEGIN CERTIFICATE-----
+MIIDtTCCAp2gAwIBAgIJAJgQuE9T48+gMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV
+BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX
+aWRnaXRzIFB0eSBMdGQwHhcNMTcwNTA5MDIyNTI0WhcNMTgwNTA5MDIyNTI0WjBF
+MQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50
+ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
+CgKCAQEA1OsuQ71qaSZ4ivGnh4YryeQEHMn5wZLX7kWYB637ssyOJnkU1ZGs93JM
+XJADzsjmssP6icSDhV2JPgDDYzx1eBJt6y3vHI7L3AdGfQJj+4FFABKR8moqpc1J
+WIMGnPzO6DeEc8irf0qxSh+yvuFX0j6oS8oCqiRxz5+HL2wEGWmrgr37JY4/bs7o
+4CMY19Ru1dP2Fr292HEIqCEnLTOuaHSWAEWx1Tm93kT9sXbw/SG2JTLQSX80biFL
+7foJeoGWLls2reTCYTprzWFaMu3x9I8HLtf4VIN44rtvo5N20KYgjGqvPjFGPljL
+yrgB8rXSCpH3M4AbazxD8fZKbdORawIDAQABo4GnMIGkMB0GA1UdDgQWBBT6zEpf
+DYbYCI3Bu82+Q5SmI+/7ojB1BgNVHSMEbjBsgBT6zEpfDYbYCI3Bu82+Q5SmI+/7
+oqFJpEcwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNV
+BAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZIIJAJgQuE9T48+gMAwGA1UdEwQF
+MAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAGLs1NcYNtUgN6FuMb6/UskEWLTKwfno
+NBtNdIbcZP3HmJHwruLWCeqj6HIWJC87EqmPTIYPdem3SAN1L20fWpzm7AB7av+2
+wTCAPVP0punF/IouSb6fyo8fdG1a104Mge4iy/Sf2uf09NEv08sfVdB4P0tKRRlg
+5KChhmspdPP7fmPXyghm4IC0Seknmh6IlVOnALXLU5OoCLHTie5Hjv4Tm8Xu0oBA
+dIH/cPu2/w5SAIVq9CtcsdglS0ZsCAv4W2YieuSLPf5xuI0q/5lFZGNoDpIWJldx
+Y2IpnoNCrHEAxijP5ctPawsxkSt2PmQ5uNNL7TbMudc3hZzOpTPkGoo=
+-----END CERTIFICATE-----
+" > localhost.crt
+
+echo "-----BEGIN RSA PRIVATE KEY-----
+MIIEpQIBAAKCAQEA1OsuQ71qaSZ4ivGnh4YryeQEHMn5wZLX7kWYB637ssyOJnkU
+1ZGs93JMXJADzsjmssP6icSDhV2JPgDDYzx1eBJt6y3vHI7L3AdGfQJj+4FFABKR
+8moqpc1JWIMGnPzO6DeEc8irf0qxSh+yvuFX0j6oS8oCqiRxz5+HL2wEGWmrgr37
+JY4/bs7o4CMY19Ru1dP2Fr292HEIqCEnLTOuaHSWAEWx1Tm93kT9sXbw/SG2JTLQ
+SX80biFL7foJeoGWLls2reTCYTprzWFaMu3x9I8HLtf4VIN44rtvo5N20KYgjGqv
+PjFGPljLyrgB8rXSCpH3M4AbazxD8fZKbdORawIDAQABAoIBAQCYOINc/qCDCHQJ
+sfa511ya/B9MjcG3eMpTmQG2C9b033WJX+tbPMjSJ68cRgHS5qK4j5AgypPU1yh1
+YYpO+jxpWZOoHbDjU9u/NJxaZ0kf2C2CfcRF8U0IOJoFY7doqP0r2/Uf6glh+f6C
+JeNewDBPKWictpHtHh0X+M9nQew0VZ7slXnV+IwUxiWYEtiIjwMyzSmfDEnN3ix5
+fuVQLvVaq+bbqXj2rMpJWFj7zMsG5HRePQl2kQGtMYLCIalnJIQs5jQn2YsliNyy
+fQiwWnU0wkrLlmkhlivlISRDtP35WQgF8ObsoQ3LZXRflB0C7U7zEl7Dj3Vi7WXr
+jsRZC4dxAoGBAPwuPdtc9gSNKjn8RnqfEJjdSo1qdLbGvRcSJNy4/kEEFECJXkeO
+mV/aklCi39cxAaIjVdTQ1XN67RMxgdekCI2Eg8h4RdvwgB/tAO+C3ExzMSOA1IcZ
+tWuwIA2YnaFF9Sla9iJqxgtoGlaqm4VTUM/IdZqlzsP08pfNq7bXPsr9AoGBANgk
+tkovf1Y0O4lBHX3eVLnHXForxEZh8bGHwuJJWWzb0ZFcXrrSd8FSycZrR28v4sdQ
+WSSVPz3Op95HoTVXVL9EJcZ+MTnHaoCHbYBkrGTlGviu5Fl2V5EbrN7R7CdxJeem
+HOU4shTy1acMPgf8sT17ykkXhVeUhSK2Jg6fZn6HAoGAI4/51SeE4htuKwMyhTRN
+SOFcFBlBIE1ieRBr9lx4Ln7+xCMbEog/hM7z9z8gxd35Vv4YqoxQrZpWOHCw2NIf
+CqX3V5vubhe6WcY4bY5MttM/yLvwPKUZeng57PDqucV9zzkuoKfiCdXCcRpaGDEp
+okOooghj4ip204WDg6NTDZkCgYEAwZTfzsGLgmF1kRBIoZqmt1zeUcQxHfhKx32Y
+BaM7/EtD/rSEAz7NEtBa9uLOL77rlSdZL3KcGXck0efFckitFkCqtIQBAoaf1E12
+vS9tV0/6QBAjZByhgM0Qnt/Uad7k2/vilUmZ9TkoMVy9kdm3xCFCowP14OKb+uK4
+YxBQc7ECgYEAm7eVtNlPHYmC54FU2bLucryNMLmu9I8O6zvbK5sxiMdtlh7OjaUB
+RQS5iVc0iTacDZTGh7eqNzgGplj76pWGHeZUy0xIj/ZIRu2qOy0v+ffqfX1wCz7p
+A22D22wvfs7CE3cUz/8UnvLM3kbTTu1WbbBbrHjAV47sAHjW/ckTqeo=
+-----END RSA PRIVATE KEY-----
+" > localhost.key
+
+resources="$(dirname "$0")"
+envsubst <"${resources}/cdn.json" >cdn.conf
+cp "${resources}/database.json" database.conf
+
+truncate --size=0 traffic.ops.log # Removes output from previous API versions and makes sure files exist
+./traffic_ops_golang --cfg ./cdn.conf --dbcfg ./database.conf &
+
+cd "../testing/api_contract/v$INPUT_VERSION"
+
+pytest -rA --to-user admin --to-password twelve12 --to-url https://localhost:6443/api/4.0
diff --git a/.github/workflows/to.api.contract.tests.yml b/.github/workflows/to.api.contract.tests.yml
new file mode 100644
index 0000000000..2d5fbbf8a3
--- /dev/null
+++ b/.github/workflows/to.api.contract.tests.yml
@@ -0,0 +1,116 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+name: Traffic Ops API Contract Tests
+
+env:
+  # alpine:3.13
+  ALPINE_VERSION: sha256:08d6ca16c60fe7490c03d10dc339d9fd8ea67c6466dea8d558526b1330a85930
+
+on:
+  push:
+    paths:
+      - .github/actions/todb-init/**
+      - .github/actions/to-api-contract-tests/**
+      - .github/workflows/to.api.contract.tests.yml
+      - traffic_ops/testing/api_contract/**
+      - lib/go-tc/**.go
+      - traffic_ops/**.go
+      - '!**_test.go'
+      - traffic_control/clients/python/**.py
+  create:
+  pull_request:
+    paths:
+      - .github/actions/todb-init/**
+      - .github/actions/to-api-contract-tests/**
+      - .github/workflows/to.api.contract.tests.yml
+      - traffic_ops/testing/api_contract/**
+      - lib/go-tc/**.go
+      - traffic_ops/**.go
+      - '!**_test.go'
+      - traffic_control/clients/python/**.py
+    types: [opened, reopened, ready_for_review, synchronize]
+
+jobs:
+
+  APIv4ContractTests:
+    if: github.event.pull_request.draft == false
+    runs-on: ubuntu-latest
+
+    services:
+      postgres:
+        image: postgres:13
+        env:
+          POSTGRES_USER: traffic_ops
+          POSTGRES_PASSWORD: twelve
+          POSTGRES_DB: traffic_ops
+        ports:
+        - 5432:5432
+        options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
+
+    steps:
+    - name: Checkout
+      uses: actions/checkout@master
+    - name: Cache Alpine Docker image
+      uses: actions/cache@v2
+      with:
+        path: ${{ github.workspace }}/docker-images
+        key: docker-images/alpine@${{ env.ALPINE_VERSION }}.tar.gz
+    - name: Import cached Alpine Docker image
+      run: .github/actions/save-alpine-tar/entrypoint.sh load ${{ env.ALPINE_VERSION }}
+    - name: Initialize Traffic Ops Database
+      id: todb
+      uses: ./.github/actions/todb-init
+    - name: Check Go Version
+      run: echo "::set-output name=value::$(cat GO_VERSION)"
+      id: go-version
+    - name: Install Go
+      uses: actions/setup-go@v2
+      with:
+        go-version: ${{ steps.go-version.outputs.value }}
+    - name: Install Python
+      uses: actions/setup-python@v1
+      with:
+        python-version: 3.10.11
+    - name: Install Python dependencies
+      run: |
+        pip install -r "${{ github.workspace }}/traffic_ops/testing/api_contract/v4/requirements.txt"
+    - name: Install Apache Traffic Control
+      run: |
+        python -m pip install --upgrade pip
+        pip install ${{ github.workspace }}/traffic_control/clients/python
+        pip install typing-extensions --upgrade
+    - name: Run API v4 contract tests
+      id: v4Tests
+      if: ${{ steps.todb.outcome == 'success' && always() }}
+      uses: ./.github/actions/to-api-contract-tests
+      with:
+        version: 4
+    - name: Upload Vault logs
+      if: ${{ steps.v4Tests.outcome != 'success' && always() }}
+      uses: actions/upload-artifact@v2
+      with:
+        name: v4 Traffic Vault logs
+        path: ${{ github.workspace }}/infrastructure/cdn-in-a-box/traffic.vault.logs
+    - name: Upload Ops logs
+      if: ${{ steps.v4Tests.outcome != 'success' && always() }}
+      uses: actions/upload-artifact@v2
+      with:
+        name: v4 Traffic Ops logs
+        path: ${{ github.workspace }}/traffic_ops/traffic_ops_golang/traffic.ops.log
+    - name: Save Alpine Docker image
+      run: .github/actions/save-alpine-tar/entrypoint.sh save ${{ env.ALPINE_VERSION }}