{"id":14985941,"url":"https://github.com/dafnik/ssp","last_synced_at":"2026-01-18T00:23:19.410Z","repository":{"id":241004330,"uuid":"803896819","full_name":"Dafnik/ssp","owner":"Dafnik","description":"Deploy static site previews via ssh.","archived":false,"fork":false,"pushed_at":"2025-02-13T20:01:13.000Z","size":93,"stargazers_count":1,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-03T12:03:00.598Z","etag":null,"topics":["action","ci","ci-cd","cicd","deploy","deployment","deployment-automation","preview","preview-environment","preview-environments","ssh","static-site","static-sites"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Dafnik.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":".github/CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":".github/SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"Dafnik","liberapay":"Dafnik"}},"created_at":"2024-05-21T15:11:00.000Z","updated_at":"2025-02-13T20:01:15.000Z","dependencies_parsed_at":"2024-09-24T15:47:36.620Z","dependency_job_id":null,"html_url":"https://github.com/Dafnik/ssp","commit_stats":{"total_commits":16,"total_committers":1,"mean_commits":16.0,"dds":0.0,"last_synced_commit":"88e62aa630ec1f28719e44efdd532473a9801cff"},"previous_names":["dafnik/ssp"],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dafnik%2Fssp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dafnik%2Fssp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dafnik%2Fssp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dafnik%2Fssp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Dafnik","download_url":"https://codeload.github.com/Dafnik/ssp/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247361598,"owners_count":20926642,"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":["action","ci","ci-cd","cicd","deploy","deployment","deployment-automation","preview","preview-environment","preview-environments","ssh","static-site","static-sites"],"created_at":"2024-09-24T14:11:59.054Z","updated_at":"2026-01-18T00:23:19.364Z","avatar_url":"https://github.com/Dafnik.png","language":null,"readme":"# Static Site Preview (SSP)\n\nDeploy static site previews via ssh.\n\n## NOTICE\n\nPlease note that this is in no way a secure solution for hosting static site previews.\n\n- You should only use this in repositories you **DO** trust.\n- You should only use this on a server\n  - you **DO NOT** care about.\n  - where you **DO NOT** have sensitive information stored.\n  - where you **DO NOT** run other sensitive services.\n- Unless you jail the specific ssh user, you are allowing a GitHub Action full ssh access to your server.\n- You allow any other repository with access to the same preview server to overwrite each other's previews.\n\n  (Though this should not happen under normal circumstances, as the GitHub Action uses a hash of repository name + pull request number)\n\n## Screenshots\n\n### GitHub Pull Request comment\n\n![GitHub Pull Request comment][github-pull-request-comment-screenshot]\n\n## Usage\n\n### GitHub Action\n\n```yml\nname: preview\n\non: [pull_request]\n\njobs:\n  deploy:\n    runs-on: ubuntu-latest\n\n    permissions:\n      pull-requests: write # needed for preview pull request comment\n      actions: read\n\n    # Deploy to the preview environment\n    environment:\n      name: preview-${{ github.event.number }}\n      url: ${{ steps.deploy-preview.outputs.url }}\n\n    steps:\n      - uses: actions/download-artifact@v4\n        with:\n          path: ./dist\n\n      - name: deploy preview\n        id: deploy-preview\n        uses: dafnik/ssp@v1\n        # with:\n        #   source: dist/*\n        #   target: /var/www/preview\n        #   host: preview.yxz.abc\n        #   port: 22\n        #   username: ubuntu\n        #   key: ${{ secrets.PREVIEW_SSH_PRIVATE_KEY }}\n        #   strip_components: 0\n        #   delete_threshold_days: 30\n```\n\n\u003c!-- prettier-ignore-start --\u003e\n| Inputs                  | Default value | Required | Description                                                                    |\n|-------------------------|---------------|----------|--------------------------------------------------------------------------------|\n| `source`                |               | x        | Path to the files which should be deployed                                     |\n| `target`                |               | x        | Preview server target path, must be a directory path.                          |\n| `host`                  |               | x        | Preview server domain                                                          |\n| `port`                  | `22`          |          | Preview server ssh port                                                        |\n| `username`              |               | x        | Preview server ssh username                                                    |\n| `key`                   |               | x        | Preview server ssh key content of private key. ex raw content of ~/.ssh/id_rsa |\n| `strip_components`      | `0`           |          | remove the specified number of leading path elements                           |\n| `delete_threshold_days` | `30`          |          | Number of days after inactive previews are deleted                             |\n\u003c!-- prettier-ignore-end --\u003e\n\nFurthermore, see [action.yml](action.yml)\n\n### NGINX Configuration\n\nPreviews are stored in the `/var/www/preview` directory by default.\n\n```\n# /etc/nginx/site-enabled/preview\n\nserver {\n    listen 80;\n    server_name *.preview.xyz.abc;\n    return 301 https://$server_name$request_uri;\n}\n\n\nserver {\n    listen 443 ssl http2;\n    server_name ~^(?P\u003csub\u003e.+)\\.preview\\.xyz\\.abc$;\n\n    ssl_certificate /etc/letsencrypt/live/preview.xyz.abc/fullchain.pem;\n    ssl_certificate_key /etc/letsencrypt/live/preview.xyz.abc/privkey.pem;\n\n    # GZIP\n    gzip on;\n    gzip_disable \"msie6\";\n\n    gzip_vary on;\n    gzip_proxied any;\n    gzip_comp_level 6;\n    gzip_buffers 16 8k;\n    gzip_http_version 1.1;\n    gzip_min_length 256;\n    gzip_types text/xml text/javascript font/ttf font/eot font/otf application/rdf+xml application/x-javascript application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;\n\n    # Remove X-Powered-By, which is an information leak\n    fastcgi_hide_header X-Powered-By;\n\n    # Do not send nginx server header\n    server_tokens off;\n\n    add_header Access-Control-Allow-Origin *;\n    add_header Strict-Transport-Security  \"max-age=31536000; includeSubDomains; preload\" always;\n    add_header Referrer-Policy            \"strict-origin\" always;\n    add_header X-Frame-Options            \"SAMEORIGIN\"    always;\n    add_header X-XSS-Protection           \"1; mode=block\" always;\n    add_header X-Content-Type-Options     \"nosniff\"       always;\n\n    access_log on;\n    error_log off;\n\n    root /var/www/preview/$sub;\n\n    location / {\n        # Check if the root directory exists\n        if (!-d $document_root) {\n            return 404;\n        }\n\n        try_files $uri $uri/ /index.html;\n\n        index index.html;\n    }\n}\n```\n\n### Cleanup cron job\n\nDelete previews with no activity in the last 30 days.\n\n```bash\n# /home/ubuntu/cronDeleteUnusedPreviews.sh\n\n# Define the directory to search in. Modify this variable to suit your needs.\nSEARCH_DIR=\"/var/www/preview\"\n\n# Find and delete directories not modified in the last 30 days.\nfind \"$SEARCH_DIR\" -type d -mtime +30 -exec rm -rf {} +\n\n# Explanation:\n# - `find \"$SEARCH_DIR\"`: Start searching in the specified directory.\n# - `-type d`: Only look for directories.\n# - `-mtime +30`: Find directories that were last modified more than 30 days ago.\n# - `-exec rm -rf {} +`: Delete each directory found ({} is replaced by the found directory name).\n```\n\nCrontab example:\n\n```bash\n@daily /home/ubuntu/cronDeleteUnusedPreviews.sh\n```\n\n## Release instructions\n\nIn order to release a new version of this action:\n\n1. Locate the semantic version of the [upcoming release][release-list] (a draft is maintained by the [`draft-release` workflow][draft-release]).\n\n2. Publish the draft release from the `main` branch with semantic version as the tag name, _with_ the checkbox to publish to the GitHub Marketplace checked. :ballot_box_with_check:\n\n3. After publishing the release, the [`release` workflow][release] will automatically run to create/update the corresponding the major version tag such as `v0`.\n\n   ⚠️ Environment approval is required. Check the [Release workflow run list][release-workflow-runs].\n\n## License\n\nThe scripts and documentation in this project are released under the [MIT License](LICENSE).\n\n\u003c!-- references --\u003e\n\n[release-list]: https://github.com/dafnik/ssp/releases\n[draft-release]: .github/workflows/draft-release.yml\n[release]: .github/workflows/release.yml\n[release-workflow-runs]: https://github.com/dafnik/ssp/actions/workflows/release.yml\n[github-pull-request-comment-screenshot]: .github/ssp/pr-comment-screenshot.png\n","funding_links":["https://github.com/sponsors/Dafnik","https://liberapay.com/Dafnik"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdafnik%2Fssp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdafnik%2Fssp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdafnik%2Fssp/lists"}