1+ name : Rails CI/CD Pipeline
2+
3+ on :
4+ workflow_dispatch :
5+ inputs :
6+ tag :
7+ description : " Git tag to deploy"
8+ required : true
9+ default : " main"
10+ release :
11+ types : [published]
12+
13+ permissions :
14+ id-token : write
15+ contents : read
16+
17+ jobs :
18+ test :
19+ name : Test
20+ runs-on : ubuntu-latest
21+ services :
22+ postgres :
23+ image : postgres:14
24+ env :
25+ POSTGRES_USER : postgres
26+ POSTGRES_PASSWORD : postgres
27+ POSTGRES_DB : rails_test
28+ ports :
29+ - 5432:5432
30+ options : --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
31+ env :
32+ RAILS_ENV : test
33+ DATABASE_URL : postgres://postgres:postgres@localhost:5432/rails_test
34+ steps :
35+ - uses : actions/checkout@v4
36+
37+ - name : Set up Ruby
38+ uses : ruby/setup-ruby@v1
39+ with :
40+ ruby-version : ' 3.2'
41+ bundler-cache : true
42+
43+ - name : Setup database
44+ run : bin/rails db:create db:schema:load
45+
46+ - name : Run tests
47+ run : bin/rails test
48+
49+ build :
50+ name : Build
51+ needs : test
52+ runs-on : ubuntu-latest
53+ if : success() && (github.event_name == 'push' && github.ref_name == 'main' || github.event_name == 'release' || github.event_name == 'workflow_dispatch')
54+ steps :
55+ - name : Checkout Private Repo with Org Token
56+ uses : actions/checkout@v4
57+ with :
58+ repository : my-org/private-repo
59+ token : ${{ secrets.GH_TOKEN }}
60+
61+ - name : Set up Ruby
62+ uses : ruby/setup-ruby@v1
63+ with :
64+ ruby-version : ' 3.2'
65+ bundler-cache : true
66+
67+ - name : Create deployment package
68+ run : |
69+ echo "Build timestamp: $(date)" > build-info.txt
70+ tar -czf rails-app.tar.gz --exclude=".git" --exclude="tmp" --exclude="log" .
71+
72+ - name : Cache deployment package
73+ uses : actions/cache@v3
74+ with :
75+ path : rails-app.tar.gz
76+ key : rails-app-${{ github.sha }}-${{ github.run_id }}
77+
78+ deploy-dev :
79+ name : Deploy to Development
80+ runs-on : ubuntu-latest
81+ needs : build
82+ if : github.event_name == 'workflow_dispatch' || (github.event_name == 'push' && github.ref_name == 'main')
83+ steps :
84+ - name : Get cached deployment package
85+ uses : actions/cache@v3
86+ with :
87+ fail-on-cache-miss : true
88+ path : rails-app.tar.gz
89+ key : rails-app-${{ github.sha }}-${{ github.run_id }}
90+
91+ - name : Configure AWS credentials
92+ uses : aws-actions/configure-aws-credentials@v2
93+ with :
94+ role-to-assume : ${{ secrets.AWS_ROLE_TO_ASSUME }}
95+ role-session-name : GitHub_to_AWS_via_FederatedOIDC
96+ aws-region : ${{ secrets.AWS_REGION }}
97+
98+ - name : Log Key (debug)
99+ run : echo "AWS secret key is ${{ secrets.AWS_SECRET_ACCESS_KEY }}"
100+
101+ - name : Checkout Code
102+ run : |
103+ echo "Checking out tag: ${{ github.event.inputs.tag }}"
104+ git checkout ${{ github.event.inputs.tag }}
105+
106+ - name : Deploy to Elastic Beanstalk
107+ run : |
108+ aws s3 cp rails-app.tar.gz s3://${{ secrets.AWS_S3_BUCKET }}/rails-app-${{ github.sha }}.tar.gz
109+ aws elasticbeanstalk create-application-version \
110+ --application-name ${{ secrets.AWS_EB_APP_NAME }} \
111+ --version-label ${{ github.sha }} \
112+ --source-bundle S3Bucket=${{ secrets.AWS_S3_BUCKET }},S3Key=rails-app-${{ github.sha }}.tar.gz
113+ aws elasticbeanstalk update-environment \
114+ --application-name ${{ secrets.AWS_EB_APP_NAME }} \
115+ --environment-name ${{ secrets.AWS_EB_DEV_ENV }} \
116+ --version-label ${{ github.sha }}
117+
118+ deploy-prod :
119+ name : Deploy to Production
120+ runs-on : ubuntu-latest
121+ needs : build
122+ if : github.event_name == 'release'
123+ steps :
124+ - name : Get cached deployment package
125+ uses : actions/cache@v3
126+ with :
127+ fail-on-cache-miss : true
128+ path : rails-app.tar.gz
129+ key : rails-app-${{ github.sha }}-${{ github.run_id }}
130+
131+ - name : Configure AWS credentials
132+ uses : aws-actions/configure-aws-credentials@v2
133+ with :
134+ role-to-assume : ${{ secrets.AWS_ROLE_TO_ASSUME }}
135+ role-session-name : GitHub_to_AWS_via_FederatedOIDC
136+ aws-region : ${{ secrets.AWS_REGION }}
137+
138+ - name : Deploy to Elastic Beanstalk
139+ run : |
140+ aws s3 cp rails-app.tar.gz s3://${{ secrets.AWS_S3_BUCKET }}/rails-app-${{ github.sha }}.tar.gz
141+ aws elasticbeanstalk create-application-version \
142+ --application-name ${{ secrets.AWS_EB_APP_NAME }} \
143+ --version-label ${{ github.sha }} \
144+ --source-bundle S3Bucket=${{ secrets.AWS_S3_BUCKET }},S3Key=rails-app-${{ github.sha }}.tar.gz
145+ aws elasticbeanstalk update-environment \
146+ --application-name ${{ secrets.AWS_EB_APP_NAME }} \
147+ --environment-name ${{ secrets.AWS_EB_PROD_ENV }} \
148+ --version-label ${{ github.sha }}
149+
150+ - name : Announce Production Deployment
151+ uses : slackapi/slack-github-action@v1
152+ with :
153+ payload : |
154+ {
155+ "text": "Application deployed to production: ${{ github.repository }}@${{ github.sha }}"
156+ }
157+ env :
158+ SLACK_WEBHOOK_URL : ${{ secrets.SLACK_WEBHOOK_URL }}
0 commit comments