How do I prevent GitHub actions from replacing some files - laravel

I want to do a simple CD/CD to do automatic deployments for my Laravel project but turns out my .env file is always replaced. How do I make sure it's not always replaced
Here is my action file
name: Laravel
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
laravel-tests:
runs-on: self-hosted
steps:
- uses: shivammathur/setup-php#b7d1d9c9a92d8d8463ce36d7f60da34d461724f8
with:
php-version: '7.4'
- uses: actions/checkout#v2
- name: Copy .env
run: php -r "file_exists('.env') || copy('.env.example', '.env');"
- name: Install Dependencies
run: composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist
- name: Generate key
run: php artisan key:generate
- name: Directory Permissions
run: chmod -R 777 storage bootstrap/cache
- name: Create Database
run: |
mkdir -p database
touch database/database.sqlite
- name: Execute tests (Unit and Feature tests) via PHPUnit
env:
DB_CONNECTION: sqlite
DB_DATABASE: database/database.sqlite
run: vendor/bin/phpunit

Each time your workflow run you will get a new machine. Thus there is no files you created them on previous run. As this if you need to have some file created at runtime you need to repeat this step each time.
Please check it here to understand better github ations basics.
You don't have much options to share this file accros run, as keeping secrets in artifacts is bad choice. So you need to recreate this file each time you need it based on the secret which you may keep in secrets context. Please check this link:
- name: Create env file
run: |
cat << EOF >> .env
API_ENDPOINT="https://xxx.execute-api.us-west-2.amazonaws.com"
API_KEY=${{ secrets.API_KEY }}
EOF

The github action works on the files on your git repo.
Your .env is not and should not be in the repo, because it contains your credentials/secrets.
You may have it on your local computer, but it's included in the gitignore so git (an github as a consequence) doesn't track it.
As a consequence no, you don't have the .env file at each action run. The most straightforward way to do it is:
create a .env.production file that is gitted and committed. Place there your main .env variables that aren't secrets/sensitive, such as:
APP_NAME=YourAppName
APP_ENV=production
APP_DEBUG=false
APP_LOG_LEVEL=warning
APP_URL=https://your-url.com
CACHE_DRIVER=redis
SESSION_DRIVER=file
QUEUE_CONNECTION=redis
... etc ...
DO NOT INCLUDE KEYS, PASSWORDS OR SECRETS THOUGH..
Now copy that file as your default .env file in one of your steps:
- name: Copy .env
run: php -r "file_exists('.env') || copy('.env.production', '.env');"
Now it's time to handle your secrets. You should add them as github secret of your repo, and included using the env directive of your github actions:
env:
APP_KEY: ${{ secrets.APP_KEY }}
DB_PASSWORD: ${{ secrets.DB_PASSWORD }}
....
This last step may need to vary a bit depending on how/where you do the actual deploy, but that should be the gist of it: you pull them from the github secrets space and you add them to the production environment

Related

How to work with Github Actions without .env file

I'm trying to perform deploy Laravel app to AWS Elastic Beanstalk with Github Actions but I had questions on running Github actions because currently I'm try to avoid upload .env file to my repository.
Below provided the default workflows which generated by Github
name: Laravel
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
jobs:
laravel-tests:
runs-on: ubuntu-latest
steps:
- uses: shivammathur/setup-php#15c43e89cdef867065b0213be354c2841860869e
with:
php-version: '8.0'
- uses: actions/checkout#v3
- name: Copy .env
run: php -r "file_exists('.env') || copy('.env.example', '.env');"
- name: Install Dependencies
run: composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist
- name: Generate key
run: php artisan key:generate
- name: Directory Permissions
run: chmod -R 777 storage bootstrap/cache
- name: Create Database
run: |
mkdir -p database
touch database/database.sqlite
- name: Execute tests (Unit and Feature tests) via PHPUnit
env:
DB_CONNECTION: sqlite
DB_DATABASE: database/database.sqlite
run: vendor/bin/phpunit
The generated file showing error
There was 1 failure:
1) Tests\Feature\ExampleTest::test_the_application_returns_a_successful_response
Expected response status code [200] but received 500.
Failed asserting that 200 is identical to 500.
The following exception occurred during the last request:
PDOException: SQLSTATE[HY000]: General error: 1 no such table: users in /home/runner/work/sampleSearch/sampleSearch/vendor/laravel/framework/src/Illuminate/Database/Connection.php:414
So may I know how can I solve this connection issues without upload .env file?

Default .yml file from GitHub from does not work

I'm trying to run phpunit tests through GitHub actions.
I use .yml file that GitHub creates by default for Laravel projects but it does not seem worked.
Here it is (looks good):
name: Laravel
on:
push:
branches: [ master ]
jobs:
tests:
runs-on: ubuntu-latest
steps:
- name: Setup
uses: shivammathur/setup-php#15c43e89cdef867065b0213be354c2841860869e
with:
php-version: '8.1'
- name: Copy.env
run: |
php -r "file_exists('.env') || copy('.env.example', '.env');"
- name: Install Dependencies
run: composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist
- name: Generate key
run: php artisan key:generate
- name: Directory Permissions
run: chmod -R 777 storage bootstrap/cache
- name: Create Database
run: |
mkdir -p database
touch database/database.sqlite
- name: Execute tests (Unit and Feature tests) via PHPUnit
env:
DB_CONNECTION: sqlite
DB_DATABASE: database/database.sqlite
run: vendor/bin/phpunit
But when I do git push I got:
Any ideas? Thanks
I found a solution.
I compared my script with the default one by GitHub and found that somehow I missed 1 step: uses: actions/checkout#v2.
That's why the script could not find .env.example file in the directory.
Now everything works fine.

Deploy my laravel project to shared hosting with github actions

