{"id":13314093,"url":"https://github.com/skadi-cloud/gist","last_synced_at":"2025-03-10T20:33:15.679Z","repository":{"id":37954016,"uuid":"408334358","full_name":"skadi-cloud/gist","owner":"skadi-cloud","description":"Share MPS code snippets. More than just screenshots.","archived":false,"fork":false,"pushed_at":"2024-06-17T19:37:12.000Z","size":7794,"stargazers_count":6,"open_issues_count":24,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-07-29T19:05:24.797Z","etag":null,"topics":["jetbrains-mps","ktor-server"],"latest_commit_sha":null,"homepage":"https://gist.skadi.cloud","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/skadi-cloud.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-09-20T06:32:00.000Z","updated_at":"2023-09-02T14:55:10.000Z","dependencies_parsed_at":"2024-04-29T20:24:35.797Z","dependency_job_id":null,"html_url":"https://github.com/skadi-cloud/gist","commit_stats":null,"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skadi-cloud%2Fgist","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skadi-cloud%2Fgist/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skadi-cloud%2Fgist/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skadi-cloud%2Fgist/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/skadi-cloud","download_url":"https://codeload.github.com/skadi-cloud/gist/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":242921977,"owners_count":20207131,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["jetbrains-mps","ktor-server"],"created_at":"2024-07-29T18:10:26.033Z","updated_at":"2025-03-10T20:33:14.544Z","avatar_url":"https://github.com/skadi-cloud.png","language":"Kotlin","funding_links":[],"categories":["[Awesome MPS](#awesome-MPS)"],"sub_categories":["Plugins"],"readme":"# skadi gist\n\nShare MPS code snippets. More than just screenshots.\n\n## Repository Content\n\n- `ide-plugin`: MPS Plugin that creates a gist from the IDE written in kotlin.\n- `js`: Type script sources used by the front end. Mostly [hotwired.dev](https://hotwired.dev) progressive enhancement.\n  All core functionality is server side rendered!\n- `server`: Backend for the `ide-plugin` and serves the web interface. Written in kotlin with KTOR.\n- `shared`: Shared classes between the `ide-plugin` and `server` mostly constants and JSON messages.\n\n# Getting Started with Development\n\n## Prerequists\n\n- an installed JDK at least Java 11 is required (IntelliJ can install it when opening the project)\n- optionally: PostgreSQL (for running the tests)\n- [Node](https://nodejs.org/en/) and [Yarn](https://yarnpkg.com)\n\n## Editing Code\n\nThe repository contains a intelliJ project in the root directory which you can open and intelliJ will import the project\nfor you. It will also download all the dependencies, and you get work on the project.\n\nIf you are using a different code editor e.g. VS Code or GitHub Codespaces your want to run `./gradlew assemble` before\nyou open the project. This will download all dependencies and build the project.\n\n## Running the Tests\n\nTo run the tests you will need ProstgreSQL. The esiest way to get an instance up and running is via docker:\n\n```\ndocker run --name some-postgres -e POSTGRES_PASSWORD=mysecretpassword -p 5432:5432 -d postgres\n```\n\nThis will start a container with a PostgreSQL sever and expose the server to port `5432`.\n\nIf you use this exact configuration you can run the test from intelliJ via the `Tests in 'cloud.skadi'`\nrunconfiguration. If you changed the port of the password you will need to change the environment variables in the\nconfiguration to match yours. If you modify the configuration it's best to create copy to not accidentially commit the\nchanges.\n\nIf you don't use intelliJ to run the test you will need to set these four environment variables:\n\n```\nCOOKIE_SALT=\"give me cookies\"\nSQL_USER=postgres\nSQL_PASSWORD=mysecretpassword\nSQL_HOST=localhost:5432\n```\n\n`COOKIE_SALT` is used to authenticate cookies during the tests. The value doesn't matter for testing choose what ever\nyou like. The `SQL_*` variables need match your PostgreSQL configuration.\n\nYou can then run the test via `./gradlew build`.\n\n## Running the MPS plugin\n\nOpen the file `build.gradle.kts` in the `ide-plugin` folder and change the `intellij` block to use a local\npath and disable instrumentation of the code, e.g.:\n```\nintellij {\n    localPath.set(\"/Applications/mps/mac/MPS 2021.1.4.app/Contents\")\n    instrumentCode.set(false)\n}\n```\n\nThen you have to make sure that the system variable `idea.platform.prefix` is set to 'Idea'.\nWorkaround: create a file with extension .sh or .bat in the bin folder of the MPS installation with the following content: `-Didea.platform.prefix=Idea`.\n\nYou can now open MPS with the plugin installed by calling `./gradlew runIde`.\n\n# Running your own Instance\n\nThe preferred way of running skadi gist is via a container. The container image is available\nat [docker hub](https://registry.hub.docker.com/r/skadicloud/gist-server).\n\n## Storage Backend\n\nskadi gist support to two backends for storing the screenshots: `directory` and `s3`. The models are always stored in\nthe database.\n\n### S3 Storage\n\nskadi gist support storing screenshots in AWS S3 or compatible storage (\ne.g. [digitalocean spaces](https://www.digitalocean.com/products/spaces/)\n, [scaleway object storage](https://www.scaleway.com/en/object-storage/) or self-hosted [minIO](https://min.io)). When\nusing this storage backend skadi will store all screenshots in S3 making the container entirely stateless.\n\nSkadi gist will also leverage features like presigned urls for none public gists. This means the urls to screenshots are\nonly valid for short period of time.\n\n#### Configuration\n\nTo configure S3 storage set the `STORAGE_KIND` environment varialbe to `s3`.\n\nAdditional configuration via environment variables is required for authentication and the endpoint at your cloud\nprovider:\n\n```\nS3_REGION=\u003cAWS region of your S3 storage\u003e\nS3_ACCESS_KEY=\u003cAWS Access Key\u003e\nS3_SECRET_KEY=\u003cAWS Secret Key\u003e\nS3_BUCKET_NAME=\u003cBucket used for storing the screenshots\u003e\n```\n\nIf you are not using AWS but another provider you can omit `S3_REGION`. Instead, set `S3_ENDPOINT` according to your\nproviders' documentation.\n\n### Directory Storage\n\nDirectory storage uses the file system to store the screenshots. It then serves these files directly from the local\nfilesystem. This storage is mainly useful for testing and small deployments.\n\n#### Configuration\n\nTo confgiure directory storage set the `STORAGE_KIND` environment varialbe to `directory`.\n\nFor production deployments you definitly want to set `STORAGE_DIRECTORY` to point to a directory that is persistent and\nnot deleted when the container is updated. For testing no additional configuation is required.\n\n## Database\n\nskadi gist uses PostgreSQL for storing all data except the screenshots. This includes the models that are stored as JSON\nin the database. You can configure the database connection with the following environment variables:\n\n```\nSQL_USER=\u003cuses for the database\u003e\nSQL_PASSWORD=\u003cpassword for the user\u003e\nSQL_HOST=\u003chostname including port e.g. localhost:5432\u003e\nSQL_DB=\u003cdatabase name, the database needs to exists and isn't created by the application.\u003e\n```\n\nMake sure the user has `CREATE` permissions on the database in order to be able to create and update the database.\n\nIf you like to see support for a database backend that requires less configuration feel free to vode\nup [this issue](https://github.com/skadi-cloud/gist/issues/55).\n\n## GitHub Authentication\n\nSkadi gist uses OAuth to authenticate the user. At the moment only GitHub is supported. To use GitHub authentication you \nneed to [create a new](https://github.com/settings/applications/new) OAuth App. The callback URL is the url of your \nskadi cloud instance. If you are testing locally this is `http://localhost:8080`.\n\nAfter the OAuth app is created you can start configuring skadi cloud to use it. \n\n### Configuration \n\nskadi cloud uses environment variables to configure authentication:\n\n```\nGITHUB_SECRET=\u003cclient secret generated on the GitHub\u003e\nGITHUB_ID=\u003cclient id from GitHub\u003e\n```\n\nIn addition to the OAuth configuration a key for signing the cookies is required. That key is used to authenticate that\nthe cookies a client presents aren't modified. Keep this key secret as others can use it to inpersionate any use with \nthat key. If you change the key all existing user sessions are invalidated and the users need to login again.\n\nTo set the key use the environment variable `COOKIE_SALT`. The value has not requirements since it is not used directly\nbut the key for signing cookies is derived from the value. \n\n## Docker Compose Example\n\nMake sure you replace the environemnt variables with your values!\n\n### Direct Access Deployment \n\nThis creates a deployment that exposes skadi gist directly on port 8080. \n\n```\nversion: '3'\n\nservices:\n  skadi-gist:\n    image: skadicloud/gist-server\n    container_name: skadi-gist\n    restart: unless-stopped\n    ports:\n      - 8080:8080\n    security_opt:\n      - no-new-privileges:true\n    volumes:\n      - ./data:/data\n    environment:\n      - STORAGE_KIND=directory\n      - STORAGE_DIRECTORY=/data\n      - SQL_HOST=database\n      - SQL_USER=skadi\n      - SQL_PASSWORD=123456789\n      - SQL_DB=skadi-gist\n      - GITHUB_SECRET=addme\n      - GITHUB_ID=clientid\n      - COOKIE_SALT=replaceme\n      - IS_PRODUCTION=TRUE\n    depends_on:\n      - database\n    links:\n      - database\n  database:\n    image: 'postgres:latest'\n\n    ports:\n      - 5432\n\n    environment:\n      POSTGRES_USER: skadi # The PostgreSQL user (useful to connect to the database)\n      POSTGRES_PASSWORD: 123456789 # The PostgreSQL password (useful to connect to the database)\n      POSTGRES_DB: skadi-gist # The PostgreSQL default database (automatically created at first launch)\n    volumes:\n      - ./db/:/var/lib/postgresql/data/\n    healthcheck:\n      test: [ \"CMD-SHELL\", \"pg_isready -U skadi\" ]\n      interval: 5s\n      timeout: 5s\n      retries: 5\n```\n\n### With Treafik Ingress\n\nThis example uses [traefik](https://traefik.io) as an ingress handler. Traefik allows for automatic TLS configuration with certificates from\n[Let's Encrypt](https://letsencrypt.org). \n\ndocker-compose.yaml:\n\n```\nversion: '3'\n\nservices:\n  traefik:\n      image: traefik:v2.4\n      container_name: traefik\n      restart: unless-stopped\n      security_opt:\n        - no-new-privileges:true\n      networks:\n        - proxy\n      ports:\n        - 80:80\n        - 443:443\n      volumes:\n        - /etc/localtime:/etc/localtime:ro\n        - /var/run/docker.sock:/var/run/docker.sock:ro\n        - ./traefik.yml:/traefik.yml:ro\n        - ./traefik/acme/:/data\n  skadi-gist:\n    image: skadicloud/gist-server\n    container_name: skadi-gist\n    restart: unless-stopped\n    networks:\n      - proxy\n    security_opt:\n      - no-new-privileges:true\n    volumes:\n      - /var/run/docker.sock:/var/run/docker.sock:ro\n      - ./data:/data\n    environment:\n      - STORAGE_KIND=directory\n      - STORAGE_DIRECTORY=/data\n      - SQL_HOST=database\n      - SQL_USER=skadi\n      - SQL_PASSWORD=123456789\n      - SQL_DB=skadi-gist\n      - GITHUB_SECRET=addme\n      - GITHUB_ID=clientid\n      - COOKIE_SALT=replaceme\n      - IS_PRODUCTION=TRUE\n    depends_on:\n      - database\n    labels:\n      - \"traefik.enable=true\"\n      - \"traefik.http.routers.skadi.entrypoints=https\"\n      - \"traefik.http.routers.skadi.rule=Host(`\u003cmy skadi url\u003e`)\"\n      - \"traefik.http.routers.skadi.tls=true\"\n      - \"traefik.http.routers.skadi.tls.certresolver=myresolver\"\n      - \"traefik.docker.network=proxy\"\n    links:\n      - database\n  database:\n    image: 'postgres:latest'\n\n    ports:\n      - 5432\n    networks:\n      - proxy\n\n    environment:\n      POSTGRES_USER: skadi # The PostgreSQL user (useful to connect to the database)\n      POSTGRES_PASSWORD: 123456789 # The PostgreSQL password (useful to connect to the database)\n      POSTGRES_DB: skadi-gist # The PostgreSQL default database (automatically created at first launch)\n    volumes:\n      - ./db/:/var/lib/postgresql/data/\n    healthcheck:\n      test: [ \"CMD-SHELL\", \"pg_isready -U skadi\" ]\n      interval: 5s\n      timeout: 5s\n      retries: 5\n\nnetworks:\n  proxy:\n    external: true\n```\n\ntreafik.yml:\n\n```\napi:\n  dashboard: true\n\nentryPoints:\n  http:\n    address: \":80\"\n  https:\n    address: \":443\"\n\nproviders:\n  docker:\n    endpoint: \"unix:///var/run/docker.sock\"\n    exposedByDefault: false\n\ncertificatesResolvers:\n  myresolver:\n    acme:\n      email: \u003cyour email\u003e\n      storage: /data/acme.json\n      httpChallenge:\n        entryPoint: http\n```\n\n## Kubernetes Example\n\nFor a kubernets example take a look at the `kubernetes` subfolder of the repository. It contains the production confguration\nfor skadi-gist. It doesn't include a database deployment because is uses a hosted postgreSQL database. ","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fskadi-cloud%2Fgist","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fskadi-cloud%2Fgist","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fskadi-cloud%2Fgist/lists"}