diff --git a/.github/workflows/aws_deploy.yml b/.github/workflows/aws_deploy.yml index 9bd78ea3e..5af3c2d08 100644 --- a/.github/workflows/aws_deploy.yml +++ b/.github/workflows/aws_deploy.yml @@ -22,10 +22,6 @@ on: release_tag: required: false type: string - ref: - required: false - type: string - default: "" concurrency: group: deploy-${{ inputs.environment }}${{ inputs.concurrency_tag }} @@ -46,8 +42,6 @@ jobs: steps: - name: Checkout code uses: actions/checkout@v4 - with: - ref: ${{ inputs.ref || github.sha }} - name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@v4 @@ -59,19 +53,16 @@ jobs: id: ecr-login uses: aws-actions/amazon-ecr-login@v2 - - name: Resolve commit SHA - run: echo "commit_sha=${{ inputs.ref || github.sha }}" >> $GITHUB_ENV - - name: Check if image with tag already exists run: | - echo "image-exists=$(if aws ecr describe-images --repository-name=$repository --image-ids imageTag=${{ env.commit_sha }} > /dev/null 2>&1; then echo true; else echo false; fi)" >> $GITHUB_ENV + echo "image-exists=$(if aws ecr list-images --repository-name=$repository --query "imageIds[*].imageTag" | grep -q ${{ github.sha }}; then echo true; else echo false; fi)" >> $GITHUB_ENV - name: Build, tag, and push docker image to ECR if there is no image, failing for releases id: build-image if: ${{ env.image-exists == 'false' }} env: registry: ${{ steps.ecr-login.outputs.registry }} - commit_tag: ${{ env.commit_sha }} + commit_tag: ${{ github.sha }} run: | if [[ ${{ inputs.environment }} == 'production' ]]; then echo "Error: Deployment to production environment is not allowed as there is no docker image (i.e. the AWS deploy on staging was unsuccessful for this commit)." @@ -109,7 +100,7 @@ jobs: id: update-image-tags env: registry: ${{ steps.ecr-login.outputs.registry }} - commit_tag: ${{ inputs.ref || github.sha }} + commit_tag: ${{ github.sha }} readable_tag: ${{ inputs.environment }}-${{ env.additional-tag }} run: | manifest=$(aws ecr batch-get-image --repository-name $repository --image-ids imageTag=$commit_tag --output text --query images[].imageManifest) diff --git a/.github/workflows/review_app_prompt.yml b/.github/workflows/review_app_prompt.yml deleted file mode 100644 index 9c795cfa9..000000000 --- a/.github/workflows/review_app_prompt.yml +++ /dev/null @@ -1,24 +0,0 @@ -name: Review app deploy prompt - -on: - pull_request: - types: [opened] - -jobs: - prompt: - name: Add review app deploy instructions - runs-on: ubuntu-latest - permissions: - pull-requests: write - - steps: - - name: Comment with deploy instructions - uses: actions/github-script@v7 - with: - script: | - await github.rest.issues.createComment({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: context.issue.number, - body: 'To deploy a review app for this PR, comment `/deploy-review`.', - }); diff --git a/.github/workflows/review_pipeline.yml b/.github/workflows/review_pipeline.yml index 5c89d91e3..b31f81e23 100644 --- a/.github/workflows/review_pipeline.yml +++ b/.github/workflows/review_pipeline.yml @@ -1,94 +1,57 @@ name: Review app pipeline +concurrency: + group: review-${{ github.event.pull_request.number }} + on: - issue_comment: - types: [created] + pull_request: + types: + - opened + - synchronize + - reopened workflow_dispatch: - inputs: - pr_number: - required: true - type: string - description: "The number of the PR for which to deploy a review app. Note: this is NOT the ticket number" -permissions: {} +defaults: + run: + shell: bash jobs: - get_pr_details: - name: Get PR details - if: github.event_name == 'workflow_dispatch' || (github.event.issue.pull_request && startsWith(github.event.comment.body, '/deploy-review')) - runs-on: ubuntu-latest - outputs: - pr_number: ${{ steps.get_pr_details.outputs.pr_number }} - pr_head_sha: ${{ steps.get_pr_details.outputs.pr_head_sha }} - steps: - - name: Get PR number and HEAD SHA - id: get_pr_details - uses: actions/github-script@v7 - with: - script: | - let prNumber; - if (context.eventName === 'workflow_dispatch') { - prNumber = '${{ inputs.pr_number }}'; - } else { - prNumber = context.issue.number.toString(); - } - core.setOutput('pr_number', prNumber); - const { data: pr } = await github.rest.pulls.get({ - owner: context.repo.owner, - repo: context.repo.repo, - pull_number: parseInt(prNumber), - }); - core.setOutput('pr_head_sha', pr.head.sha); - infra: name: Deploy review app infrastructure - needs: [get_pr_details] uses: communitiesuk/submit-social-housing-lettings-and-sales-data-infrastructure/.github/workflows/create_review_app_infra.yml@main with: - key: ${{ needs.get_pr_details.outputs.pr_number }} + key: ${{ github.event.pull_request.number }} app_repo_role: arn:aws:iam::815624722760:role/core-application-repo permissions: id-token: write code: name: Deploy review app code - needs: [get_pr_details, infra] + needs: [infra] uses: ./.github/workflows/aws_deploy.yml with: aws_account_id: 837698168072 aws_role_prefix: core-dev - aws_task_prefix: core-review-${{ needs.get_pr_details.outputs.pr_number }} - concurrency_tag: ${{ needs.get_pr_details.outputs.pr_number }} + aws_task_prefix: core-review-${{ github.event.pull_request.number }} + concurrency_tag: ${{ github.event.pull_request.number }} environment: review - ref: ${{ needs.get_pr_details.outputs.pr_head_sha }} permissions: id-token: write comment: name: Add link to PR - needs: [get_pr_details, code] + needs: [code] runs-on: ubuntu-latest permissions: + issues: write pull-requests: write steps: - name: Comment on PR with URL - uses: actions/github-script@v7 + uses: unsplash/comment-on-pr@v1.3.0 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: - script: | - const prNumber = ${{ needs.get_pr_details.outputs.pr_number }}; - const body = `Created review app at https://review.submit-social-housing-data.communities.gov.uk/${prNumber}. Note that the review app will be automatically deprovisioned after 30 days and will need the review app pipeline running again.`; - const { data: comments } = await github.rest.issues.listComments({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: prNumber, - }); - const duplicate = comments.find(c => c.body.startsWith('Created review app at')); - if (!duplicate) { - await github.rest.issues.createComment({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: prNumber, - body: body, - }); - } + msg: "Created review app at https://review.submit-social-housing-data.communities.gov.uk/${{ github.event.pull_request.number }}. Note that the review app will be automatically deprovisioned after 30 days and will need the review app pipeline running again." + check_for_duplicate_msg: true + duplicate_msg_pattern: Created review app at* diff --git a/app/models/form/sales/questions/purchase_price.rb b/app/models/form/sales/questions/purchase_price.rb index d37d549ce..fbd3ea7a5 100644 --- a/app/models/form/sales/questions/purchase_price.rb +++ b/app/models/form/sales/questions/purchase_price.rb @@ -3,7 +3,7 @@ class Form::Sales::Questions::PurchasePrice < ::Form::Question super(id, hsh, page) @id = "value" @type = "numeric" - @min = 0 + @min = form.start_year_2026_or_later? ? 15_000 : 0 @step = 0.01 @width = 5 @prefix = "£" diff --git a/app/models/form/sales/questions/value.rb b/app/models/form/sales/questions/value.rb index c8b9cadd3..a1b4a155a 100644 --- a/app/models/form/sales/questions/value.rb +++ b/app/models/form/sales/questions/value.rb @@ -4,7 +4,7 @@ class Form::Sales::Questions::Value < ::Form::Question @id = "value" @copy_key = form.start_year_2025_or_later? ? "sales.sale_information.value.#{page.id}" : "sales.sale_information.value" @type = "numeric" - @min = 0 + @min = form.start_year_2026_or_later? ? 15_000 : 0 @step = 1 @width = 5 @prefix = "£" diff --git a/spec/models/form/sales/pages/purchase_price_outright_ownership_spec.rb b/spec/models/form/sales/pages/purchase_price_outright_ownership_spec.rb index 27ab0b422..c9bff2f95 100644 --- a/spec/models/form/sales/pages/purchase_price_outright_ownership_spec.rb +++ b/spec/models/form/sales/pages/purchase_price_outright_ownership_spec.rb @@ -5,7 +5,7 @@ RSpec.describe Form::Sales::Pages::PurchasePriceOutrightOwnership, type: :model let(:page_id) { "purchase_price" } let(:page_definition) { nil } - let(:subsection) { instance_double(Form::Subsection, form: instance_double(Form, start_date: Time.zone.local(2023, 4, 1))) } + let(:subsection) { instance_double(Form::Subsection, form: instance_double(Form, start_date: Time.zone.local(2023, 4, 1), start_year_2026_or_later?: false)) } it "has correct subsection" do expect(page.subsection).to eq(subsection) diff --git a/spec/models/form/sales/pages/purchase_price_spec.rb b/spec/models/form/sales/pages/purchase_price_spec.rb index ad857ee9f..f8bbde0e7 100644 --- a/spec/models/form/sales/pages/purchase_price_spec.rb +++ b/spec/models/form/sales/pages/purchase_price_spec.rb @@ -8,7 +8,7 @@ RSpec.describe Form::Sales::Pages::PurchasePrice, type: :model do let(:subsection) { instance_double(Form::Subsection) } before do - allow(subsection).to receive(:form).and_return(instance_double(Form, start_year_2024_or_later?: false, start_date: Time.zone.local(2023, 4, 1))) + allow(subsection).to receive(:form).and_return(instance_double(Form, start_year_2024_or_later?: false, start_year_2026_or_later?: false, start_date: Time.zone.local(2023, 4, 1))) end it "has correct subsection" do diff --git a/spec/models/form/sales/pages/value_shared_ownership_spec.rb b/spec/models/form/sales/pages/value_shared_ownership_spec.rb index 579084b35..e7e709d28 100644 --- a/spec/models/form/sales/pages/value_shared_ownership_spec.rb +++ b/spec/models/form/sales/pages/value_shared_ownership_spec.rb @@ -5,7 +5,7 @@ RSpec.describe Form::Sales::Pages::ValueSharedOwnership, type: :model do let(:page_id) { "value_shared_ownership" } let(:page_definition) { nil } - let(:subsection) { instance_double(Form::Subsection, form: instance_double(Form, start_date: Time.zone.local(2023, 4, 1)), id: "shared_ownership") } + let(:subsection) { instance_double(Form::Subsection, form: instance_double(Form, start_date: Time.zone.local(2023, 4, 1), start_year_2026_or_later?: false), id: "shared_ownership") } before do allow(page.subsection.form).to receive(:start_year_2025_or_later?).and_return(false) diff --git a/spec/models/form/sales/questions/purchase_price_spec.rb b/spec/models/form/sales/questions/purchase_price_spec.rb index c3d2999a0..6790b4a35 100644 --- a/spec/models/form/sales/questions/purchase_price_spec.rb +++ b/spec/models/form/sales/questions/purchase_price_spec.rb @@ -1,11 +1,15 @@ require "rails_helper" RSpec.describe Form::Sales::Questions::PurchasePrice, type: :model do + include CollectionTimeHelper + subject(:question) { described_class.new(question_id, question_definition, page, ownershipsch: 1) } let(:question_id) { nil } let(:question_definition) { nil } - let(:page) { instance_double(Form::Page, subsection: instance_double(Form::Subsection, form: instance_double(Form, start_date: Time.zone.local(2023, 4, 1)))) } + let(:start_year) { current_collection_start_year } + let(:start_year_2026_or_later?) { false } + let(:page) { instance_double(Form::Page, subsection: instance_double(Form::Subsection, form: instance_double(Form, start_date: collection_start_date_for_year(start_year), start_year_2026_or_later?: start_year_2026_or_later?))) } it "has correct page" do expect(question.page).to eq(page) @@ -30,6 +34,8 @@ RSpec.describe Form::Sales::Questions::PurchasePrice, type: :model do context "when discounted ownership scheme" do subject(:question) { described_class.new(question_id, question_definition, page, ownershipsch: 2) } + let(:start_year) { 2023 } + it "has the correct question_number" do expect(question.question_number).to eq(100) end @@ -38,6 +44,8 @@ RSpec.describe Form::Sales::Questions::PurchasePrice, type: :model do context "when outright sale" do subject(:question) { described_class.new(question_id, question_definition, page, ownershipsch: 3) } + let(:start_year) { 2023 } + it "has the correct question_number" do expect(question.question_number).to eq(110) end @@ -51,7 +59,20 @@ RSpec.describe Form::Sales::Questions::PurchasePrice, type: :model do expect(question.prefix).to eq("£") end - it "has correct min" do - expect(question.min).to eq(0) + context "with year 2025", metadata: { year: 25 } do + let(:start_year) { 2025 } + + it "has correct min" do + expect(question.min).to eq(0) + end + end + + context "with year 2026", metadata: { year: 26 } do + let(:start_year) { 2026 } + let(:start_year_2026_or_later?) { true } + + it "has correct min" do + expect(question.min).to eq(15_000) + end end end diff --git a/spec/models/form/sales/questions/value_spec.rb b/spec/models/form/sales/questions/value_spec.rb index bed4c7f96..2ebbf6d89 100644 --- a/spec/models/form/sales/questions/value_spec.rb +++ b/spec/models/form/sales/questions/value_spec.rb @@ -1,11 +1,15 @@ require "rails_helper" RSpec.describe Form::Sales::Questions::Value, type: :model do + include CollectionTimeHelper + subject(:question) { described_class.new(question_id, question_definition, page) } let(:question_id) { nil } let(:question_definition) { nil } - let(:page) { instance_double(Form::Page, id: "value_shared_ownership", subsection: instance_double(Form::Subsection, form: instance_double(Form, start_date: Time.zone.local(2023, 4, 1)), id: "shared_ownership")) } + let(:start_year) { current_collection_start_year } + let(:start_year_2026_or_later?) { false } + let(:page) { instance_double(Form::Page, id: "value_shared_ownership", subsection: instance_double(Form::Subsection, form: instance_double(Form, start_date: collection_start_date_for_year(start_year), start_year_2026_or_later?: start_year_2026_or_later?), id: "shared_ownership")) } before do allow(page.subsection.form).to receive(:start_year_2025_or_later?).and_return(false) @@ -35,7 +39,20 @@ RSpec.describe Form::Sales::Questions::Value, type: :model do expect(question.prefix).to eq("£") end - it "has correct min" do - expect(question.min).to eq(0) + context "with year 2025", metadata: { year: 25 } do + let(:start_year) { 2025 } + + it "has correct min" do + expect(question.min).to eq(0) + end + end + + context "with year 2026", metadata: { year: 26 } do + let(:start_year) { 2026 } + let(:start_year_2026_or_later?) { true } + + it "has correct min" do + expect(question.min).to eq(15_000) + end end end