Hangar is a hackathon management platform that can help with everything from project registration, communicating prizes, listing schedule info, and provides judging.
- Event info: share info about the hack with your attendees and link to resources
- Project registration: collect info from attendees about their hack
- Prize info: communicate prizes of various types
- Schedule: list your event schedule so attendees have access
- Judging: judge projects either by fixed criteria or by "expo" style comparison judging
- What is Hangar?
- Table of Contents
- Using Hangar
- Development
Interested in deploying an instance of Hangar to help with your hack? Follow the steps below to deploy and customize an instance of Hangar to use with your hack.
Hangar is containerized via Docker; simply build the docker image and deploy to a cloud environment of your choice. See the sections within Setup to generate the necessary environment variables and make them accessible to your app at runtime.
Authentication uses OAuth via Ping Federate OR Slack but it can be easily modified to use a new callback from a different OAuth provider. See the Ping Federate or Slack below for full details on how to setup and configure your SSO solution.
In Hangar's current state, you'll need to manually modify the Admin
table to create a new record for your admin users. Once created, your admin users will have full access to create judging sessions and see their results.
In order to modify the content of the homepage and to make other modifications to the presentation of the app, simply modify the values in packages/shared/src/config
.
-
Node 18+
-
This project is a monorepo, so Yarn was chosen for better dependency management
-
Open the project via the workspace file (e.g.,
code hangar.code-workspace
) -
Install dependencies
yarn
-
Copy
packages/api/.env.sample
topackages/api/.env.local
cp packages/api/.env.sample packages/api/.env.local
If you don't have Postgres installed already, see the
Installation and Use
section below.After installing, create a DB with the name
hangar
(or use another name and overrideDATABASE_URL
in your.env.local
).Installation and Use
Using Postgres.app is recommended as the installation doesn't require a password and is generally easier to use that the traditional Postgres app below.
During the installation process (if you follow the steps on postgresql.org), you will be prompted to set a password - make sure to use something you'll remember.
If you'd like a visual way of viewing or editing your local database, try using TablePlus.
You can seed the database using the
mikro-orm/cli
tool.You can drop, create, migrate, and seed the database any time you need with this command (run from
packages/api
):yarn mikro-orm migration:fresh --seed DatabaseSeeder
⚠️ NOTE: Running the above command will delete all data in your databaseTo run migrations locally, use
yarn migrate
from the root. If you ever want to replace your db contents with a fresh setup, runyarn db:fresh
.If you need to make a new migration, simply run
yarn workspace @hangar/database migration:create
. There are also scripts for running theup
anddown
commands:migration:up
andmigration:down
respectively.If you need to incorporate a new migration from a recently merged feature branch, run
yarn db:seed
;db:seed
will perform themigration:up
action and seed the db, potentially including data relevant to the new migration.After creating a migration locally that needs to be reverted, follow the process below to revert your local DB state:
- Run
yarn @hangar/database migration:down
- Delete the new migration
- Run
yarn @hangar/database snapshot:reset
⚠️ This will overwrite ANY changes made to your DB structure, not just the last migration
- Begin the migration creation process again
The process to update all packages is a little painful because ALL Mikro-ORM dependencies across BOTH packages must be kept in sync. Run both commands below (after modifying the version to match whatever target needed)
# API yarn workspace @hangar/api add @mikro-orm/core@^6.0 @mikro-orm/knex@^6.0 @mikro-orm/postgresql@^6.0 mikro-orm@^6.0 # DB yarn workspace @hangar/database add @mikro-orm/cli@^6.0 @mikro-orm/core@^6.0 @mikro-orm/knex@^6.0 @mikro-orm/migrations@^6.0 @mikro-orm/postgresql@^6.0 @mikro-orm/seeder@^6.0 @mikro-orm/postgresql@^6.0 mikro-orm@^6.0
In order to debug an issue locally, it can be helpful to mirror the prod DB locally. When doing so, make sure to avoid actions that will trigger text messages because user data is REAL. Always re-seed the DB after fixing your issue to avoid sending erroneous texts.
⚠️ WARNING: Make sure to follow these steps closely. Making an error below has the potential to overwrite production data if your token allows for write access.- Open TablePlus (no need to connect to a DB)
- Go to
File > Backup
(Windows steps TBD), choose your production database connection - Select the prod database
- Make sure the Postgres version is
PostgreSQL 14.0
and set the options to be--no-owner
and--format=custom
- Click
Start Backup
- (OPTIONAL) Drop all current data to ensure your local copy is an exact replica, otherwise some local data may persist
- Open a connection to your local database, select all tables and functions (
command + a
on macOS), right click, and choose "Delete" - When prompted, check the option for
Cascade
and clickOK
- Open a connection to your local database, select all tables and functions (
- Wait for the backup to finish and then go to
File > Restore
(Windows steps TBD), choose your local database connection - Remove all flags from the left hand side (primarily,
--single-transaction
which will cause your restore to fail on conflict) - Select your database on the right hand side
- Click
Start restore
If you add data manually to your database (through a tool like TablePlus) and do NOT let Postgres assign an
id
automatically, you will disrupt the sequence for that table that determines the next availableid
to assign. If that happens, perform the following queries to restart it.Find the appropriate sequence name:
SELECT sequence_schema, sequence_name FROM information_schema.sequences ORDER BY sequence_name;
Restart the sequence with a new id:
ALTER SEQUENCE "YOUR_TABLE_SEQUENCE" RESTART WITH THE_NEXT_ID_TO_ASSIGN;
(e.g.,
ALTER SEQUENCE "Provider_id_seq" RESTART WITH 11;
)Ping Federate is enabled by default for SSO. To configure it, simply add the following environment variables to your
.env.local
:PINGFED_CLIENT_ID
: Your client IDPINGFED_CLIENT_SECRET
: Your client secretPINGFED_AUTH_BASE_URL
: The URL which starts the authentication flowPINGFED_TOKEN_BASE_URL
: The URL from which the token containing user data can be retrieved
To configure the app to use Slack for SSO Authentication, modify the
packages/shared/src/config/auth.ts
and setslack
as the auth method. Next, create a Slack app using the following manifest after selectingFrom an app manifest
(NOTE: watch out for whitespace issues when copying):display_information: name: Hangar Dev (YOUR_FIRST_NAME) description: Dev instance of Hangar background_color: '#000000' features: bot_user: display_name: Hangar Dev (YOUR_FIRST_NAME) always_online: true oauth_config: redirect_urls: - [YOUR_NGROK_URL]/api/auth/callback/slack scopes: user: - email - openid - profile bot: - chat:write - chat:write.public settings: org_deploy_enabled: false socket_mode_enabled: false token_rotation_enabled: false
After creating the app, use the sidebar and go to
Install App
and request to install the app to your workspace. Once approved, head back to this section andInstall to workspace
.After installation, go to
OAuth & Permissions
and copy theBot User OAuth Token
value (starting withxoxb-
) and use that for yourSLACK_BOT_TOKEN
.You will also need to go to
Basic Information
and useClient ID
andClient Secret
as yourSLACK_CLIENT_ID
andSLACK_CLIENT_SECRET
, respectively.For Slack OAuth to work, your bot needs to be configured with your redirect URL. Go to
OAuth & Permissions
if you need to update your Redirect URL (e.g.,[YOUR_NGROK_URL]/api/auth/callback/slack
).
-
Start the development server
yarn dev
When you see this success message, open the url to load the site
🚀 Listening at http://localhost:3000
The server starts before Next.js finishes compiling, so the first time may take a little bit to load
-
After your initial setup, you'll need to run your database migrations:
yarn migrate
-
Start developing
-
For Slack integration, make sure to copy your ngrok address into
BASE_URL
config var (with no trailing slash!)
Hangar is containerized to make deployment efficient and to prevent vendor-dependence for our cloud environment
- Installing relevant dependencies
- Duplicate
.env.docker.sample
as.env.docker
and modify values as needed - Download Docker Desktop and start it
- Optionally modify
Settings > Resources > Advanced
to provide more resources to Docker and speed up your build commands
- Optionally modify
- Run
yarn docker:build
from the root to build your image - Run
yarn docker:run
to start your container - Visit
localhost:3001
to use the app running in Docker
packages/api/.env.local
is used as the base for all environment variables but .env.docker
will override any specified environment variables as needed.
On macOS Postgres user/pass is typically not required. If you do not use one in your API .env.local
, you WILL need to specify one in .env.docker
; the password is typically blank (no value needed) and your username is typically your machine user
(use whoami
in terminal).
If you are unable to start your Docker app, make sure the steps above have been followed, then:
- Check the accuracy of your
.env.docker
andpackages/api/.env.local
values (the former will override the latter) - Make sure no quotes are used in either file; Docker does not remove them and your value will include them
- You can use Docker Desktop to inspect the environment:
Docker Desktop > Containers / Apps > hangar
(environment variables can be found on theInspect
tab)