diff --git a/.github/workflows/test-negative.yml b/.github/workflows/test-negative.yml deleted file mode 100644 index 8fe0747..0000000 --- a/.github/workflows/test-negative.yml +++ /dev/null @@ -1,48 +0,0 @@ -name: Test example negative -on: -# # Uncomment when test added first time to register workflow and comment it back after workflow would be registered -# # -# # Added pull_request to register workflow from the PR. -# # Read more https://stackoverflow.com/questions/63362126/github-actions-how-to-run-a-workflow-created-on-a-non-master-branch-from-the-wo -# pull_request: {} - workflow_dispatch: {} - -jobs: - setup: - runs-on: ubuntu-latest - steps: - - name: Setup - run: echo "Do setup" - - test: - runs-on: ubuntu-latest - needs: [setup] - continue-on-error: true - steps: - - name: Checkout - uses: actions/checkout@v3 - - - uses: ./ - id: current - with: - param1: 'false' - - outputs: - result: "${{ steps.current.outputs.result1 }}" - - assert: - runs-on: ubuntu-latest - needs: [test] - steps: - - uses: nick-fields/assert-action@v1 - with: - expected: 'false' - actual: "${{ needs.test.outputs.result }}" - - teardown: - runs-on: ubuntu-latest - needs: [assert] - if: ${{ always() }} - steps: - - name: Tear down - run: echo "Do Tear down" diff --git a/.github/workflows/test-positive.yml b/.github/workflows/test-positive.yml deleted file mode 100644 index 4ee4acf..0000000 --- a/.github/workflows/test-positive.yml +++ /dev/null @@ -1,48 +0,0 @@ -name: Test example positive -on: -# # Uncomment when test added first time to register workflow and comment it back after workflow would be registered -# # -# # Added pull_request to register workflow from the PR. -# # Read more https://stackoverflow.com/questions/63362126/github-actions-how-to-run-a-workflow-created-on-a-non-master-branch-from-the-wo -# pull_request: {} - workflow_dispatch: {} - -jobs: - setup: - runs-on: ubuntu-latest - steps: - - name: Setup - run: echo "Do setup" - - test: - runs-on: ubuntu-latest - continue-on-error: true - needs: [setup] - steps: - - name: Checkout - uses: actions/checkout@v3 - - - uses: ./ - id: current - with: - param1: 'true' - - outputs: - result: "${{ steps.current.outputs.result1 }}" - - assert: - runs-on: ubuntu-latest - needs: [test] - steps: - - uses: nick-fields/assert-action@v1 - with: - expected: 'true' - actual: "${{ needs.test.outputs.result }}" - - teardown: - runs-on: ubuntu-latest - needs: [assert] - if: ${{ always() }} - steps: - - name: Tear down - run: echo "Do Tear down" diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml new file mode 100644 index 0000000..dfc76d6 --- /dev/null +++ b/.github/workflows/test.yaml @@ -0,0 +1,93 @@ +name: Test + +on: + pull_request: + types: [opened, synchronize, reopened] + +permissions: + contents: write + packages: read + +jobs: + + + screengrab: + runs-on: ubuntu-latest + concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}-${{ matrix.type }} + cancel-in-progress: true + strategy: + matrix: + type: [svg, png, jpg, pdf, html, ansi] + + permissions: + # Give the default GITHUB_TOKEN write permission to commit and push the + # added or changed files to the repository. + contents: write + + steps: + - uses: actions/checkout@v4 + + - name: Run this composite action + id: screengrab + uses: ./ # Use the path to your action directory + with: + # Your action's inputs + command: "(fortune ascii-art && fortune computers) | lolcat" + dependencies: >- + lolcat + fortune + fortunes + output: "docs/example.${{ matrix.type }}" + outputType: "${{ matrix.type }}" + viewportWidth: 600 + viewportHeight: 450 + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Rebase before push (optimistic concurrency) + shell: bash + run: | + git stash || true + git pull --rebase -X ours origin ${{ github.ref }} --rebase + git stash apply || true + + - uses: stefanzweifel/git-auto-commit-action@v5 + name: Commit artifact + id: auto-commit + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + commit_message: "chore: update ${{matrix.type}} example image" + commit_user_name: screengrab-action πŸ’» + commit_user_email: actions@github.com + commit_author: screengrab-action πŸ’» + file_pattern: '${{ steps.screengrab.outputs.file }}' + + - name: Add Image to Step Summary + if: steps.auto-commit.outputs.changes_detected == 'true' && (matrix.type == 'svg' || matrix.type == 'png' || matrix.type == 'jpg') + run: | + echo "## Generated Screengrab (${{matrix.type}})" >> $GITHUB_STEP_SUMMARY + echo "![Generated Screengrab](https://github.com/${{ github.repository }}/blob/${{ steps.auto-commit.outputs.commit_hash }}/${{ steps.screengrab.outputs.image }}?raw=true)" >> $GITHUB_STEP_SUMMARY + + - name: Add PDF to Step Summary + if: steps.auto-commit.outputs.changes_detected == 'true' && matrix.type == 'pdf' + run: | + echo "## Generated Screengrab (${{matrix.type}})" >> $GITHUB_STEP_SUMMARY + echo "[Generated PDF](https://github.com/${{ github.repository }}/blob/${{ steps.auto-commit.outputs.commit_hash }}/${{ steps.screengrab.outputs.image }}?raw=true)" >> $GITHUB_STEP_SUMMARY + + - name: Add HTML to Step Summary + if: steps.auto-commit.outputs.changes_detected == 'true' && matrix.type == 'html' + run: | + echo "## Generated Screengrab (${{matrix.type}})" >> $GITHUB_STEP_SUMMARY + echo "[Generated HTML](https://github.com/${{ github.repository }}/blob/${{ steps.auto-commit.outputs.commit_hash }}/${{ steps.screengrab.outputs.html }}?raw=true)" >> $GITHUB_STEP_SUMMARY + + - name: Add ANSI to Step Summary + if: steps.auto-commit.outputs.changes_detected == 'true' && matrix.type == 'ansi' + run: | + echo "## Generated Screengrab (${{matrix.type}})" >> $GITHUB_STEP_SUMMARY + echo "[Generated ANSI](https://github.com/${{ github.repository }}/blob/${{ steps.auto-commit.outputs.commit_hash }}/${{ steps.screengrab.outputs.ansi }}?raw=true)" >> $GITHUB_STEP_SUMMARY + + - name: No changes + if: steps.auto-commit.outputs.changes_detected == 'false' + run: | + echo "No changes to screengrab" >> $GITHUB_STEP_SUMMARY \ No newline at end of file diff --git a/README.md b/README.md index 17187e1..28bc780 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,8 @@ - -# example-github-action-composite [![Latest Release](https://img.shields.io/github/release/cloudposse/example-github-action-composite.svg)](https://github.com/cloudposse/example-github-action-composite/releases/latest) [![Slack Community](https://slack.cloudposse.com/badge.svg)](https://slack.cloudposse.com) +# screengrab +Latest ReleaseSlack Community -[![README Header][readme_header_img]][readme_header_link] - -[![Cloud Posse][logo]](https://cpco.io/homepage) - -Template repository of composite GitHub Action - ---- - -This project is part of our comprehensive ["SweetOps"](https://cpco.io/sweetops) approach towards DevOps. -[][share_email] -[][share_googleplus] -[][share_facebook] -[][share_reddit] -[][share_linkedin] -[][share_twitter] - - +Generate a screenshot from any command. Supports SVG, JPG, PNG, or PDF. +## Screenshots -It's 100% Open Source and licensed under the [APACHE2](LICENSE). +Demo*
Example of a screengrab generated by this action.* +--- +> [!NOTE] +> This project is part of Cloud Posse's comprehensive ["SweetOps"](https://cpco.io/homepage?utm_source=github&utm_medium=readme&utm_campaign=cloudposse-github-actions/screengrab&utm_content=) approach towards DevOps. +>
Learn More +> +> It's 100% Open Source and licensed under the [APACHE2](LICENSE). +> +> We have [*dozens of GitHub Actions*](https://github.com/cloudposse-github-actions?utm_source=github&utm_medium=readme&utm_campaign=cloudposse-github-actions/screengrab&utm_content=github_actions) that are Open Source and well-maintained. Check them out! +>
+ +## Introduction +This action generates a screengrab of any command using a combination of tools like script, aha, svg2html, and Puppeteer. +Many similar tools exist list it, however they are optimized generally for recorded video or GIFs. +It's excellent for showcasing still frames of CLI tools or terminal output in your documentation. +> [!IMPORTANT] +> This action is optimized for generating static images, HTML or ANSI files. +> If you need to generate a video or GIF, then you should use a different tool. -## Introduction +## Usage -This is template repository to create composite GitHub Actions. -Feel free to use it as reference and starting point. +For a complete working example that generated the demo image, see the [`.github/workflows/test.yaml`](.github/workflows/test.yaml) workflow. +```yaml +name: Generate Screenshot +on: + pull_request: + types: [opened, synchronize, reopened] -## Usage +jobs: + screenshot: + runs-on: ubuntu-latest + concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + steps: + - uses: actions/checkout@v2 + - name: Generate a Screengrab of the terminal + id: screenshot + uses: cloudposse-github-actions/screengrab@v0 + with: + output: "docs/example.svg" + command: ps -uxa + theme: "macos" + workdir: "/tmp" + output: "docs/example.svg" + # Set the width & height of the viewport of the terminal window + viewportWidth: 600 + viewportHeight: 450 + ``` -```yaml - name: Pull Request - on: - pull_request: - branches: [ 'main' ] - types: [opened, synchronize, reopened, closed, labeled, unlabeled] - - jobs: - context: - runs-on: ubuntu-latest - steps: - - name: Example action - uses: cloudposse/example-github-action-composite@main - id: example - with: - param1: true - - outputs: - result: ${{ steps.example.outputs.result1 }} -``` @@ -101,120 +107,134 @@ Feel free to use it as reference and starting point. | Name | Description | Default | Required | |------|-------------|---------|----------| -| param1 | Input parameter placeholder | true | true | +| command | Command to run (make sure it is already installed!) | N/A | true | +| consoleOutputEnabled | Whether or not to output the browser console log | true | false | +| css | Custom CSS overrides | N/A | false | +| dependencies | List of ubuntu dependencies to install | | false | +| deviceScaleFactor | Specifies the device scale factor (pixel ratio) for the web page rendering. It determines how many physical pixels are used to represent a single logical pixel. For example, a device scale factor of 2 means one logical pixel is represented by two physical pixels, commonly used for high-DPI (Retina) displays. A value of 1 uses standard pixel density. This factor affects the resolution and quality of the rendered page or screenshot. | 2 | false | +| fullPage | Screen capture the entire page by scrolling down | false | false | +| imageQuality | Quality of the output image (1-100, applicable for JPEG) | N/A | false | +| omitBackground | Omit the browser default background. Enable to support transparency. | false | false | +| output | Output image file path | screenshot.svg | false | +| outputType | Output image type (svg, png, jpeg, pdf) | svg | false | +| puppeteerImage | Docker image to run puppeteer. See https://github.com/puppeteer/puppeteer/pkgs/container/puppeteer | ghcr.io/cloudposse-github-actions/screenshot:sha-65d10e40b3507a6d752bd0be8a9647f681b46f75 | false | +| theme | Theme for the terminal. Supported values: macos, none | macos | false | +| timeout | Timeout for the command. is a floating point number with an optional suffix: 's' for seconds (the default), 'm' for minutes,
'h' for hours or 'd' for days. A duration of 0 disables the associated timeout.
| 5s | false | +| token | A GitHub token | | false | +| viewportHeight | Viewport height in pixels | 450 | true | +| viewportWidth | Viewport width in pixels | 600 | true | +| waitForTimeout | Number of milliseconds to delay before taking screenshot | 500 | false | +| workdir | Working directory for the command | . | false | ## Outputs | Name | Description | |------|-------------| -| result1 | Output result placeholder | +| ansi | File containing the generated ANSI | +| file | File containing the screengrab | +| html | File containing the generated HTML | +| image | File containing the generated image | - -## Share the Love - -Like this project? Please give it a β˜… on [our GitHub](https://github.com/cloudposse/example-github-action-composite)! (it helps us **a lot**) - -Are you using this project or any of our other projects? Consider [leaving a testimonial][testimonial]. =) - - - ## Related Projects Check out these related projects. +- [Screenshot](https://github.com/cloudposse-github-actions/screenshot) - This GitHub Action will use Puppeteer to generate screenshots from any URL or even a `file://`. It's great for creating dynamic banners for GitHub projects. ## References For additional context, refer to some of these links. -- [github-actions-workflows](https://github.com/cloudposse/github-actions-workflows) - Reusable workflows for different types of projects -- [example-github-action-release-workflow](https://github.com/cloudposse/example-github-action-release-workflow) - Example application with complicated release workflow - - -## Help - -**Got a question?** We got answers. - -File a GitHub [issue](https://github.com/cloudposse/example-github-action-composite/issues), send us an [email][email] or join our [Slack Community][slack]. - -[![README Commercial Support][readme_commercial_support_img]][readme_commercial_support_link] - -## DevOps Accelerator for Startups - - -We are a [**DevOps Accelerator**][commercial_support]. We'll help you build your cloud infrastructure from the ground up so you can own it. Then we'll show you how to operate it and stick around for as long as you need us. +- [Cloud Posse GitHub Actions](https://docs.cloudposse.com/github-actions/) - A collection of all Cloud Posse managed GitHub Actions -[![Learn More](https://img.shields.io/badge/learn%20more-success.svg?style=for-the-badge)][commercial_support] -Work directly with our team of DevOps experts via email, slack, and video conferencing. +## ✨ Contributing -We deliver 10x the value for a fraction of the cost of a full-time engineer. Our track record is not even funny. If you want things done right and you need it done FAST, then we're your best bet. - -- **Reference Architecture.** You'll get everything you need from the ground up built using 100% infrastructure as code. -- **Release Engineering.** You'll have end-to-end CI/CD with unlimited staging environments. -- **Site Reliability Engineering.** You'll have total visibility into your apps and microservices. -- **Security Baseline.** You'll have built-in governance with accountability and audit logs for all changes. -- **GitOps.** You'll be able to operate your infrastructure via Pull Requests. -- **Training.** You'll receive hands-on training so your team can operate what we build. -- **Questions.** You'll have a direct line of communication between our teams via a Shared Slack channel. -- **Troubleshooting.** You'll get help to triage when things aren't working. -- **Code Reviews.** You'll receive constructive feedback on Pull Requests. -- **Bug Fixes.** We'll rapidly work with you to fix any bugs in our projects. +This project is under active development, and we encourage contributions from our community. +Many thanks to our outstanding contributors: -## Slack Community + + + -Join our [Open Source Community][slack] on Slack. It's **FREE** for everyone! Our "SweetOps" community is where you get to talk with others who share a similar vision for how to rollout and manage infrastructure. This is the best place to talk shop, ask questions, solicit feedback, and work together as a community to build totally *sweet* infrastructure. +### πŸ› Bug Reports & Feature Requests -## Discourse Forums +Please use the [issue tracker](https://github.com/cloudposse-github-actions/screengrab/issues) to report any bugs or file feature requests. -Participate in our [Discourse Forums][discourse]. Here you'll find answers to commonly asked questions. Most questions will be related to the enormous number of projects we support on our GitHub. Come here to collaborate on answers, find solutions, and get ideas about the products and services we value. It only takes a minute to get started! Just sign in with SSO using your GitHub account. +### πŸ’» Developing -## Newsletter +If you are interested in being a contributor and want to get involved in developing this project or help out with Cloud Posse's other projects, we would love to hear from you! +Hit us up in [Slack](https://cpco.io/slack?utm_source=github&utm_medium=readme&utm_campaign=cloudposse-github-actions/screengrab&utm_content=slack), in the `#cloudposse` channel. -Sign up for [our newsletter][newsletter] that covers everything on our technology radar. Receive updates on what we're up to on GitHub as well as awesome new projects we discover. - -## Office Hours +In general, PRs are welcome. We follow the typical "fork-and-pull" Git workflow. + 1. Review our [Code of Conduct](https://github.com/cloudposse-github-actions/screengrab/?tab=coc-ov-file#code-of-conduct) and [Contributor Guidelines](https://github.com/cloudposse/.github/blob/main/CONTRIBUTING.md). + 2. **Fork** the repo on GitHub + 3. **Clone** the project to your own machine + 4. **Commit** changes to your own branch + 5. **Push** your work back up to your fork + 6. Submit a **Pull Request** so that we can review your changes -[Join us every Wednesday via Zoom][office_hours] for our weekly "Lunch & Learn" sessions. It's **FREE** for everyone! +**NOTE:** Be sure to merge the latest changes from "upstream" before making a pull request! -[![zoom](https://img.cloudposse.com/fit-in/200x200/https://cloudposse.com/wp-content/uploads/2019/08/Powered-by-Zoom.png")][office_hours] +### 🌎 Slack Community -## Contributing +Join our [Open Source Community](https://cpco.io/slack?utm_source=github&utm_medium=readme&utm_campaign=cloudposse-github-actions/screengrab&utm_content=slack) on Slack. It's **FREE** for everyone! Our "SweetOps" community is where you get to talk with others who share a similar vision for how to rollout and manage infrastructure. This is the best place to talk shop, ask questions, solicit feedback, and work together as a community to build totally *sweet* infrastructure. -### Bug Reports & Feature Requests +### πŸ“° Newsletter -Please use the [issue tracker](https://github.com/cloudposse/example-github-action-composite/issues) to report any bugs or file feature requests. +Sign up for [our newsletter](https://cpco.io/newsletter?utm_source=github&utm_medium=readme&utm_campaign=cloudposse-github-actions/screengrab&utm_content=newsletter) and join 3,000+ DevOps engineers, CTOs, and founders who get insider access to the latest DevOps trends, so you can always stay in the know. +Dropped straight into your Inbox every week β€” and usually a 5-minute read. -### Developing +### πŸ“† Office Hours -If you are interested in being a contributor and want to get involved in developing this project or [help out](https://cpco.io/help-out) with our other projects, we would love to hear from you! Shoot us an [email][email]. +[Join us every Wednesday via Zoom](https://cloudposse.com/office-hours?utm_source=github&utm_medium=readme&utm_campaign=cloudposse-github-actions/screengrab&utm_content=office_hours) for your weekly dose of insider DevOps trends, AWS news and GitHub Action insights, all sourced from our SweetOps community, plus a _live Q&A_ that you can’t find anywhere else. +It's **FREE** for everyone! -In general, PRs are welcome. We follow the typical "fork-and-pull" Git workflow. +## About - 1. **Fork** the repo on GitHub - 2. **Clone** the project to your own machine - 3. **Commit** changes to your own branch - 4. **Push** your work back up to your fork - 5. Submit a **Pull Request** so that we can review your changes +This project is maintained by Cloud Posse, LLC. + -**NOTE:** Be sure to merge the latest changes from "upstream" before making a pull request! +We are a [**DevOps Accelerator**](https://cpco.io/commercial-support?utm_source=github&utm_medium=readme&utm_campaign=cloudposse-github-actions/screengrab&utm_content=commercial_support) for funded startups and enterprises. +Use our ready-to-go terraform architecture blueprints for AWS & GitHub Actions to get up and running quickly. +We build it with you. You own everything. Your team wins. Plus, we stick around until you succeed. +Learn More -## Copyright +*Your team can operate like a pro today.* -Copyright Β© 2017-2023 [Cloud Posse, LLC](https://cpco.io/copyright) +Ensure that your team succeeds by using our proven process and turnkey blueprints. Plus, we stick around until you succeed. +
+ πŸ“š See What's Included +- **Reference Architecture.** You'll get everything you need from the ground up built using 100% infrastructure as code. +- **Deployment Strategy.** You'll have a battle-tested deployment strategy using GitHub Actions that's automated and repeatable. +- **Site Reliability Engineering.** You'll have total visibility into your apps and microservices. +- **Security Baseline.** You'll have built-in governance with accountability and audit logs for all changes. +- **GitOps.** You'll be able to operate your infrastructure via Pull Requests. +- **Training.** You'll receive hands-on training so your team can operate what we build. +- **Questions.** You'll have a direct line of communication between our teams via a Shared Slack channel. +- **Troubleshooting.** You'll get help to triage when things aren't working. +- **Code Reviews.** You'll receive constructive feedback on Pull Requests. +- **Bug Fixes.** We'll rapidly work with you to fix any bugs in our projects. +
+ ## License -[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) +License -See [LICENSE](LICENSE) for full details. +
+Preamble to the Apache License, Version 2.0 +
+
+ +Complete license is available in the [`LICENSE`](LICENSE) file. ```text Licensed to the Apache Software Foundation (ASF) under one @@ -234,74 +254,15 @@ KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ``` - - - - - - - - +
## Trademarks All other trademarks referenced herein are the property of their respective owners. - -## About - -This project is maintained and funded by [Cloud Posse, LLC][website]. Like it? Please let us know by [leaving a testimonial][testimonial]! - -[![Cloud Posse][logo]][website] - -We're a [DevOps Professional Services][hire] company based in Los Angeles, CA. We ❀️ [Open Source Software][we_love_open_source]. - -We offer [paid support][commercial_support] on all of our projects. - -Check out [our other projects][github], [follow us on twitter][twitter], [apply for a job][jobs], or [hire us][hire] to help with your cloud strategy and implementation. - +--- +Copyright © 2017-2024 [Cloud Posse, LLC](https://cpco.io/copyright) -### Contributors +README footer - -| [![Igor Rodionov][goruha_avatar]][goruha_homepage]
[Igor Rodionov][goruha_homepage] | -|---| - - - [goruha_homepage]: https://github.com/goruha - [goruha_avatar]: https://img.cloudposse.com/150x150/https://github.com/goruha.png - -[![README Footer][readme_footer_img]][readme_footer_link] -[![Beacon][beacon]][website] - - [logo]: https://cloudposse.com/logo-300x69.svg - [docs]: https://cpco.io/docs?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/example-github-action-composite&utm_content=docs - [website]: https://cpco.io/homepage?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/example-github-action-composite&utm_content=website - [github]: https://cpco.io/github?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/example-github-action-composite&utm_content=github - [jobs]: https://cpco.io/jobs?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/example-github-action-composite&utm_content=jobs - [hire]: https://cpco.io/hire?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/example-github-action-composite&utm_content=hire - [slack]: https://cpco.io/slack?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/example-github-action-composite&utm_content=slack - [linkedin]: https://cpco.io/linkedin?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/example-github-action-composite&utm_content=linkedin - [twitter]: https://cpco.io/twitter?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/example-github-action-composite&utm_content=twitter - [testimonial]: https://cpco.io/leave-testimonial?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/example-github-action-composite&utm_content=testimonial - [office_hours]: https://cloudposse.com/office-hours?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/example-github-action-composite&utm_content=office_hours - [newsletter]: https://cpco.io/newsletter?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/example-github-action-composite&utm_content=newsletter - [discourse]: https://ask.sweetops.com/?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/example-github-action-composite&utm_content=discourse - [email]: https://cpco.io/email?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/example-github-action-composite&utm_content=email - [commercial_support]: https://cpco.io/commercial-support?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/example-github-action-composite&utm_content=commercial_support - [we_love_open_source]: https://cpco.io/we-love-open-source?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/example-github-action-composite&utm_content=we_love_open_source - [terraform_modules]: https://cpco.io/terraform-modules?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/example-github-action-composite&utm_content=terraform_modules - [readme_header_img]: https://cloudposse.com/readme/header/img - [readme_header_link]: https://cloudposse.com/readme/header/link?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/example-github-action-composite&utm_content=readme_header_link - [readme_footer_img]: https://cloudposse.com/readme/footer/img - [readme_footer_link]: https://cloudposse.com/readme/footer/link?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/example-github-action-composite&utm_content=readme_footer_link - [readme_commercial_support_img]: https://cloudposse.com/readme/commercial-support/img - [readme_commercial_support_link]: https://cloudposse.com/readme/commercial-support/link?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/example-github-action-composite&utm_content=readme_commercial_support_link - [share_twitter]: https://twitter.com/intent/tweet/?text=example-github-action-composite&url=https://github.com/cloudposse/example-github-action-composite - [share_linkedin]: https://www.linkedin.com/shareArticle?mini=true&title=example-github-action-composite&url=https://github.com/cloudposse/example-github-action-composite - [share_reddit]: https://reddit.com/submit/?url=https://github.com/cloudposse/example-github-action-composite - [share_facebook]: https://facebook.com/sharer/sharer.php?u=https://github.com/cloudposse/example-github-action-composite - [share_googleplus]: https://plus.google.com/share?url=https://github.com/cloudposse/example-github-action-composite - [share_email]: mailto:?subject=example-github-action-composite&body=https://github.com/cloudposse/example-github-action-composite - [beacon]: https://ga-beacon.cloudposse.com/UA-76589703-4/cloudposse/example-github-action-composite?pixel&cs=github&cm=readme&an=example-github-action-composite - +Beacon diff --git a/README.yaml b/README.yaml index aeae4ad..7268370 100644 --- a/README.yaml +++ b/README.yaml @@ -5,11 +5,14 @@ # # Name of this project -name: example-github-action-composite +name: screengrab # Tags of this project tags: - github-action + - composite + - screenshot + - puppeteer # Logo for this project #logo: docs/logo.png @@ -17,62 +20,85 @@ tags: # License of this project license: "APACHE2" +# Screenshots +screenshots: + - name: "Demo" + description: "
Example of a screengrab generated by this action." + url: "docs/example.svg" + # Canonical GitHub repo -github_repo: cloudposse/example-github-action-composite +github_repo: cloudposse-github-actions/screengrab # Badges to display badges: - name: "Latest Release" - image: "https://img.shields.io/github/release/cloudposse/example-github-action-composite.svg" - url: "https://github.com/cloudposse/example-github-action-composite/releases/latest" + image: "https://img.shields.io/github/release/cloudposse-github-actions/screengrab.svg?syle=for-the-badge" + url: "https://github.com/cloudposse-github-actions/screengrab/releases/latest" - name: "Slack Community" - image: "https://slack.cloudposse.com/badge.svg" + image: "https://slack.cloudposse.com/for-the-badge.svg" url: "https://slack.cloudposse.com" -related: [] +related: +- name: "Screenshot" + description: "This GitHub Action will use Puppeteer to generate screenshots from any URL or even a `file://`. It's great for creating dynamic banners for GitHub projects." + url: "https://github.com/cloudposse-github-actions/screenshot" # Short description of this project -description: Template repository of composite GitHub Action +description: Generate a screenshot from any command. Supports SVG, JPG, PNG, or PDF. introduction: |- - This is template repository to create composite GitHub Actions. - Feel free to use it as reference and starting point. + This action generates a screengrab of any command using a combination of tools like script, aha, svg2html, and Puppeteer. + + Many similar tools exist list it, however they are optimized generally for recorded video or GIFs. + + It's excellent for showcasing still frames of CLI tools or terminal output in your documentation. + + > [!IMPORTANT] + > This action is optimized for generating static images, HTML or ANSI files. + > If you need to generate a video or GIF, then you should use a different tool. references: - - name: "github-actions-workflows" - description: "Reusable workflows for different types of projects" - url: "https://github.com/cloudposse/github-actions-workflows" - - name: "example-github-action-release-workflow" - description: "Example application with complicated release workflow" - url: "https://github.com/cloudposse/example-github-action-release-workflow" + - name: "Cloud Posse GitHub Actions" + description: "A collection of all Cloud Posse managed GitHub Actions" + url: "https://docs.cloudposse.com/github-actions/" # How to use this project -usage: |- +usage: | + For a complete working example that generated the demo image, see the [`.github/workflows/test.yaml`](.github/workflows/test.yaml) workflow. + ```yaml - name: Pull Request - on: - pull_request: - branches: [ 'main' ] - types: [opened, synchronize, reopened, closed, labeled, unlabeled] - - jobs: - context: - runs-on: ubuntu-latest - steps: - - name: Example action - uses: cloudposse/example-github-action-composite@main - id: example - with: - param1: true - - outputs: - result: ${{ steps.example.outputs.result1 }} - ``` + name: Generate Screenshot + + on: + pull_request: + types: [opened, synchronize, reopened] + + jobs: + screenshot: + runs-on: ubuntu-latest + concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + + steps: + - uses: actions/checkout@v2 + - name: Generate a Screengrab of the terminal + id: screenshot + uses: cloudposse-github-actions/screengrab@v0 + with: + output: "docs/example.svg" + command: ps -uxa + theme: "macos" + workdir: "/tmp" + output: "docs/example.svg" + + # Set the width & height of the viewport of the terminal window + viewportWidth: 600 + viewportHeight: 450 + ``` include: - - "docs/github-action.md" +- docs/github-action.md # Contributors to this project -contributors: - - name: "Igor Rodionov" - github: "goruha" \ No newline at end of file +contributors: [] diff --git a/action.yml b/action.yml index d7d527d..a644f38 100644 --- a/action.yml +++ b/action.yml @@ -1,23 +1,193 @@ -name: 'Example composite GitHub action' -description: 'Example composite GitHub action' +name: 'Screengrab' +description: "Generate a screenshot from any command. Supports SVG, JPG, PNG, PDF, ANSI, HTML." author: hello@cloudposse.com branding: - icon: 'file' + icon: 'camera' color: 'white' inputs: - param1: + command: + description: 'Command to run (make sure it is already installed!)' required: true - description: "Input parameter placeholder" - default: "true" + workdir: + description: 'Working directory for the command' + required: false + default: '.' + theme: + description: 'Theme for the terminal. Supported values: macos, none' + required: false + default: 'macos' + dependencies: + description: 'List of ubuntu dependencies to install' + default: '' + required: false + timeout: + description: | + Timeout for the command. is a floating point number with an optional suffix: 's' for seconds (the default), 'm' for minutes, + 'h' for hours or 'd' for days. A duration of 0 disables the associated timeout. + default: '5s' + required: false + css: + description: 'Custom CSS overrides' + required: false + output: + description: 'Output image file path' + required: false + default: screenshot.svg + outputType: + description: 'Output image type (svg, png, jpeg, pdf)' + default: svg + omitBackground: + description: 'Omit the browser default background. Enable to support transparency.' + default: 'false' + viewportWidth: + description: 'Viewport width in pixels' + default: '600' + required: true + viewportHeight: + description: 'Viewport height in pixels' + default: '450' + required: true + imageQuality: + description: 'Quality of the output image (1-100, applicable for JPEG)' + required: false + consoleOutputEnabled: + description: 'Whether or not to output the browser console log' + default: 'true' + deviceScaleFactor: + description: 'Specifies the device scale factor (pixel ratio) for the web page rendering. It determines how many physical pixels are used to represent a single logical pixel. For example, a device scale factor of 2 means one logical pixel is represented by two physical pixels, commonly used for high-DPI (Retina) displays. A value of 1 uses standard pixel density. This factor affects the resolution and quality of the rendered page or screenshot.' + default: '2' + required: false + fullPage: + description: 'Screen capture the entire page by scrolling down' + default: 'false' + waitForTimeout: + description: 'Number of milliseconds to delay before taking screenshot' + default: '500' + puppeteerImage: + description: 'Docker image to run puppeteer. See https://github.com/puppeteer/puppeteer/pkgs/container/puppeteer' + default: 'ghcr.io/cloudposse-github-actions/screenshot:sha-65d10e40b3507a6d752bd0be8a9647f681b46f75' + token: + description: 'A GitHub token' + required: false + default: "" + outputs: - result1: - description: "Output result placeholder" - value: "${{ steps.context.outputs.action-result }}" + image: + description: "File containing the generated image" + value: "${{ steps.image.outputs.file }}" + ansi: + description: "File containing the generated ANSI" + value: "${{ steps.ansi.outputs.file }}" + html: + description: "File containing the generated HTML" + value: "${{ steps.html.outputs.file }}" + file: + description: "File containing the screengrab" + value: "${{ steps.output.outputs.file }}" + runs: using: "composite" steps: - - id: context + - name: Install dependencies + id: deps + shell: bash + run: | + sudo apt-get update + sudo apt-get install -y aha ${{ inputs.dependencies }} + + - name: Run command + id: ansi + shell: bash + env: + OUTPUT_FILE: "output.ansi" + run: | + + # If we're only going to produce an ANSI file, then we should just write to it directly + if [ "${{ inputs.outputType }}" == "ansi" ]; then + OUTPUT_FILE="${{ inputs.output }}" + fi + + mkdir -p ${{ inputs.workdir }} + cd ${{ inputs.workdir }} + rm -f ${{github.workspace}}/${OUTPUT_FILE} + + # Generate a typescript file from the command, being mindful of the timeout + timeout -s SIGKILL ${{ inputs.timeout }} script -f -q ${{github.workspace}}/${OUTPUT_FILE} bash -c '${{ inputs.command }}' + + # Delete the first and last lines of the generated typescript file + sed -i -e '1,1d' -e '$d' ${{github.workspace}}/${OUTPUT_FILE} + + echo "file=${OUTPUT_FILE}" >> $GITHUB_OUTPUT + + - name: Convert ANSI to HTML + id: html + shell: bash + env: + OUTPUT_FILE: "output.html" + run: | + + # If we're only going to produce an HTML file, then we should just write to it directly + if [ "${{ inputs.outputType }}" == "html" ]; then + OUTPUT_FILE="${{ inputs.output }}" + fi + + if [ "${{ inputs.theme }}" == "macos" ]; then + aha --css "file://${{ github.workspace }}/term.css" < "${{ github.workspace }}/${{ steps.ansi.outputs.file }}" | \ + sed '//r term.html' > ${{ github.workspace }}/${OUTPUT_FILE} + + # Inject the command into the HTML (command may contains special characters, so we cannot use simple sed) + # NOTE: this is de-intended due to the heredoc + cat << "__EOF__" > ${{ github.workspace }}/command.txt + ${{ inputs.command }} + __EOF__ + + sed -i '/

