Skip to content

Commit

Permalink
Merge pull request #63 from SAP-samples/feat/gh-action
Browse files Browse the repository at this point in the history
Feat/gh action
  • Loading branch information
alperdedeoglu authored Oct 11, 2024
2 parents 7fb6918 + bfbd24a commit eff3427
Show file tree
Hide file tree
Showing 6 changed files with 341 additions and 9 deletions.
82 changes: 82 additions & 0 deletions .github/workflows/ci-pr.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
name: CI for Pull Requests

on:
pull_request:
branches:
- main # Run the workflow for PRs targeting the "main" branch

jobs:
test:
runs-on: ubuntu-latest

steps:
# Step 1: Check out the code from the PR branch
- name: Checkout code
uses: actions/checkout@v2

# Step 2: Set up Node.js
- name: Set up Node.js
uses: actions/setup-node@v3
with:
node-version: '20.x'

# Step 3: Install MBT and dependencies
- name: Install MBT and dependencies
run: |
npm install -g mbt
cd code
npm install --production
# Step 4: Install CF Cli
- name: Install CF Cli
run: |
wget -q -O - https://packages.cloudfoundry.org/debian/cli.cloudfoundry.org.key | gpg --dearmor -o /usr/share/keyrings/cli.cloudfoundry.org.gpg
echo "deb [trusted=yes] https://packages.cloudfoundry.org/debian stable main" | sudo tee /etc/apt/sources.list.d/cloudfoundry-cli.list
sudo apt-get update
sudo apt-get install cf8-cli
# Step 5: Download and Install SAP BTP CLI
- name: Install BTP CLI
run: |
dpkg --print-architecture
curl -LJO https://tools.hana.ondemand.com/additional/btp-cli-linux-amd64-latest.tar.gz --cookie "eula_3_2_agreed=tools.hana.ondemand.com/developer-license-3_2.txt"
tar -xzf btp-cli-linux-amd64-latest.tar.gz
ls -a
mv linux-amd64/btp /usr/local/bin
chmod +x /usr/local/bin/btp
# Step 6: Install Multiapps Plugin
- name: Install Multiapps Plugin
run: |
cf add-plugin-repo CF-Community https://plugins.cloudfoundry.org
cf install-plugin multiapps -f
# Step 7: Login to CF
- name: Log in to Cloud Foundry
run: |
cf login -u ${{ secrets.CF_USERNAME }} -p ${{ secrets.CF_PASSWORD }} -o ${{ secrets.CF_ORG }} -s ${{ secrets.CF_SPACE }} -a ${{ secrets.CF_API }}
# Step 8: Build the project
- name: Build MTA Archive
run: |
cd deploy/cf
sed -i 's|{{BROKER_USER}}|'"${{ secrets.BROKER_USER }}"'|g' ./mtaext/ci.mtaext
sed -i 's|{{BROKER_PASSWORD}}|'"${{ secrets.BROKER_PASSWORD }}"'|g' ./mtaext/ci.mtaext
mbt build -e ./mtaext/ci.mtaext
# Step 9: Verify MTA Archive built successfully
- name: Deploy to CF
run: |
cf deploy ./deploy/cf/mta_archives/susaas_0.0.1.mtar -f
# Step 10: Verify MTA Archive built successfully
- name: Run Subscription Test Script
run: |
chmod +x ./code/test/subscription-test.sh
./code/test/subscription-test.sh
env:
BTP_USERNAME: ${{ secrets.CF_USERNAME }}
BTP_PASSWORD: ${{ secrets.CF_PASSWORD }}
BTP_SUBDOMAIN: ${{ secrets.BTP_SUBDOMAIN }}


38 changes: 35 additions & 3 deletions code/broker/start.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,44 @@

import Broker from '@sap/sbf';