please I added GitHub action main.yml to my Laravel project to the shared hosting for automated deployment. The deployment worked okay but the project was placed outside public_html because of the path I specified - server_dir: /home5/app/public_html/, I want the project files to be put into the public_html folder. Below is the code:
name: Glory Deploy Production
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
web-deploy:
name: Deploying...
runs-on: ubuntu-latest
steps:
- uses: shivammathur/setup-php#15c43e89cdef867065b0213be354c2841860869e
with:
php-version: '8.0'
- uses: actions/checkout#v2.3.2
- name: Copy .env
run: php -r "file_exists('.env') || copy('.env.example', '.env');"
- name: Install Dependencies
run: composer update --ignore-platform-reqs
- name: Generate key
run: php artisan key:generate
- name: Directory Permissions
run: chmod -R 777 storage bootstrap/cache
- name: 📂 Sync files
uses: SamKirkland/FTP-Deploy-Action#4.0.0
with:
server: ${{ secrets.server }}
username: ${{ secrets.username}}
password: ${{ secrets.password}}
server_dir: /home5/app/public_html/
Please can I modify the path pointing to the public_html? How?
I am considering your ftp user is a default user that has root path
server_dir: "public_html/"
If your user not has the root path you must consider its path until public_html

Is it possible to use GitHub secrets inside my shell file?

This is my simple Action on my GitHub repo:
name: CI
on:
push:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Get /my_account/my_infra
run: |
sudo mkdir /my_account
sudo chmod -R 777 /my_account
cd /my_account
git clone https://github.com/my_account/my_infra
- name: Get /my_account/my_repo
run: |
cd /my_account
git clone https://github.com/my_account/my_repo
- name: Run my build script
run: |
cd /my_account/my_infra
./build.sh /my_account/my_repo
Since GitHub does not provide a way to reuse actions across multiple similar repos, I came up with the idea of creating a base repo, then download that base alongside the current repo, then run a custom shell script from that base repo, passing my current repo as a parameter.
This works perfect. This way I can reuse my base repo across many similar repositories. And I can reuse near 500 lines of build script instead of repeating myself for 50 repositors (which means 25000 lines of CI/CD code).
However, now I need to access some resources (like login into my docker hub account) to pull and push stuff.
Is it possible to use GitHub secrects in my build.sh?
When you set env in your workflow, doc here, they are set as environment variables in your containerised workflow.
This means that if you set a secret in your repository, can be found under settings=> secrets and then assign it to an env in your workflow, they can then be accessed in your build.sh
example:
name: CI
on:
push:
branches: [ main ]
env:
super_secret: ${{ secrets.my_secret }}
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Get /my_account/my_infra
run: |
sudo mkdir /my_account
sudo chmod -R 777 /my_account
cd /my_account
git clone https://github.com/my_account/my_infra
- name: Get /my_account/my_repo
run: |
cd /my_account
git clone https://github.com/my_account/my_repo
- name: Run my build script
run: |
cd /my_account/my_infra
./build.sh /my_account/my_repo
In this case your build.sh can do something like:
#!/bin/bash
npm run build $super_secret
Yes, you just need to assign them to a variable, like
env:
ACCESS_TOKEN: ${{ secrets.ACCESS_TOKEN }}
run: build.sh
Then you can refer to ACCESS_TOKEN variable in the shell script.

How can I upload vendor/ folder when composer.lock changes through github action using SamKirkland/FTP-Deploy-Action#3.1.1

I was trying to push a laravel app to a ftp server through github action. Here is the snippet is from my deploy.yml file.
jobs:
Deployment:
name: Deploy Action
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#v2.1.0
with:
fetch-depth: 2
- name: Create env file
run: |
touch .env
echo APP_NAME=MyAppName >> .env
echo APP_ENV=production >> .env
echo APP_DEBUG=false >> .env
echo LOG_CHANNEL=daily >> .env
echo DB_DATABASE=${{ secrets.DEV_DB_DATABASE }} >> .env
echo DB_USERNAME=${{ secrets.DEV_DB_USERNAME }} >> .env
echo DB_PASSWORD=${{ secrets.DEV_DB_PASSWORD }} >> .env
echo "!.env" > .git-ftp-include
- name: Cache dependencies
uses: actions/cache#v1
with:
path: ~/.composer/cache/files
key: dependencies-composer-${{ hashFiles('composer.json') }}
- name: Setup PHP
uses: shivammathur/setup-php#v2
with:
php-version: 7.3
extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite
coverage: none
- name: Install Composer dependencies
run: composer install --prefer-dist --no-interaction --no-suggest
- name: Adding Vendor
run: echo "!vendor/" > .git-ftp-include
- name: FTP Deploy Action
uses: SamKirkland/FTP-Deploy-Action#3.1.1
with:
ftp-server: ftp://${{ secrets.DEV_FTP_SERVER }}
ftp-username: ${{ secrets.DEV_FTP_USERNAME }}
ftp-password: ${{ secrets.DEV_FTP_PASSWORD }}
Every time when the job runs, it uploads whole vendor/ directory on FTP server. It takes a lot of time when the vendor folder uploads. How can I just upload only changes in vendor/ directory, or if only composer.lock get modified it will upload vendor/.
Or how can I make it simple, fast and easy ?
You can replace:
run: echo "!vendor/" > .git-ftp-include
for:
run: echo "vendor/:composer.lock" > .git-ftp-include
However keep in mind that this:
will upload all files in the vendor folder, even those that are on the server already. And it will not delete files from that directory if local files are deleted.
That could be a problem in the case in which a package removes a local file in a new version release because the file would be kept on the server, possibly causing some conflicts.
See the docs here.
Edit: If you have already committed the composer.lock file, And you want to reupload the vendor folder for the last time, make sure to change the .lock file. Maybe add a new line or space to it.

Resources