I have a CodeIgniter Web app connected with Mysql that is developed in the docker. I would like to do some unit test in the GitHub action fo ci/cd pipeline. The problem is some of the function would require enquiry data from Mysql database. So may I know if there is a way to setup a MySQL instance on Github action and run some .sql file so that my test data is in the database?
You can use GitHub Actions service containers to connect to databases like mysql. You can find details at https://docs.github.com/en/actions/guides/about-service-containers
I think this script can help people to conduct unit test with MySQL database and a .sql script file to load table schema and data on Github action. I am using Codeigniter 4 with Mysql. But the process of setting up a database would be similar as long as you are using MySQL.
name: CI Pipeline
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#v2
- name: Build the Docker image
run: docker-compose build
- name: up mysql and apache container runs
run: docker-compose up -d
#I am using codeIgniter4
- name: install dependencies
run: docker exec CI4_1 php composer.phar install
- name: buffering time for db container
uses: jakejarvis/wait-action#master
with:
time: '30s'
#db_1 is the name of database
- name: load database
run: docker exec -i mysql_1 mysql -uroot -proot db_1< ./testDatabase.sql
- name: unit test
run: docker exec CI4_1 ./vendor/bin/phpunit
Related
When I run skaffold in a github workflow like this
skaffold build
it calls the gradle jib correctly, creates an image and pushes it to the ghcr successfully. Grdale finishes successfully as can be seen in the log. Nevertheless, something happens afterwards that fails. It seems someone tries to access the just built image but is not authorized. This does not happen, if I execute it locally. And it does not fail in the github workflow if I call gradlew jib directly without skaffold being involved.
Built and pushed image as ghcr.io/tobias-neubert/motd-service:453f4c4-dirty
BUILD SUCCESSFUL in 11s
4 actionable tasks: 4 executed
time="2023-02-15T12:07:09Z" level=error msg="No matching credentials were found for \"ghcr.io\""
time="2023-02-15T12:07:09Z" level=error msg="No matching credentials were found for \"ghcr.io\""
getting image: GET https://ghcr.io/token?scope=repository%3Atobias-neubert%2Fmotd-service%3Apull&service=ghcr.io: UNAUTHORIZED: authentication required
Error: Process completed with exit code 1.
The github workflow:
name: Build and push motd-service
on:
push:
permissions:
packages: write
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout#v3
- name: Set up Java
uses: actions/setup-java#v2
with:
java-version: 17
distribution: temurin
- name: Setup Gradle
uses: gradle/gradle-build-action#v2
- name: Make gradlew executable
run: chmod +x ./gradlew
- name: Install skaffold
run: |
curl -Lo skaffold https://storage.googleapis.com/skaffold/releases/latest/skaffold-linux-amd64 && \
sudo install skaffold /usr/local/bin/
- name: Deactivate collecting skaffold metrics
run: skaffold config set --global collect-metrics false
- name: Build the motd image
env:
GH_PASSWORD: '${{ secrets.GITHUB_TOKEN }}'
run: skaffold build
Does anybody know what happens here?
It tries to fetch the digest of the new image, which it needs to render the k8s resources. Pushing the image was made by gradle. The jib plugin is configured to use environment variables for authenticating against ghcr.io. But skaffold does not know about those. So it fails to authenticate. A docker login does the trick, although it is not safe in a CI. So now I have to search for a better way to tell skaffold to authenticate against the registry
I am trying to create a job which has a test app needed for integrated tests. The test app is a simple application which is built and run first and then the final build runs which uses port 8080 on localhost for its integrated tests. However port 8080 is not available when the second docker build runs.
jobs:
my-job:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Build and run testapp
run: >
docker build
-t testapp
-f testapp/Dockerfile .
docker run
-p 8080:80
-d -t testapp
docker build
-t app
-f Dockerfile .
Is this a limitation of github actions? I have started looking at service containers as a workaround, but is there any way that the port can be made available for the subsequent commands in the step?
I'm using GitHub Actions and Docker WatchTower to update my images on the fly when I check-in my software (no, it is not crucial software. It is more important to have a lean CI/CD).
name: Docker Image CI
on:
push:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#v3
- name: Build the Docker image
run: docker build . -t me/myrepo:${{github.run_number}}
#:$(date +%s)
#docker build --rm -t ne/myrepo .
- name: Login to Docker Hub
env:
DOCKER_USER: ${{ secrets.DOCKER_USER }}
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
run: |
echo $DOCKER_USER
docker login -u $DOCKER_USER -p $DOCKER_PASSWORD
- name: Push the new Tag to Docker Hub
run: |
docker push me/myrepo:${{github.run_number}}
This works very nicely.
But watch tower can only download the latest version of a version e.g. latest.
Best solution would be I could keep the incrementing versions on github actions and watchtower would take the highest version. I guess it cannot do that.
or -
I tag the latest version (e.g. 49) also as the latest. How would you do that with git hub actions? This should be nothing else than giving multiple tags to a build, no?
Well, I actually answered it almost myself when phrasing the question.
Simply create 2 builds and 2 images. One incrementing (so that you always could roll-back to an older version) and update the latest version.
Prioritize the latest so that it is available faster.
- name: Build the Docker image
run: docker build . -t me/myrepo:latest
- name: Build the Docker image
run: docker build .
-t me/myrepo:${{github.run_number}}
and then push it twice.
- name: Push the also the latest Tag to Docker Hub
run: |
docker push me/myrepo:latest
- name: Push the new Tag to Docker Hub
run: |
docker push me/myrepo:${{github.run_number}}
I am trying to get a coverage report in GitHub Actions
but when I run the pipeline I gives me this error:
Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock
Then I search around add added the sudo mysql start service and now I get this error, but I don't know were or have to write mit -root -password and the -host?
Access denied for user 'root'#'localhost' (using password: YES)")
how do I do that?
name: Django CI
on:
push:
branches: [ unittests ]
paths-ignore: '**/SkoleProtocol/attendanceCode/tests/test_selenium.py'
pull_request:
branches: [ unittests ]
jobs:
build:
runs-on: ubuntu-latest
strategy:
max-parallel: 4
matrix:
python-version: [3.7, 3.8, 3.9]
steps:
- uses: actions/checkout#v2
- name: Set up Python 3.7
uses: actions/setup-python#v2
with:
python-version: 3.7
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Create test database
run: |
sudo service mysql start
- name: Coverage report
run: |
pip install coverage
coverage run manage.py test
coverage report
- name: Lint with flake8
run: |
pip install flake8
flake8 ./attendanceCode --exit-zero # Exit with status code "0" even if there are errors.
- name: Django Tests
run: |
python3 manage.py test
Two things that stand out.
Do you happen to have the credentials in an env file else where?
- name: Create test database
run: |
sudo service mysql start
You just happen to start the service rather than creating the database.
Try:
sudo /etc/init.d/mysql start // To start the service
mysql -uroot -proot -e "CREATE DATABASE __dbname__;"
I have the following yaml file. It were working just fine until yesterday. Unfortunately starting from today received the below warning and followed by the following error.
Hope someone will be able to point me to solution to fixed this issue. Below is the yaml code
name: CI_dev
on:
pull_request:
branches: [ dev ]
jobs:
test_pipeline:
runs-on: ubuntu-latest
steps:
# Install Salesforce CLI
- name: Install Salesforce CLI
run: |
wget https://developer.salesforce.com/media/salesforce-cli/sfdx-linux-amd64.tar.xz
mkdir sfdx-cli
tar xJf sfdx-linux-amd64.tar.xz -C sfdx-cli --strip-components 1
./sfdx-cli/install
#Checkout master
- name: 'checkout master'
uses: actions/checkout#master
#read secret, authenticate and deploy
- name: 'Populate auth file with SFDX_URL secret'
shell: bash
run: 'echo ${{ secrets.secret}} > ./secret.txt'
- name: 'Authenticate'
run: 'sfdx force:auth:sfdxurl:store --sfdxurlfile=./secret.txt -a secretAlias'
- name: 'Deploy'
run: "sfdx force:source:deploy --sourcepath ./force-app/main/default -l RunLocalTests -u secretAlias"
Below is the warning that appear on the authenticate step
Warning: force:auth:sfdxurl:store is not a sfdx command.
Did you mean auth:sfdxurl:store? [y/n]:
And below is the error that appear on the Deploy step
ERROR running force:source:deploy: No org configuration found for name secretAlias
Error: Process completed with exit code 1.
sfdx (at least linux distributions) have recently updated from 7.82.1 to 7.83.1 (January 2021)
since 7.83.1 it follows different syntax format.
You need to remove force: from your 'Authenticate' command line as it is advised in error message.
You can look your current version with:
sfdx --version
Busy Box was right. just need to remove force from force:auth and its alread working again. below is the updated yaml file as reference.
name: CI_dev
on:
pull_request:
branches: [ dev ]
jobs:
test_pipeline:
runs-on: ubuntu-latest
steps:
# Install Salesforce CLI
- name: Install Salesforce CLI
run: |
wget https://developer.salesforce.com/media/salesforce-cli/sfdx-linux-amd64.tar.xz
mkdir sfdx-cli
tar xJf sfdx-linux-amd64.tar.xz -C sfdx-cli --strip-components 1
./sfdx-cli/install
#Checkout master
- name: 'checkout master'
uses: actions/checkout#master
#read secret, authenticate and deploy
- name: 'Populate auth file with SFDX_URL secret'
shell: bash
run: 'echo ${{ secrets.secret}} > ./secret.txt'
- name: 'Authenticate'
run: 'sfdx auth:sfdxurl:store --sfdxurlfile=./secret.txt -a secretAlias'
- name: 'Deploy'
run: "sfdx force:source:deploy --sourcepath ./force-app/main/default -l RunLocalTests -u secretAlias"