// If this is a CI CD deployment we get broker credentials from env and hardcode the catalog.
if (process.env.cicd) {
const catalog = `{
"services": [
{
"name": "susaas-api",
"description": "Sustainable SaaS API",
"bindable": true,
"plans": [
{
"name": "trial",
"description": "Trial Plan",
"id": "8f7c2dce-7500-4115-9df5-aebb9060e83d"
},
{
"name": "default",
"description": "Standard Plan",
"id": "d1d6bcc4-5f75-43cb-a537-3fddbff00f11"
},
{
"name": "premium",
"description": "Premium Plan",
"id": "2e12d1f4-d871-443c-8824-6f33d2748a1b"
}
],
"id": "ba609874-a1da-4f9c-a22b-f61de0c71a9e"
}
]
}`
let brokerConfig = { brokerCredentials: { [process.env["BROKER_USER"]]: process.env["BROKER_PASSWORD"] }, catalog: JSON.parse(catalog) }
new Broker(brokerConfig).start()
}
// If VCAP_APPLICATION is defined, we are in a Cloud Foundry scenario
// For local testing, the USER and PASSWORD are always injected via environment variables
if(process.env.VCAP_APPLICATION && process.env.NODE_ENV === "production"){
else if (process.env.VCAP_APPLICATION && process.env.NODE_ENV === "production" && process.env.cicd !== true) {
new Broker().start();
}else{
} else {
// In production Kyma scenarios and local testing, BROKER_USER and BROKER_PASSWORD are passed in env variables
let brokerConfig = { brokerCredentials : { [process.env["BROKER_USER"]] : process.env["BROKER_PASSWORD"] }}
let brokerConfig = { brokerCredentials: { [process.env["BROKER_USER"]]: process.env["BROKER_PASSWORD"] } }
new Broker(brokerConfig).start()
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ annotate service.CircularityMetrics with @(
},
{
$Type : 'UI.DataField',
Value : countryRecyclability,
Value : countryRecyclability_code,
![@UI.Importance] : #High
},
{
Expand Down Expand Up @@ -49,7 +49,7 @@ annotate service.CircularityMetrics with @(
AggregatableProperties : [{
Property : eoLRecyclability
}],
GroupableProperties : [countryRecyclability]
GroupableProperties : [countryRecyclability_code]
}
);

Expand All @@ -73,7 +73,7 @@ annotate service.CircularityMetrics with @(
UI.Chart #columnChartCircularityMetrics : {
ChartType : #Column,
Measures : [sumEoLRecyclability],
Dimensions : [countryRecyclability],
Dimensions : [countryRecyclability_code],
Title : '{i18n>chartCircularityMetrics}',
MeasureAttributes : [{
$Type : 'UI.ChartMeasureAttributeType',
Expand Down
6 changes: 3 additions & 3 deletions code/srv/srv/annotations/public/layouts_SalesSplits.cds
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ annotate service.SalesSplits with @(
{
Property : reSellSales
}],
GroupableProperties : [ country],
GroupableProperties : [ country_code],
},
Analytics.AggregatedProperties : [
{
Expand Down Expand Up @@ -96,7 +96,7 @@ annotate service.SalesSplits with @(
},
{
$Type : 'UI.DataField',
Value : country,
Value : country_code,
![@UI.Importance] : #High
}
]}
Expand All @@ -107,7 +107,7 @@ annotate service.SalesSplits with @(
UI.Chart #columnChartSalesSplits : {
ChartType : #Column,
Measures : [sumTotalRevenue],
Dimensions : [country],
Dimensions : [country_code],
Title : '{i18n>chartSalesSplits}',
MeasureAttributes : [{
$Type : 'UI.ChartMeasureAttributeType',
Expand Down
200 changes: 200 additions & 0 deletions code/test/subscription-test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
#!/bin/bash

# Configuration Variables
SUBACCOUNT_GUID=""
APPLICATION_NAME="susaas-dev-tfe-saas-dev-test"
PLAN_NAME="default"
POLL_INTERVAL=10
TIMEOUT=90

# Login
btp_login() {
echo "Logging into BTP..."
btp login --url "https://cli.btp.cloud.sap" \
--user "$BTP_USERNAME" \
--password "$BTP_PASSWORD" \
--subdomain "$BTP_SUBDOMAIN"

if [[ $? -ne 0 ]]; then
echo "Error: BTP login failed."
exit 1
fi

echo "Successfully logged into BTP."
}

# Function to create a subaccount
create_subaccount() {
local START_TIME=$(date +%s)
local DISPLAY_NAME="ci-susaas-$START_TIME"
local REGION="eu10"
local SUBDOMAIN="ci-susaas-$START_TIME"
local START_TIME=$(date +%s)

RESPONSE=$(btp --format json create accounts/subaccount --display-name "$DISPLAY_NAME" --region "$REGION" --subdomain "$SUBDOMAIN")
SUBACCOUNT_GUID=$(echo "$RESPONSE" | jq -r '.guid')

if [[ -z "$SUBACCOUNT_GUID" ]]; then
echo "Error: Failed to create subaccount."
exit 1
fi

echo "Subaccount creation with GUID: $SUBACCOUNT_GUID"
}

# Function to check subaccount status
check_subaccount_status() {
local START_TIME=$(date +%s)

while true; do
local CURRENT_TIME=$(date +%s)
local ELAPSED_TIME=$(( CURRENT_TIME - START_TIME ))

if (( ELAPSED_TIME >= TIMEOUT )); then
echo "Error: Subaccount status check timed out after $TIMEOUT seconds."
exit 1
fi

RESPONSE=$(btp --format json get accounts/subaccount "$SUBACCOUNT_GUID")
STATUS=$(echo "$RESPONSE" | jq -r '.state')

if [[ "$STATUS" == "OK" ]]; then
echo "Subaccount is ready."
break
else
echo "Current status is $STATUS. Checking again in $POLL_INTERVAL seconds..."
fi

sleep "$POLL_INTERVAL"
done
}

# Function to subscribe to the application
subscribe_to_application() {
RESPONSE=$(btp --format json subscribe accounts/subaccount --to-app "$APPLICATION_NAME" --plan "$PLAN_NAME" -sa "$SUBACCOUNT_GUID")
JOB_ID=$(echo "$RESPONSE" | jq -r '.jobId')

if [[ -z "$JOB_ID" ]]; then
echo "Error: Failed to subscribe to the application."
exit 1
fi

echo "Subscription initiated with Job ID: $JOB_ID"
check_subscription_status
}

# Function to check subscription status
check_subscription_status() {
local START_TIME=$(date +%s)

while true; do
local CURRENT_TIME=$(date +%s)
local ELAPSED_TIME=$(( CURRENT_TIME - START_TIME ))

if (( ELAPSED_TIME >= TIMEOUT )); then
echo "Error: Subscription status check timed out after $TIMEOUT seconds."
exit 1
fi

RESPONSE=$(btp --format json get accounts/subscription -sa "$SUBACCOUNT_GUID" --of-app "$APPLICATION_NAME" --plan "$PLAN_NAME")
STATUS=$(echo "$RESPONSE" | jq -r '.state')

if [[ "$STATUS" == "SUBSCRIBED" ]]; then
echo "Successfully subscribed to the application."
break
elif [[ "$STATUS" == "ERROR" ]]; then
echo "Error: Subscription failed."
exit 1
else
echo "Current status is $STATUS. Checking again in $POLL_INTERVAL seconds..."
fi

sleep "$POLL_INTERVAL"
done
}

# Function to unsubscribe from the application
unsubscribe_from_application() {
echo "Initiating unsubscription from the application..."

RESPONSE=$(btp --format json unsubscribe accounts/subaccount --from-app "$APPLICATION_NAME" -sa "$SUBACCOUNT_GUID" --confirm)

# The unsubscribe process is asynchronous, so we don't have a job ID to check
check_unsubscribe_status
}

# Function to check unsubscription status
check_unsubscribe_status() {
local START_TIME=$(date +%s)

while true; do
local CURRENT_TIME=$(date +%s)
local ELAPSED_TIME=$(( CURRENT_TIME - START_TIME ))

if (( ELAPSED_TIME >= TIMEOUT )); then
echo "Error: Unsubscribe status check timed out after $TIMEOUT seconds."
exit 1
fi

RESPONSE=$(btp --format json get accounts/subscription -sa "$SUBACCOUNT_GUID" --of-app "$APPLICATION_NAME" --plan "$PLAN_NAME")
STATUS=$(echo "$RESPONSE" | jq -r '.state')

if [[ "$STATUS" == "NOT_SUBSCRIBED" ]]; then
echo "Successfully unsubscribed from the application."
break
elif [[ "$STATUS" == "ERROR" ]]; then
echo "Error: Unsubscription failed."
exit 1
else
echo "Current status is $STATUS. Checking again in $POLL_INTERVAL seconds..."
fi

sleep "$POLL_INTERVAL"
done
}
# Function to remove the subaccount
delete_subaccount() {
echo "Removing the subaccount..."

RESPONSE=$(btp --format json delete accounts/subaccount "$SUBACCOUNT_GUID" --confirm)

echo "Subaccount deletion initiated. Checking status..."

# Check the status of the subaccount deletion
check_subaccount_removal
}

# Function to check if the subaccount has been removed
check_subaccount_removal() {
local START_TIME=$(date +%s)

while true; do
local CURRENT_TIME=$(date +%s)
local ELAPSED_TIME=$(( CURRENT_TIME - START_TIME ))

if (( ELAPSED_TIME >= TIMEOUT )); then
echo "Error: Subaccount removal check timed out after $TIMEOUT seconds."
exit 1
fi

RESPONSE=$(btp --format json get accounts/subaccount "$SUBACCOUNT_GUID" 2>&1)

if echo "$RESPONSE" | grep -q "404 Not Found"; then
echo "Subaccount removed successfully."
break
else
echo "Subaccount still exists. Checking again in $POLL_INTERVAL seconds..."
fi

sleep "$POLL_INTERVAL"
done
}

# Main script execution
btp_login
create_subaccount
check_subaccount_status
subscribe_to_application
unsubscribe_from_application
delete_subaccount

Loading

0 comments on commit eff3427

Please sign in to comment.