/r command.txt' ${{ github.workspace }}/${OUTPUT_FILE} + elif [ "${{ inputs.theme }}" == "none" ]; then + aha --no-header < "${{ github.workspace }}/${{ steps.ansi.outputs.file }}" > ${{ github.workspace }}/${OUTPUT_FILE} + else + echo "Unsupported theme: ${{ inputs.theme }}" + exit 1 + fi + + cat ${{ github.workspace }}/${OUTPUT_FILE} + # Return the file as an output + echo "file=${OUTPUT_FILE}" >> $GITHUB_OUTPUT + + - name: Run puppeteer convert HTML to image + id: screenshot + if: ${{ contains(fromJSON('["svg", "png", "jpeg", "jpg", "pdf"]'), inputs.outputType) }} + uses: 'cloudposse-github-actions/screenshot@svg-support' + with: + # Your action's inputs + url: "file://${{ github.workspace }}/${{ steps.html.outputs.file }}" + output: "${{ inputs.output }}" + css: "${{ inputs.css }}" + customizations: | + '#title': ${{ inputs.command }} + viewportWidth: "${{ inputs.viewportWidth }}" + viewportHeight: "${{ inputs.viewportHeight }}" + outputType: "${{ inputs.outputType }}" + omitBackground: "${{ inputs.omitBackground }}" + imageQuality: "${{ inputs.imageQuality }}" + consoleOutputEnabled: "${{ inputs.consoleOutputEnabled }}" + deviceScaleFactor: "${{ inputs.deviceScaleFactor }}" + fullPage: "${{ inputs.fullPage }}" + waitForTimeout: "${{ inputs.waitForTimeout }}" + puppeteerImage: "${{ inputs.puppeteerImage }}" + token: ${{ inputs.token }} + + - id: image + shell: bash + if: ${{ steps.screenshot.outputs.file != '' }} + run: | + echo "file=${{ inputs.output }}" >> $GITHUB_OUTPUT + + - id: output + name: "Output" shell: bash run: | - echo "action-result=${{ inputs.param1 }}" >> $GITHUB_OUTPUT + # Only if a file was created, should we produce this output + if [ -f "${{ inputs.output }}" ]; then + echo "file=${{ inputs.output }}" >> $GITHUB_OUTPUT + fi \ No newline at end of file diff --git a/docs/example.ansi b/docs/example.ansi new file mode 100644 index 0000000..9e62719 --- /dev/null +++ b/docs/example.ansi @@ -0,0 +1,15 @@ +You are here: +                *** +                *** +             ********* +              ******* +               ***** +                *** +                 * + +                 But you're not all there. +If addiction is judged by how long a dumb animal will sit pressing a lever +to get a "fix" of something, to its own detriment, then I would conclude +that netnews is far more addictive than cocaine. +                -- Rob Stampfli +[?25h[?1;5;2004l diff --git a/docs/example.html b/docs/example.html new file mode 100644 index 0000000..0050387 --- /dev/null +++ b/docs/example.html @@ -0,0 +1,44 @@ + + + + + + +stdin + + + +
+
+
+
+
+
+

