Skip to content

Commit

Permalink
Merge pull request #519 from UW-GAC/deploy/stage
Browse files Browse the repository at this point in the history
Deploy to prod
  • Loading branch information
amstilp authored Mar 22, 2024
2 parents b66064b + ce4006f commit 87dfd77
Show file tree
Hide file tree
Showing 9 changed files with 117 additions and 176 deletions.
8 changes: 4 additions & 4 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ updates:
interval: "weekly"
day: "sunday"
allow:
# Allow both direct and indirect updates for all packages
- dependency-type: "all"
# Allow up to 10 dependencies for pip dependencies
open-pull-requests-limit: 10
# Allow only direct dependencies - should be ok with pip-sync?
- dependency-type: "direct"
# Allow up to 20 dependencies for pip dependencies
open-pull-requests-limit: 20
147 changes: 17 additions & 130 deletions .github/workflows/combine-prs.yml
Original file line number Diff line number Diff line change
@@ -1,139 +1,26 @@
name: 'Combine PRs'
name: Combine PRs

# Controls when the action will run - in this case triggered manually
on:
workflow_dispatch:
inputs:
branchPrefix:
description: 'Branch prefix to find combinable PRs based on'
required: true
default: 'dependabot'
mustBeGreen:
description: 'Only combine PRs that are green (status is success)'
required: true
default: true
combineBranchName:
description: 'Name of the branch to combine PRs into'
required: true
default: 'combine-prs-branch'
ignoreLabel:
description: 'Exclude PRs with this label'
required: true
default: 'nocombine'
schedule:
- cron: '0 8 * * 1' # Monday at 08:00 UTC
workflow_dispatch: # allows you to manually trigger the workflow

# The minimum permissions required to run this Action
permissions:
contents: write
pull-requests: write
checks: read

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
# This workflow contains a single job called "combine-prs"
combine-prs:
# The type of runner that the job will run on
runs-on: ubuntu-latest

