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.sampletopackages/api/.env.localcp packages/api/.env.sample packages/api/.env.local
If you don't have Postgres installed already, see the
Installation and Usesection below.After installing, create a DB with the name
hangar(or use another name and overrideDATABASE_URLin 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/clitool.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 migratefrom 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 theupanddowncommands:migration:upandmigration:downrespectively.If you need to incorporate a new migration from a recently merged feature branch, run
yarn db:seed;db:seedwill perform themigration:upaction 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.0and set the options to be--no-ownerand--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 + aon macOS), right click, and choose "Delete" - When prompted, check the option for
Cascadeand 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-transactionwhich 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
idautomatically, you will disrupt the sequence for that table that determines the next availableidto 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.tsand setslackas 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 Appand request to install the app to your workspace. Once approved, head back to this section andInstall to workspace.After installation, go to
OAuth & Permissionsand copy theBot User OAuth Tokenvalue (starting withxoxb-) and use that for yourSLACK_BOT_TOKEN.You will also need to go to
Basic Informationand useClient IDandClient Secretas yourSLACK_CLIENT_IDandSLACK_CLIENT_SECRET, respectively.For Slack OAuth to work, your bot needs to be configured with your redirect URL. Go to
OAuth & Permissionsif 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_URLconfig 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.sampleas.env.dockerand modify values as needed - Download Docker Desktop and start it
- Optionally modify
Settings > Resources > Advancedto provide more resources to Docker and speed up your build commands
- Optionally modify
- Run
yarn docker:buildfrom the root to build your image - Run
yarn docker:runto start your container - Visit
localhost:3001to 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.dockerandpackages/api/.env.localvalues (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 theInspecttab)