+(fortune ascii-art && fortune computers) | lolcat +

+
+
+SANTA IS BRINGING GOOD WISHES FROM ALL THE
+MICRO ARTISTS GANG!  MAY 1988 BE A HAPPY YEAR!
+
+
+                                             \__\_ :. ___/
+                                                ..\  /--
+ :.______ :  .:*  :  . _ .:  :..  .  :   . .  :    ()_ .:
+  ((     \. :./(__ :._O_)________:______,____:____/  *\_o
+====((    \: (****) (***) :. ...: .. .  ()_______/\\ __-'
+ \____((   \ ()oo()_/ /.:  :  ..________/_____ll   -/.: ..
+ (      ((  \(())))__/   .  ..  \\.: ..(   )  ll (  l_.:
+(       / (( \__*__)___:___ :  : ))   .) /--------\ \ \
+(      /    ((_____________) .. //  . / / /..:: .  )_)_\
+ (____/_____________________\__// :  /_/_/  :..  :/_/ \_\
+ /_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/    /_/_/
+
+
+Never underestimate the bandwidth of a station wagon full of tapes.
+                -- Dr. Warren Jackson, Director, UTCS
+
+
+ + diff --git a/docs/example.jpg b/docs/example.jpg new file mode 100644 index 0000000..edfa743 Binary files /dev/null and b/docs/example.jpg differ diff --git a/docs/example.pdf b/docs/example.pdf new file mode 100644 index 0000000..03fd20e Binary files /dev/null and b/docs/example.pdf differ diff --git a/docs/example.png b/docs/example.png new file mode 100644 index 0000000..e417d00 Binary files /dev/null and b/docs/example.png differ diff --git a/docs/example.svg b/docs/example.svg new file mode 100644 index 0000000..b519079 --- /dev/null +++ b/docs/example.svg @@ -0,0 +1,2502 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/github-action.md b/docs/github-action.md index 257dd05..d32e987 100644 --- a/docs/github-action.md +++ b/docs/github-action.md @@ -4,12 +4,32 @@ | Name | Description | Default | Required | |------|-------------|---------|----------| -| param1 | Input parameter placeholder | true | true | +| command | Command to run (make sure it is already installed!) | N/A | true | +| consoleOutputEnabled | Whether or not to output the browser console log | true | false | +| css | Custom CSS overrides | N/A | false | +| dependencies | List of ubuntu dependencies to install | | false | +| deviceScaleFactor | Specifies the device scale factor (pixel ratio) for the web page rendering. It determines how many physical pixels are used to represent a single logical pixel. For example, a device scale factor of 2 means one logical pixel is represented by two physical pixels, commonly used for high-DPI (Retina) displays. A value of 1 uses standard pixel density. This factor affects the resolution and quality of the rendered page or screenshot. | 2 | false | +| fullPage | Screen capture the entire page by scrolling down | false | false | +| imageQuality | Quality of the output image (1-100, applicable for JPEG) | N/A | false | +| omitBackground | Omit the browser default background. Enable to support transparency. | false | false | +| output | Output image file path | screenshot.svg | false | +| outputType | Output image type (svg, png, jpeg, pdf) | svg | false | +| puppeteerImage | Docker image to run puppeteer. See https://github.com/puppeteer/puppeteer/pkgs/container/puppeteer | ghcr.io/cloudposse-github-actions/screenshot:sha-65d10e40b3507a6d752bd0be8a9647f681b46f75 | false | +| theme | Theme for the terminal. Supported values: macos, none | macos | false | +| timeout | Timeout for the command. is a floating point number with an optional suffix: 's' for seconds (the default), 'm' for minutes,
'h' for hours or 'd' for days. A duration of 0 disables the associated timeout.
| 5s | false | +| token | A GitHub token | | false | +| viewportHeight | Viewport height in pixels | 450 | true | +| viewportWidth | Viewport width in pixels | 600 | true | +| waitForTimeout | Number of milliseconds to delay before taking screenshot | 500 | false | +| workdir | Working directory for the command | . | false | ## Outputs | Name | Description | |------|-------------| -| result1 | Output result placeholder | +| ansi | File containing the generated ANSI | +| file | File containing the screengrab | +| html | File containing the generated HTML | +| image | File containing the generated image | diff --git a/term.css b/term.css new file mode 100644 index 0000000..7c41699 --- /dev/null +++ b/term.css @@ -0,0 +1,68 @@ +body { + color: #ccc; + background: #171717; + margin-top: 10px; + margin-left: 20px; + margin-right: 20px; + line-height: 0.8em; +} + +pre { + overflow: hidden; +} + +h1 { + text-align: center; + font-size: 1em; + font-family: monospace; + flex-grow: 1; + + align-items: center; + width: 100vw; + position: relative; + left: -30px; + color: #fff; + font-weight: bold; + + white-space: nowrap; + overflow: hidden; + max-width: 60%; + text-overflow: ellipsis; +} + + +/* The container for the dots, representing a window control bar */ +.window-bar { + display: flex; + justify-content: center; +} + +.window-controls { + display: flex; + width: 60px; + align-items: start; + position: absolute; + left: 15px; + top: 17px; +} + +/* General styles for each dot */ +.control-dot { + width: 12px; /* Dot size */ + height: 12px; /* Dot size */ + border-radius: 50%; /* Makes the dot circular */ + margin: 0 4px; /* Spacing between dots */ +} + +/* Specific color for each dot */ +.close-dot { + background-color: #ff605c; /* Red color */ +} + +.minimize-dot { + background-color: #ffbd44; /* Yellow color */ +} + +.maximize-dot { + background-color: #00ca56; /* Green color */ +} diff --git a/term.html b/term.html new file mode 100644 index 0000000..899ab6f --- /dev/null +++ b/term.html @@ -0,0 +1,9 @@ +
+
+
+
+
+
+

+

+