# Steps represent a sequence of tasks that will be executed as part of the job
steps:
- uses: actions/github-script@v7
id: fetch-branch-names
name: Fetch branch names
with:
github-token: ${{secrets.GITHUB_TOKEN}}
script: |
const pulls = await github.paginate('GET /repos/:owner/:repo/pulls', {
owner: context.repo.owner,
repo: context.repo.repo
});
branches = [];
prs = [];
base_branch = null;
for (const pull of pulls) {
const branch = pull['head']['ref'];
console.log('Pull for branch: ' + branch);
if (branch.startsWith('${{ github.event.inputs.branchPrefix }}')) {
console.log('Branch matched: ' + branch);
statusOK = true;
if(${{ github.event.inputs.mustBeGreen }}) {
console.log('Checking green status: ' + branch);
const checkRuns = await github.request('GET /repos/{owner}/{repo}/commits/{ref}/check-runs', {
owner: context.repo.owner,
repo: context.repo.repo,
ref: branch
});
for await (const cr of checkRuns.data.check_runs) {
console.log('Validating check conclusion: ' + cr.conclusion);
if(cr.conclusion != 'success') {
console.log('Discarding ' + branch + ' with check conclusion ' + cr.conclusion);
statusOK = false;
}
}
}
console.log('Checking labels: ' + branch);
const labels = pull['labels'];
for(const label of labels) {
const labelName = label['name'];
console.log('Checking label: ' + labelName);
if(labelName == '${{ github.event.inputs.ignoreLabel }}') {
console.log('Discarding ' + branch + ' with label ' + labelName);
statusOK = false;
}
}
if (statusOK) {
console.log('Adding branch to array: ' + branch);
branches.push(branch);
prs.push('#' + pull['number'] + ' ' + pull['title']);
base_branch = pull['base']['ref'];
}
}
}
if (branches.length == 0) {
core.setFailed('No PRs/branches matched criteria');
return;
}
core.setOutput('base-branch', base_branch);
core.setOutput('prs-string', prs.join('\n'));
combined = branches.join(' ')
console.log('Combined: ' + combined);
return combined
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v4
with:
fetch-depth: 0
# Creates a branch with other PR branches merged together
- name: Created combined branch
env:
BASE_BRANCH: ${{ steps.fetch-branch-names.outputs.base-branch }}
BRANCHES_TO_COMBINE: ${{ steps.fetch-branch-names.outputs.result }}
COMBINE_BRANCH_NAME: ${{ github.event.inputs.combineBranchName }}
run: |
echo "${{steps.fetch-branch-names.outputs.result}}"
sourcebranches="${BRANCHES_TO_COMBINE%\"}"
sourcebranches="${sourcebranches#\"}"
basebranch="${BASE_BRANCH%\"}"
basebranch="${basebranch#\"}"
git config pull.rebase false
git config user.name github-actions
git config user.email [email protected]
git branch $COMBINE_BRANCH_NAME $basebranch
git checkout $COMBINE_BRANCH_NAME
git pull origin $sourcebranches --no-edit
git push origin $COMBINE_BRANCH_NAME
# Creates a PR with the new combined branch
- uses: actions/github-script@v7
name: Create Combined Pull Request
- name: combine-prs
id: combine-prs
uses: github/[email protected]
with:
github-token: ${{secrets.GITHUB_TOKEN}}
script: |
const prString = `${{ steps.fetch-branch-names.outputs.prs-string }}`;
const body = 'This PR was created by the Combine PRs action by combining the following PRs:\n' + prString;
await github.pulls.create({
owner: context.repo.owner,
repo: context.repo.repo,
title: 'Combined PR',
head: '${{ github.event.inputs.combineBranchName }}',
base: '${{ steps.fetch-branch-names.outputs.base-branch }}',
body: body
});
labels: combined-pr # Optional: add a label to the combined PR
ci_required: true # require all checks to pass before combining
select_label: dependencies # Optional: only combine PRs with this label
autoclose: false # do not close the source PRs - dependabot should handle it.
13 changes: 13 additions & 0 deletions config/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@
"dal_select2",
"fontawesomefree",
"simple_history",
"constance",
]

LOCAL_APPS = [
Expand Down Expand Up @@ -198,6 +199,7 @@
"django.template.context_processors.static",
"django.template.context_processors.tz",
"django.contrib.messages.context_processors.messages",
"constance.context_processors.config",
"gregor_django.utils.context_processors.settings_context",
],
},
Expand Down Expand Up @@ -362,6 +364,17 @@
# https://django-tables2.readthedocs.io/en/latest/pages/custom-rendering.html?highlight=django_tables2_template#available-templates
DJANGO_TABLES2_TEMPLATE = "django_tables2/bootstrap5.html"

# django-constance
# ------------------------------------------------------------------------------
CONSTANCE_CONFIG = {
"ANNOUNCEMENT_TEXT": ("", "Site-wide announcement message", str),
}

CONSTANCE_BACKEND = "constance.backends.database.DatabaseBackend"
CONSTANCE_IGNORE_ADMIN_VERSION_CHECK = True
# CONSTANCE_DATABASE_CACHE_BACKEND = "default"
CONSTANCE_DATABASE_CACHE_AUTOFILL_TIMEOUT = None

# django-anvil-consortium-manager
# ------------------------------------------------------------------------------
# Specify the path to the service account to use for managing access on AnVIL.
Expand Down
21 changes: 21 additions & 0 deletions gregor_django/gregor_anvil/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from anvil_consortium_manager.models import AnVILProjectManagerAccess
from anvil_consortium_manager.tests import factories as acm_factories
from anvil_consortium_manager.tests.utils import AnVILAPIMockTestMixin
from constance.test import override_config
from django.conf import settings
from django.contrib.auth import get_user_model
from django.contrib.auth.models import Permission
Expand Down Expand Up @@ -96,6 +97,26 @@ def test_acm_link_with_edit_but_not_view_permission(self):
reverse("anvil_consortium_manager:index"), response.rendered_content
)

