diff --git a/.github/workflows/declarative-release-action.yml b/.github/workflows/declarative-release-action.yml new file mode 100644 index 0000000..79305aa --- /dev/null +++ b/.github/workflows/declarative-release-action.yml @@ -0,0 +1,122 @@ +name: Declarative rollout using bytebase-action image + +on: + push: + branches: + - main + paths: + - "schema/*.sql" + +# cancel previous workflow run if a new workflow run is triggered +# to prevent multiple rollout +concurrency: + group: ${{ github.workflow }} + cancel-in-progress: true + +env: + BYTEBASE_URL: http://host.docker.internal:8080 + BYTEBASE_SERVICE_ACCOUNT: api@service.bytebase.com # set service account via environment variable + BYTEBASE_SERVICE_ACCOUNT_SECRET: ${{ secrets.BYTEBASE_SERVICE_ACCOUNT_SECRET }} # set service account secret via environment variable + BYTEBASE_PROJECT: "projects/project-test" + +jobs: + build: + runs-on: self-hosted + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Build app and upload + run: | + echo "Building..." + echo "Build done!" + echo "Uploading..." + echo "Upload done!" + create-rollout: + needs: build + # runs-on: ubuntu-latest # use self-hosted machines if your Bytebase runs in internal networks. + runs-on: self-hosted + outputs: + bytebase-plan: ${{ steps.set-output.outputs.plan }} + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Roll out database change + env: + BYTEBASE_TARGETS: "instances/test-sample-instance/databases/school_test,instances/prod-sample-instance/databases/school_prod" + FILE_PATTERN: "schema/*.sql" + BYTEBASE_OUTPUT: ${{ runner.temp }}/bytebase-metadata.json + run: | + ls -la schema/ + docker run --rm \ + --add-host=host.docker.internal:host-gateway \ + -v "${{ github.workspace }}":/workspace \ + -v "${{ runner.temp }}":/temp \ + -e BYTEBASE_URL="${{ env.BYTEBASE_URL }}" \ + -e BYTEBASE_SERVICE_ACCOUNT="${{ env.BYTEBASE_SERVICE_ACCOUNT }}" \ + -e BYTEBASE_SERVICE_ACCOUNT_SECRET="${{ env.BYTEBASE_SERVICE_ACCOUNT_SECRET }}" \ + -e BYTEBASE_PROJECT="${{ env.BYTEBASE_PROJECT }}" \ + -e BYTEBASE_TARGETS="${{ env.BYTEBASE_TARGETS }}" \ + -w /workspace \ + bytebase/bytebase-action:3.12.0 \ + sh -c "ls -la /workspace/schema/ && bytebase-action rollout --url=${{ env.BYTEBASE_URL }} --project=${{ env.BYTEBASE_PROJECT }} --file-pattern=${{ env.FILE_PATTERN }} --targets=${{ env.BYTEBASE_TARGETS }} --declarative --output=/temp/bytebase-metadata.json" + - name: Set output + id: set-output + run: | + PLAN=$(jq -r .plan ${{ runner.temp }}/bytebase-metadata.json) + echo "plan=$PLAN" >> $GITHUB_OUTPUT + deploy-to-test: + needs: create-rollout + # runs-on: ubuntu-latest # use self-hosted machines if your Bytebase runs in internal networks. + runs-on: self-hosted + environment: test + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Roll out database change + env: + BYTEBASE_TARGET_STAGE: environments/test + run: | + docker run --rm \ + --add-host=host.docker.internal:host-gateway \ + -v "${{ github.workspace }}":/workspace \ + -e BYTEBASE_URL="${{ env.BYTEBASE_URL }}" \ + -e BYTEBASE_SERVICE_ACCOUNT="${{ env.BYTEBASE_SERVICE_ACCOUNT }}" \ + -e BYTEBASE_SERVICE_ACCOUNT_SECRET="${{ env.BYTEBASE_SERVICE_ACCOUNT_SECRET }}" \ + -e BYTEBASE_PROJECT="${{ env.BYTEBASE_PROJECT }}" \ + -e BYTEBASE_TARGET_STAGE="${{ env.BYTEBASE_TARGET_STAGE }}" \ + -w /workspace \ + bytebase/bytebase-action:3.12.0 \ + bytebase-action rollout --url=${{ env.BYTEBASE_URL }} --project=${{ env.BYTEBASE_PROJECT }} --target-stage=${{ env.BYTEBASE_TARGET_STAGE }} --plan=${{ needs.create-rollout.outputs.bytebase-plan }} + - name: Deploy app + run: | + echo "Deploying app to test environment..." + echo "Deploy app to test environment done!" + deploy-to-prod: + needs: + - deploy-to-test + - create-rollout + # runs-on: ubuntu-latest + runs-on: self-hosted + environment: prod + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: rollout + env: + BYTEBASE_TARGET_STAGE: environments/prod + run: | + docker run --rm \ + --add-host=host.docker.internal:host-gateway \ + -v "${{ github.workspace }}":/workspace \ + -e BYTEBASE_URL="${{ env.BYTEBASE_URL }}" \ + -e BYTEBASE_SERVICE_ACCOUNT="${{ env.BYTEBASE_SERVICE_ACCOUNT }}" \ + -e BYTEBASE_SERVICE_ACCOUNT_SECRET="${{ env.BYTEBASE_SERVICE_ACCOUNT_SECRET }}" \ + -e BYTEBASE_PROJECT="${{ env.BYTEBASE_PROJECT }}" \ + -e BYTEBASE_TARGET_STAGE="${{ env.BYTEBASE_TARGET_STAGE }}" \ + -w /workspace \ + bytebase/bytebase-action:3.12.0 \ + bytebase-action rollout --url=${{ env.BYTEBASE_URL }} --project=${{ env.BYTEBASE_PROJECT }} --target-stage=${{ env.BYTEBASE_TARGET_STAGE }} --plan=${{ needs.create-rollout.outputs.bytebase-plan }} + - name: Deploy app + run: | + echo "Deploying app to prod environment..." + echo "Deploy app to prod environment done!" \ No newline at end of file diff --git a/.github/workflows/sql-review-action.yml b/.github/workflows/sql-review-action.yml new file mode 100644 index 0000000..ea860a9 --- /dev/null +++ b/.github/workflows/sql-review-action.yml @@ -0,0 +1,44 @@ +name: SQL review on pull request using bytebase-action image + +on: + pull_request: + branches: + - main + paths: + - "schema/*.sql" + +jobs: + check-release-on-prod: + permissions: + pull-requests: write # write permission required to allow the action writes the check results to the comment. + # runs-on: ubuntu-latest # use self-hosted machines if your Bytebase runs in internal networks. + runs-on: self-hosted + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Check release + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # set GITHUB_TOKEN because the 'Check release' step needs it to comment the pull request with check results. + BYTEBASE_URL: http://host.docker.internal:8080 + BYTEBASE_SERVICE_ACCOUNT: api@service.bytebase.com # set service account via environment variable + BYTEBASE_SERVICE_ACCOUNT_SECRET: ${{ secrets.BYTEBASE_SERVICE_ACCOUNT_SECRET }} # set service account secret via environment variable + BYTEBASE_PROJECT: "projects/project-test" + BYTEBASE_TARGETS: "instances/prod-sample-instance/databases/school_prod" + FILE_PATTERN: "schema/*.sql" + run: | + ls -la schema/ + docker run --rm \ + --add-host=host.docker.internal:host-gateway \ + -v "${{ github.workspace }}":/workspace \ + -e GITHUB_TOKEN="${{ secrets.GITHUB_TOKEN }}" \ + -e BYTEBASE_URL="${{ env.BYTEBASE_URL }}" \ + -e BYTEBASE_SERVICE_ACCOUNT="${{ env.BYTEBASE_SERVICE_ACCOUNT }}" \ + -e BYTEBASE_SERVICE_ACCOUNT_SECRET="${{ secrets.BYTEBASE_SERVICE_ACCOUNT_SECRET }}" \ + -e BYTEBASE_PROJECT="${{ env.BYTEBASE_PROJECT }}" \ + -e BYTEBASE_TARGETS="${{ env.BYTEBASE_TARGETS }}" \ + -e GITHUB_REPOSITORY="${{ github.repository }}" \ + -e GITHUB_EVENT_NUMBER="${{ github.event.number }}" \ + -e GITHUB_API_URL="${{ github.api_url }}" \ + -w /workspace \ + bytebase/bytebase-action:3.12.0 \ + sh -c "ls -la /workspace/schema/ && bytebase-action check --url=${{ env.BYTEBASE_URL }} --project=${{ env.BYTEBASE_PROJECT }} --targets=${{ env.BYTEBASE_TARGETS }} --file-pattern=${{ env.FILE_PATTERN }} --declarative" \ No newline at end of file diff --git a/schema/class.sql b/schema/class.sql new file mode 100644 index 0000000..c61b698 --- /dev/null +++ b/schema/class.sql @@ -0,0 +1,8 @@ +CREATE TABLE "public"."class" ( + "class_no" integer DEFAULT nextval('public.class_no_seq'::regclass) NOT NULL, + "class_name" text NOT NULL, + "grade" integer NOT NULL, + CONSTRAINT "class_pkey" PRIMARY KEY (class_no), + CONSTRAINT "class_grade_check" CHECK (grade > 0 AND grade <= 12) +); + diff --git a/schema/class_student.sql b/schema/class_student.sql new file mode 100644 index 0000000..1613b07 --- /dev/null +++ b/schema/class_student.sql @@ -0,0 +1,10 @@ +CREATE TABLE "public"."class_student" ( + "class_no" integer NOT NULL, + "student_no" integer NOT NULL, + "from_date" date NOT NULL, + "to_date" date NOT NULL, + CONSTRAINT "class_student_pkey" PRIMARY KEY (class_no, student_no), + CONSTRAINT "class_student_class_no_fkey" FOREIGN KEY ("class_no") REFERENCES "public"."class" ("class_no") ON DELETE CASCADE, + CONSTRAINT "class_student_student_no_fkey" FOREIGN KEY ("student_no") REFERENCES "public"."student" ("student_no") ON DELETE CASCADE +); + diff --git a/schema/sequences.sql b/schema/sequences.sql new file mode 100644 index 0000000..b35cb02 --- /dev/null +++ b/schema/sequences.sql @@ -0,0 +1,3 @@ +CREATE SEQUENCE "public"."class_no_seq" AS bigint START WITH 1 INCREMENT BY 1 MINVALUE 1 MAXVALUE 9223372036854775807 NO CYCLE CACHE 1; + +CREATE SEQUENCE "public"."student_no_seq" AS bigint START WITH 1 INCREMENT BY 1 MINVALUE 1 MAXVALUE 9223372036854775807 NO CYCLE CACHE 1; diff --git a/schema/student.sql b/schema/student.sql new file mode 100644 index 0000000..afba1e2 --- /dev/null +++ b/schema/student.sql @@ -0,0 +1,10 @@ +CREATE TABLE "public"."student" ( + "student_no" integer DEFAULT nextval('public.student_no_seq'::regclass) NOT NULL, + "birth_date" date NOT NULL, + "first_name" text NOT NULL, + "last_name" text NOT NULL, + "gender" text NOT NULL, + CONSTRAINT "student_pkey" PRIMARY KEY (student_no), + CONSTRAINT "student_gender_check" CHECK (gender = ANY (ARRAY['M'::text, 'F'::text])) +); +