Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 32 additions & 11 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -214,8 +214,28 @@ jobs:
- name: Log in to GHCR
run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u "${{ github.actor }}" --password-stdin

# Docker Hub is optional. GHCR needs no configuration, so a missing Docker Hub secret
# must not fail a release that otherwise succeeded.
- name: Log in to Docker Hub
run: echo "${{ secrets.DOCKERHUB_TOKEN }}" | docker login docker.io -u "${{ secrets.DOCKERHUB_USERNAME }}" --password-stdin
shell: bash
env:
DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }}
run: |
set -euo pipefail
if [[ -z "${DOCKERHUB_USERNAME:-}" || -z "${DOCKERHUB_TOKEN:-}" ]]; then
echo "DOCKERHUB_USERNAME or DOCKERHUB_TOKEN is not set; publishing to GHCR only." >&2
echo "DOCKERHUB_ENABLED=false" >> "$GITHUB_ENV"
{
echo "### Docker Hub"
echo ""
echo "Skipped — \`DOCKERHUB_USERNAME\` / \`DOCKERHUB_TOKEN\` are not configured."
echo "The image was published to GHCR only."
} >> "$GITHUB_STEP_SUMMARY"
exit 0
fi
echo "$DOCKERHUB_TOKEN" | docker login docker.io -u "$DOCKERHUB_USERNAME" --password-stdin
echo "DOCKERHUB_ENABLED=true" >> "$GITHUB_ENV"

- name: Build and push
shell: bash
Expand All @@ -224,14 +244,15 @@ jobs:
run: |
set -euo pipefail
MAJOR_MINOR="${VERSION%.*}"
docker build \
--build-arg VERSION="$VERSION" \
-t "$IMAGE_GHCR:$VERSION" \
-t "$IMAGE_GHCR:$MAJOR_MINOR" \
-t "$IMAGE_GHCR:latest" \
-t "$IMAGE_DOCKERHUB:$VERSION" \
-t "$IMAGE_DOCKERHUB:$MAJOR_MINOR" \
-t "$IMAGE_DOCKERHUB:latest" \
.

TAGS=(-t "$IMAGE_GHCR:$VERSION" -t "$IMAGE_GHCR:$MAJOR_MINOR" -t "$IMAGE_GHCR:latest")
if [[ "${DOCKERHUB_ENABLED:-false}" == "true" ]]; then
TAGS+=(-t "$IMAGE_DOCKERHUB:$VERSION" -t "$IMAGE_DOCKERHUB:$MAJOR_MINOR" -t "$IMAGE_DOCKERHUB:latest")
fi

docker build --build-arg VERSION="$VERSION" "${TAGS[@]}" .

docker push --all-tags "$IMAGE_GHCR"
docker push --all-tags "$IMAGE_DOCKERHUB"
if [[ "${DOCKERHUB_ENABLED:-false}" == "true" ]]; then
docker push --all-tags "$IMAGE_DOCKERHUB"
fi
12 changes: 11 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,15 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

## [1.0.2] - 2026-07-31

### Fixed

- A missing `DOCKERHUB_USERNAME` / `DOCKERHUB_TOKEN` no longer fails the release. The 1.0.1 run
published the tag, the zip and the GHCR image correctly, then went red on
`docker login docker.io -u ""`. Docker Hub is now skipped with a note in the run summary when
it is not configured, and the image still goes to GHCR.

## [1.0.1] - 2026-07-31

### Changed
Expand Down Expand Up @@ -110,6 +119,7 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
- Every pull request runs `dotnet list package --vulnerable --include-transitive` and fails on a
hit. CLI output is forced to English so the check cannot silently pass on a localised runner.

[Unreleased]: https://github.com/Mysttic/TargetApiSimulator/compare/v1.0.1...HEAD
[Unreleased]: https://github.com/Mysttic/TargetApiSimulator/compare/v1.0.2...HEAD
[1.0.2]: https://github.com/Mysttic/TargetApiSimulator/compare/v1.0.1...v1.0.2
[1.0.1]: https://github.com/Mysttic/TargetApiSimulator/compare/v1.0.0...v1.0.1
[1.0.0]: https://github.com/Mysttic/TargetApiSimulator/releases/tag/v1.0.0
13 changes: 13 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,19 @@ source, but it requires an application and approval, and the signature is issued
foundation's name rather than the project's. Everything this project publishes stays on
GitHub — no external package registry or account is involved.

### Repository secrets

Only one thing is configurable, and it is optional:

| Secret | Purpose |
|---|---|
| `DOCKERHUB_USERNAME` | Docker Hub account name, lowercase — `mysttic`, not an email address. Has to match the `docker.io/<namespace>/targetapisimulator` namespace. |
| `DOCKERHUB_TOKEN` | A Docker Hub personal access token with **Read & Write** scope, from Account settings → Personal access tokens. Not the account password; with 2FA enabled a password cannot work anyway. |

If either is missing the release still succeeds and the image is published to GHCR only, with a
note in the run summary. GHCR needs no secret — it authenticates with the built-in
`GITHUB_TOKEN`.

### Dry run

`release.yml` can be started manually from the Actions tab. A `workflow_dispatch` run builds and
Expand Down
2 changes: 1 addition & 1 deletion VERSION.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Version

1.0.1
1.0.2

<!--
This file is the single source of truth for the released version.
Expand Down