def test_site_announcement_no_text(self):
user = User.objects.create_user(username="test-none", password="test-none")
self.client.force_login(user)
response = self.client.get(self.get_url())
self.assertNotContains(response, """id="alert-announcement""")

@override_config(ANNOUNCEMENT_TEXT="This is a test announcement")
def test_site_announcement_text(self):
user = User.objects.create_user(username="test-none", password="test-none")
self.client.force_login(user)
response = self.client.get(self.get_url())
self.assertContains(response, """id="alert-announcement""")
self.assertContains(response, "This is a test announcement")

@override_config(ANNOUNCEMENT_TEXT="This is a test announcement")
def test_site_announcement_text_unauthenticated_user(self):
response = self.client.get(self.get_url(), follow=True)
self.assertContains(response, """id="alert-announcement""")
self.assertContains(response, "This is a test announcement")


class ConsentGroupDetailTest(TestCase):
"""Tests for the ConsentGroupDetail view."""
Expand Down
13 changes: 11 additions & 2 deletions gregor_django/templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -104,17 +104,26 @@
</div>
</nav>

{% block extra_navbar %}
{% endblock %}
<main class="flex-shrink-0">
<div class="container">

{% if config.ANNOUNCEMENT_TEXT %}
<div class="alert alert-info my-3" role="alert" id="alert-announcement">
<i class="bi bi-megaphone-fill me-1"></i>
{{ config.ANNOUNCEMENT_TEXT }}
</div>
{% endif %}

{% if messages %}
{% for message in messages %}
<div class="alert {% if message.tags %}alert-{{ message.tags }}{% endif %} alert-dismissible fade show" role="alert">{{ message }}<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button></div>
{% endfor %}
{% endif %}

{% block extra_navbar %}
{% endblock %}


{% block content %}

<div class="my-3 alert alert-warning" role="alert">
Expand Down
12 changes: 6 additions & 6 deletions requirements/dev-requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ asgiref==3.7.2
# via
# -c requirements/requirements.txt
# django
astroid==3.0.3
astroid==3.1.0
# via pylint
asttokens==2.4.1
# via stack-data
Expand All @@ -22,7 +22,7 @@ backports-zoneinfo==0.2.1
# via
# -c requirements/requirements.txt
# django
black==24.2.0
black==24.3.0
# via -r requirements/dev-requirements.in
certifi==2023.7.22
# via
Expand Down Expand Up @@ -50,7 +50,7 @@ dill==0.3.8
# via pylint
distlib==0.3.8
# via virtualenv
django==4.2.10
django==4.2.11
# via
# -c requirements/requirements.txt
# django-debug-toolbar
Expand Down Expand Up @@ -111,7 +111,7 @@ mccabe==0.7.0
# via
# flake8
# pylint
mypy==1.8.0
mypy==1.9.0
# via -r requirements/dev-requirements.in
mypy-extensions==1.0.0
# via
Expand Down Expand Up @@ -154,7 +154,7 @@ pygments==2.17.2
# via
# ipython
# sphinx
pylint==3.0.3
pylint==3.1.0
# via
# pylint-django
# pylint-plugin-utils
Expand Down Expand Up @@ -246,7 +246,7 @@ urllib3==2.1.0
# -c requirements/requirements.txt
# -c requirements/test-requirements.txt
# requests
virtualenv==20.25.0
virtualenv==20.25.1
# via pre-commit
wcwidth==0.2.13
# via prompt-toolkit
Expand Down
4 changes: 4 additions & 0 deletions requirements/requirements.in
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,7 @@ certifi>=2023.7.22
pyjwt>=2.4.0
urllib3>=1.26.18
sqlparse>=0.4.4

# Dynamic settings
django-constance
django-picklefield # Required by django-constance for database backend
Loading

0 comments on commit 87dfd77

Please sign in to comment.